Support Requests - CLICK TO READ BEFORE POSTING


Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5

Linux Lite 7.8 RC1 Released
#11

Je l'ai testé rapidement, et tout est vraiment fluide. J'ai hâte de voir ce que les autres pensent des nouvelles applications ! Idea Rolleyes
Reply
#12

Wow, that was fast!  Thanks Jerry!

Could you supply the file name and line # with the code change and I'll test again (in dark mode etc.)

Cheers!
Reply
#13

Just replace the existing code with this:

Code:
#!/usr/bin/env python3 # -*- coding: utf-8 -*- # Lite Welcome - GTK4 Native Version # Copyright © 2012-2013 "Korora Project" <[email protected]> # Copyright © 2013-2015 "Manjaro Linux" <[email protected]> # Copyright © 2014-2025 "Jerry Bezencon" <[email protected]> # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. import os import sys import signal import subprocess from webbrowser import open_new_tab # Force CPU/Cairo rendering for VM compatibility (fixes white window issues) os.environ['GSK_RENDERER'] = 'cairo' import gi gi.require_version('Gtk', '4.0') gi.require_version('Adw', '1') from gi.repository import Gtk, Gdk, GLib, Gio, Adw, GdkPixbuf # Try to import GdkX11 for window centering on X11 systems try:     gi.require_version('GdkX11', '4.0')     from gi.repository import GdkX11     HAS_X11 = True except (ValueError, ImportError):     HAS_X11 = False # Application constants APP_ID = "com.linuxlite.welcome" APP_NAME = "Lite Welcome" ICON_NAME = "litewelcome" # Detect Live mode by checking for ubiquity installer on desktop IS_LIVE_MODE = os.path.exists(os.path.expanduser("~/Desktop/ubiquity.desktop")) def load_image_from_file(filepath, width=None, height=None):     """     Load an image from file using GdkPixbuf (CPU-based, reliable).     """     if not os.path.exists(filepath):         print(f"File not found: {filepath}")         return None     try:         # Use GdkPixbuf for reliable CPU-based rendering         if width and height:             pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(filepath, width, height, True)         else:             pixbuf = GdkPixbuf.Pixbuf.new_from_file(filepath)                 # Create Gtk.Image directly from pixbuf for GTK4         texture = Gdk.Texture.new_for_pixbuf(pixbuf)         image = Gtk.Image.new_from_paintable(texture)         return image     except Exception as e:         print(f"Error loading image {filepath}: {e}")         return None class WelcomeConfig:     def __init__(self):         self._arch = '64-bit' if os.uname()[4] == 'x86_64' else '32-bit'         self._config_dir = os.path.expanduser('~/.config/lite/welcome/')         self._autostart_path = os.path.expanduser('~/.config/autostart/lite-welcome.desktop')         os.makedirs(self._config_dir, exist_ok=True)         self._autostart = os.path.exists(self._autostart_path)         @property     def autostart(self):         return self._autostart         def toggle_autostart(self):         try:             if not self._autostart:                 os.makedirs(os.path.dirname(self._autostart_path), exist_ok=True)                 os.symlink('/usr/share/applications/lite-welcome.desktop', self._autostart_path)             else:                 if os.path.exists(self._autostart_path):                     os.unlink(self._autostart_path)         except OSError as e:             print(f"Error toggling autostart: {e}")         self._autostart = os.path.exists(self._autostart_path)         return self._autostart class CommandHandler:     def __init__(self, app=None):         self.app = app         @staticmethod     def spawn(args):         try:             subprocess.Popen(args, start_new_session=True)         except Exception as e:             print(f"Error spawning process: {e}")         @staticmethod     def open_url(url):         try:             open_new_tab(url)         except Exception as e:             print(f"Error opening URL: {e}")         def show_feedback(self, message):         """Show toast feedback if app reference is available."""         if self.app and hasattr(self.app, 'show_toast'):             self.app.show_toast(message)         def execute(self, command):         if command == 'start_updates':             if os.path.exists("/usr/bin/lite-updates"):                 self.show_feedback("Launching Install Updates...")                 self.spawn(['pkexec', '/usr/bin/lite-updates'])         elif command == 'install_drivers':             if os.path.exists("/usr/bin/software-properties-gtk"):                 self.show_feedback("Launching Driver Manager...")                 self.spawn(['/usr/bin/software-properties-gtk', '--open-tab=4'])         elif command == 'timeshift':             if os.path.exists("/usr/bin/timeshift-launcher"):                 self.show_feedback("Launching Timeshift...")                 self.spawn(['/usr/bin/timeshift-launcher'])         elif command == 'start_software':             if os.path.exists("/usr/bin/lite-software"):                 self.show_feedback("Launching Install Software...")                 self.spawn(['pkexec', 'lite-software'])         elif command == 'upgrade':             if os.path.exists("/usr/bin/lite-upgrade-series7"):                 self.show_feedback("Launching Upgrade Tool...")                 self.spawn(['/usr/bin/lite-upgrade-series7'])         elif command == 'lite-manual':             self.show_feedback("Opening Help Manual...")             self.open_url("https://wiki.linuxliteos.com/en/home")         elif command == 'installlang':             self.show_feedback("Opening Language Settings...")             self.open_url("https://wiki.linuxliteos.com/en/install.html#setlang")             self.spawn(['/usr/bin/gnome-language-selector'])         elif command == 'lighttheme':             self.show_feedback("Applying Light Theme...")             self.spawn(["xfconf-query", "-c", "xsettings", "-p", "/Net/ThemeName", "-s", "Materia"])             self.spawn(["xfconf-query", "-c", "xsettings", "-p", "/Net/IconThemeName", "-s", "Papirus-Adapta"])             self.spawn(["zenity", "--title=Lite Welcome", "--info", "--width=320", "--text=Light Theme applied"])         elif command == 'darktheme':             self.show_feedback("Applying Dark Theme...")             self.spawn(["xfconf-query", "-c", "xsettings", "-p", "/Net/ThemeName", "-s", "Materia-dark"])             self.spawn(["xfconf-query", "-c", "xsettings", "-p", "/Net/IconThemeName", "-s", "Papirus-Adapta-Nokto"])             self.spawn(["zenity", "--title=Lite Welcome", "--info", "--width=320", "--text=Dark Theme applied"])         elif command == 'install-now':             self.spawn(["sudo", "--preserve-env=DBUS_SESSION_BUS_ADDRESS,XDG_RUNTIME_DIR", "pkexec", "ubiquity", "gtk_ui"])             self.spawn(["zenity", "--timeout", "5", "--title=Lite Welcome", "--info", "--width=200", "--text=Loading please wait..."])             self.spawn(["killall", "lite-welcome"])         elif command.startswith("link:"):             self.show_feedback("Opening in browser...")             self.open_url(command[5:]) class NavigationPage(Gtk.Box):     def __init__(self, app, title=""):         super().__init__(orientation=Gtk.Orientation.VERTICAL, spacing=0)         self.app = app         self.title = title         self.cmd_handler = app.cmd_handler  # Use app's command handler for toast support         def create_header(self, title):         header_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=8)         header_box.set_margin_top(16)         header_box.set_margin_bottom(16)         title_label = Gtk.Label(label=title)         title_label.add_css_class("title-1")         title_label.set_halign(Gtk.Align.CENTER)         header_box.append(title_label)         return header_box         def create_button(self, label, icon_name, command=None, style_class="suggested-action"):         button = Gtk.Button()         box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=8)         box.set_halign(Gtk.Align.CENTER)         if icon_name:             icon = Gtk.Image.new_from_icon_name(icon_name)             box.append(icon)         lbl = Gtk.Label(label=label)         box.append(lbl)         button.set_child(box)         if style_class:             button.add_css_class(style_class)         if command:             button.connect("clicked", lambda b: self.cmd_handler.execute(command))         return button class HomePage(NavigationPage):     def __init__(self, app, data_path):         super().__init__(app, "Home")         self.data_path = data_path         self.build_ui()         def build_ui(self):         scrolled = Gtk.ScrolledWindow()         scrolled.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)         scrolled.set_vexpand(True)                 content = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=16)         content.set_margin_top(16)         content.set_margin_bottom(16)         content.set_margin_start(24)         content.set_margin_end(24)                 # Logo - use PNG for maximum compatibility (SVG has rendering issues in some VMs)         logo_path = os.path.join(self.data_path, "img", "lite-welcome.png")         if os.path.exists(logo_path):             # Use Gtk.Picture for proper image display at desired size             logo = Gtk.Picture.new_for_filename(logo_path)             logo.set_content_fit(Gtk.ContentFit.CONTAIN)             logo.set_can_shrink(True)             logo.set_size_request(291, 160)  # Explicit minimum size                         logo_button = Gtk.Button()             logo_button.set_child(logo)             logo_button.add_css_class("flat")             logo_button.set_halign(Gtk.Align.CENTER)             logo_button.connect("clicked", lambda b: self.cmd_handler.open_url("https://mityer.khdlhfjijfrupr.tk/"))             content.append(logo_button)                 # Summary         summary_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=8)         summary_box.set_margin_top(16)         summary_box.set_margin_bottom(16)                 summary1 = Gtk.Label()         summary1.set_wrap(True)         summary1.set_justify(Gtk.Justification.CENTER)         summary1.set_markup("Linux Lite is free for everyone to use and share, and suitable for people who are new to Linux or for people who want a lightweight environment that is also fully functional.")         summary_box.append(summary1)                 summary2 = Gtk.Label()         summary2.set_wrap(True)         summary2.set_justify(Gtk.Justification.CENTER)         summary2.set_markup("Linux Lite provides a basic collection of everyday tools: a web browser, an email client, a media player, an office suite, an image editor, and so on.")         summary_box.append(summary2)         content.append(summary_box)                 # Columns         columns_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=24)         columns_box.set_halign(Gtk.Align.CENTER)         columns_box.set_homogeneous(True)                 start_column = self.create_button_column("Start Here", [             ("Install Updates", "software-update-available-symbolic", "page:start#updates"),             ("Install Drivers", "preferences-system-symbolic", "page:start#drivers"),             ("Set a Restore Point", "computer-symbolic", "page:start#restore"),             ("Install Language Support", "preferences-desktop-locale-symbolic", "page:start#language"),             ("Select Dark or Light Theme", "preferences-desktop-display-symbolic", "page:start#theme"),         ], "suggested-action")         columns_box.append(start_column)                 support_column = self.create_button_column("Support", [             ("Online Support", "help-about-symbolic", "page:support#online"),             ("Linux Lite Wiki", "accessories-dictionary-symbolic", "page:support#wiki"),             ("Forums", "system-users-symbolic", "page:support#forums"),             ("Hardware Database", "printer-symbolic", "page:support#hardware"),             ("UEFI & Secure Boot", "security-high-symbolic", "page:start#uefi"),         ], "")                 if IS_LIVE_MODE:             install_btn = Gtk.Button()             install_btn.set_size_request(-1, 48)             install_btn.set_margin_top(8)             install_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=8)             install_box.set_halign(Gtk.Align.CENTER)             install_icon = Gtk.Image.new_from_icon_name("system-software-install-symbolic")             install_box.append(install_icon)             install_lbl = Gtk.Label(label="INSTALL NOW")             install_box.append(install_lbl)             install_btn.set_child(install_box)             install_btn.add_css_class("destructive-action")             install_btn.connect("clicked", lambda b: self.cmd_handler.execute("install-now"))             support_column.append(install_btn)                 columns_box.append(support_column)                 contribute_column = self.create_button_column("Contribute", [             ("Code", "utilities-terminal-symbolic", "page:contribute#code"),             ("Donate", "emblem-favorite-symbolic", "page:contribute#donate"),             ("Host a Mirror", "folder-download-symbolic", "page:contribute#mirror"),             ("Social Media", "emblem-shared-symbolic", "page:contribute#social"),             ("Feedback", "document-edit-symbolic", "link:https://mityer.khdlhfjijfrupr.tk/feedback.html"),         ], "")         columns_box.append(contribute_column)                 content.append(columns_box)         scrolled.set_child(content)         self.append(scrolled)         def create_button_column(self, title, buttons, style_class):         column = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=8)         column.set_size_request(200, -1)                 title_label = Gtk.Label(label=title)         title_label.add_css_class("heading")         title_label.set_margin_bottom(8)         column.append(title_label)                 for label, icon, cmd in buttons:             button = Gtk.Button()             button.set_size_request(-1, 40)             box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=8)             box.set_halign(Gtk.Align.CENTER)             if icon:                 icon_widget = Gtk.Image.new_from_icon_name(icon)                 box.append(icon_widget)             lbl = Gtk.Label(label=label)             box.append(lbl)             button.set_child(box)             if style_class:                 button.add_css_class(style_class)             if cmd.startswith("page:"):                 page_cmd = cmd[5:]                 button.connect("clicked", lambda b, p=page_cmd: self.app.navigate_to(p))             elif cmd.startswith("link:"):                 url = cmd[5:]                 button.connect("clicked", lambda b, u=url: self.cmd_handler.open_url(u))             column.append(button)         return column class StartPage(NavigationPage):     def __init__(self, app, data_path):         super().__init__(app, "Starting with Linux Lite")         self.data_path = data_path         self.sections = {}  # Store section references for scrolling         self.scrolled = None         self.build_ui()         def build_ui(self):         self.scrolled = Gtk.ScrolledWindow()         self.scrolled.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)         self.scrolled.set_vexpand(True)                 content = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=24)         content.set_margin_top(24)         content.set_margin_bottom(24)         content.set_margin_start(32)         content.set_margin_end(32)                 header = self.create_header("Starting with Linux Lite")         content.append(header)                 # Intro text         intro = Gtk.Label()         intro.set_markup("Once you have installed Linux Lite and before you can begin using it, it is strongly recommended that you first complete the 4 steps listed below.\n\n<b>If you are running the Live version of Linux Lite, do not attempt these steps below.</b>\n\nIf you have just finished installing Linux Lite in a language other than English, please restart your computer after these steps to activate all supported Menu translations.")         intro.set_wrap(True)         intro.set_justify(Gtk.Justification.CENTER)         content.append(intro)                 # Step 1: Install Updates         step1_desc = "First you need to update your system. Click on the button below to Install Updates now.\n\nOn the window that pops up, enter the password of the user you created during the installation.\n\nYou can also Install Updates via the menu. Click on Menu, Favorites, Install Updates."         self.sections["updates"] = self.create_step_section("✓ Step 1: Install Updates", step1_desc, "Install Updates", "software-update-available-symbolic", "start_updates")         content.append(self.sections["updates"])                 # Step 2: Install Drivers         step2_desc = "Now, let's see if you need any drivers installed. Click on the button below to check.\n\nYou can also Install Drivers via the menu. Click on Menu, Settings, Install Drivers."         self.sections["drivers"] = self.create_step_section("✓ Step 2: Install Drivers", step2_desc, "Install Drivers", "preferences-system-symbolic", "install_drivers")         content.append(self.sections["drivers"])                 # Step 3: Restore Point         step3_desc = "Last step is to create, just like on Windows, a restore point that you can restore from in case something goes wrong. When you are ready, click on the button below.\n\nYou can also access Timeshift via the menu. Click on Menu, System, Timeshift."         self.sections["restore"] = self.create_step_section("✓ Step 3: Setting a Restore Point", step3_desc, "Set a Restore Point", "computer-symbolic", "timeshift")         content.append(self.sections["restore"])                 # Step 4: Language Support         step4_desc = "Click on the button below to install Language Support for Linux Lite.\n\nYou can also install Language Support via the menu. Click on Menu, Settings, Language Support.\n\n<b>NOTE: Don't forget to restart your computer after you have finished installing additional Language Support.</b>"         self.sections["language"] = self.create_step_section("✓ Step 4: Installing Language Support", step4_desc, "Install Language Support", "preferences-desktop-locale-symbolic", "installlang")         content.append(self.sections["language"])                 # UEFI and Secure Boot section         self.sections["uefi"] = self.create_uefi_section()         content.append(self.sections["uefi"])                 # Theme section         self.sections["theme"] = self.create_theme_section()         content.append(self.sections["theme"])                 # Keyboard and Numlock section         self.sections["keyboard"] = self.create_keyboard_section()         content.append(self.sections["keyboard"])                 # Upgrading section         self.sections["upgrade"] = self.create_upgrade_section()         content.append(self.sections["upgrade"])                 # Lite Software section         self.sections["software"] = self.create_software_section()         content.append(self.sections["software"])                 # Hardware Recommendations section         self.sections["hardware"] = self.create_hardware_section()         content.append(self.sections["hardware"])                 self.scrolled.set_child(content)         self.append(self.scrolled)         def scroll_to_section(self, section_name):         if section_name not in self.sections:             return         self.pending_scroll = section_name         GLib.idle_add(self._perform_scroll)         def _perform_scroll(self):         if not hasattr(self, 'pending_scroll') or not self.pending_scroll:             return False         section_name = self.pending_scroll         self.pending_scroll = None                 if section_name not in self.sections:             return False                     target = self.sections[section_name]         content = self.scrolled.get_child()         if hasattr(content, 'get_child'):             content = content.get_child()                 y_pos = 0         child = content.get_first_child() if content else None         while child:             if child == target:                 break             h = child.get_height()             if h <= 0:                 h = child.get_preferred_size().minimum_size.height             y_pos += h + 24             child = child.get_next_sibling()                 adj = self.scrolled.get_vadjustment()         adj.set_value(y_pos)         return False         def create_step_section(self, title, description, button_label, icon_name, command):         frame = Gtk.Frame()         box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=12)         box.add_css_class("section")         box.set_margin_top(16)         box.set_margin_bottom(16)         box.set_margin_start(16)         box.set_margin_end(16)                 title_label = Gtk.Label()         title_label.set_markup(f"<span size='large' weight='bold'>{title}</span>")         title_label.set_halign(Gtk.Align.CENTER)         box.append(title_label)                 desc_label = Gtk.Label()         desc_label.set_markup(description)         desc_label.set_wrap(True)         desc_label.set_halign(Gtk.Align.CENTER)         desc_label.set_justify(Gtk.Justification.CENTER)         box.append(desc_label)                 button = self.create_button(button_label, icon_name, command, "suggested-action")         button.set_halign(Gtk.Align.CENTER)         box.append(button)                 frame.set_child(box)         return frame         def create_uefi_section(self):         frame = Gtk.Frame()         box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0)         box.add_css_class("section")         box.set_margin_top(16)         box.set_margin_bottom(16)         box.set_margin_start(16)         box.set_margin_end(16)                 title_label = Gtk.Label()         title_label.set_markup("<span size='large' weight='bold'>? UEFI and Secure Boot</span>")         title_label.set_halign(Gtk.Align.CENTER)         box.append(title_label)                 # UEFI image         uefi_img_path = os.path.join(self.data_path, "img", "uefisb.png")         if os.path.exists(uefi_img_path):             uefi_img = load_image_from_file(uefi_img_path, width=500, height=300)             if uefi_img:                 uefi_img.set_halign(Gtk.Align.CENTER)                 uefi_img.set_valign(Gtk.Align.CENTER)                 uefi_img.set_size_request(500, 300)                 box.append(uefi_img)                 uefi_text = """<b>How do I know if my computer has UEFI?</b> In Windows Search, type <b>msinfo</b> or <b>msinfo32</b> and launch the desktop app named System Information. Look for the BIOS Mode item, and if the value for it is <b>UEFI</b>, then you have the UEFI firmware. If it says BIOS Mode Legacy, then that's the firmware you're running. If you bought the computer/motherboard after 2010, chances are you have a UEFI system. If you are still unsure, download the UEFI version as it will also detect and run on a BIOS-Legacy computer. <b>Secure Boot</b> Linux Lite recommends that you disable Secure Boot in your BIOS. This will save you potentially a lot of headaches during the use of your system. Linux Lite will run with Secure Boot enabled, but we highly recommend that you don't."""                 desc_label = Gtk.Label()         desc_label.set_markup(uefi_text)         desc_label.set_wrap(True)         desc_label.set_halign(Gtk.Align.CENTER)         desc_label.set_justify(Gtk.Justification.CENTER)         box.append(desc_label)                 frame.set_child(box)         return frame         def create_theme_section(self):         frame = Gtk.Frame()         box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=12)         box.add_css_class("section")         box.set_margin_top(16)         box.set_margin_bottom(16)         box.set_margin_start(16)         box.set_margin_end(16)                 title_label = Gtk.Label()         title_label.set_markup("<span size='large' weight='bold'>? Select a Light or Dark Theme</span>")         title_label.set_halign(Gtk.Align.CENTER)         box.append(title_label)                 desc_label = Gtk.Label(label="Click on a button below to select either a Light Theme or a Dark Theme. The Light Theme is already the default theme.")         desc_label.set_wrap(True)         desc_label.set_halign(Gtk.Align.CENTER)         desc_label.set_justify(Gtk.Justification.CENTER)         box.append(desc_label)                 # Light theme with preview         light_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=8)         light_box.add_css_class("section")         light_box.set_halign(Gtk.Align.CENTER)         light_btn = self.create_button("Light Theme", "weather-clear-symbolic", "lighttheme", "suggested-action")         light_box.append(light_btn)         light_img_path = os.path.join(self.data_path, "img", "lightth.png")         if os.path.exists(light_img_path):             light_img = load_image_from_file(light_img_path, width=380, height=192)             if light_img:                 light_img.set_halign(Gtk.Align.CENTER)                 light_img.set_valign(Gtk.Align.CENTER)                 light_img.set_size_request(380, 192)                 light_box.append(light_img)         box.append(light_box)         # Dark theme with preview         dark_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=8)         dark_box.add_css_class("section")         dark_box.set_halign(Gtk.Align.CENTER)         dark_btn = self.create_button("Dark Theme", "weather-clear-night-symbolic", "darktheme", "")         dark_box.append(dark_btn)         dark_img_path = os.path.join(self.data_path, "img", "darkth.png")         if os.path.exists(dark_img_path):             dark_img = load_image_from_file(dark_img_path, width=380, height=192)             if dark_img:                 dark_img.set_halign(Gtk.Align.CENTER)                 dark_img.set_valign(Gtk.Align.CENTER)                 dark_img.set_size_request(380, 192)                 dark_box.append(dark_img)         box.append(dark_box)                 frame.set_child(box)         return frame         def create_keyboard_section(self):         frame = Gtk.Frame()         box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=12)         box.add_css_class("section")         box.set_margin_top(16)         box.set_margin_bottom(16)         box.set_margin_start(16)         box.set_margin_end(16)                 title_label = Gtk.Label()         title_label.set_markup("<span size='large' weight='bold'>⌨️ Keyboard and Numlock</span>")         title_label.set_halign(Gtk.Align.CENTER)         box.append(title_label)                 kb_text = """There are thousands of computing configurations in existence. As a result, different manufacturers have different ways of implementing their Keyboard and Numlock settings. When you boot Linux Lite for the first time and are having issues with your Keyboard and or Numlock, try each of the following solutions: • Check your BIOS/UEFI configuration • Menu, Settings, Lite Tweaks, Numlock • FN (Function) + NUM LOCK • FN + F11 (Acer, Toshiba, Samsung) • Shift + NUM LOCK • FN + NUM LOCK (Sony, Gateway, Lenovo, ASUS) • FN + F8 (HP) • Ctrl + F11 • FN + Shift + NUM LOCK • FN + F4 (Dell) <b>Keep Numlock working between boots</b> - Menu, Settings, Keyboard, Behavior tab > Enable or Disable - <b>Restore num lock state on startup</b>"""                 desc_label = Gtk.Label()         desc_label.set_markup(kb_text)         desc_label.set_wrap(True)         desc_label.set_halign(Gtk.Align.CENTER)         desc_label.set_justify(Gtk.Justification.CENTER)         box.append(desc_label)                 frame.set_child(box)         return frame         def create_upgrade_section(self):         frame = Gtk.Frame()         box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=12)         box.add_css_class("section")         box.set_margin_top(16)         box.set_margin_bottom(16)         box.set_margin_start(16)         box.set_margin_end(16)                 title_label = Gtk.Label()         title_label.set_markup("<span size='large' weight='bold'>? Upgrading</span>")         title_label.set_halign(Gtk.Align.CENTER)         box.append(title_label)                 upgrade_text = """Each <b>Series</b> of Linux Lite lasts 2 years and is based off LTS (Long Term Support) which continues to provide updates for 5 years. eg. Linux Lite <b>4.0</b> - Linux Lite <b>4.8</b> is <b>Series 4</b>, Linux Lite <b>5.0</b> is the start of <b>Series 5</b>, and so on. Upgrading within <b>Series 7</b> is simple. Click on <b>Menu, Settings, Lite Upgrade</b> and follow the prompts to get the latest version of Linux Lite. Upgrading can only occur from within a <b>Series</b>. For example we will upgrade you from Linux Lite <b>7.0</b> to Linux Lite <b>7.8</b>, but not from Linux Lite <b>6.0</b> to Linux Lite <b>7.8</b>."""                 desc_label = Gtk.Label()         desc_label.set_markup(upgrade_text)         desc_label.set_wrap(True)         desc_label.set_halign(Gtk.Align.CENTER)         desc_label.set_justify(Gtk.Justification.CENTER)         box.append(desc_label)                 button = self.create_button("Upgrade to 7.8", "system-upgrade-symbolic", "upgrade", "suggested-action")         button.set_halign(Gtk.Align.CENTER)         box.append(button)                 frame.set_child(box)         return frame         def create_software_section(self):         frame = Gtk.Frame()         box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=12)         box.add_css_class("section")         box.set_margin_top(16)         box.set_margin_bottom(16)         box.set_margin_start(16)         box.set_margin_end(16)                 title_label = Gtk.Label()         title_label.set_markup("<span size='large' weight='bold'>? Lite Software</span>")         title_label.set_halign(Gtk.Align.CENTER)         box.append(title_label)                 software_text = """We've made it as simple as just a few clicks to install many of your favorite programs. On Linux Lite you can install: • Dropbox • Firefox Web Browser • Kodi • Spotify • Steam • Teamviewer • Tor Web Browser • VirtualBox • Zoom Click on <b>Menu, Settings, Lite Software</b> and follow the onscreen prompts to install popular software or click on the button below."""                 desc_label = Gtk.Label()         desc_label.set_markup(software_text)         desc_label.set_wrap(True)         desc_label.set_halign(Gtk.Align.CENTER)         desc_label.set_justify(Gtk.Justification.CENTER)         box.append(desc_label)                 button = self.create_button("Lite Software", "system-software-install-symbolic", "start_software", "")         button.set_halign(Gtk.Align.CENTER)         box.append(button)                 frame.set_child(box)         return frame         def create_hardware_section(self):         frame = Gtk.Frame()         box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=12)         box.add_css_class("section")         box.set_margin_top(16)         box.set_margin_bottom(16)         box.set_margin_start(16)         box.set_margin_end(16)                 title_label = Gtk.Label()         title_label.set_markup("<span size='large' weight='bold'>? Hardware Recommendations</span>")         title_label.set_halign(Gtk.Align.CENTER)         box.append(title_label)                 hw_text = """Linux Lite can run on a wide range of hardware. Our online Hardware Database contains a growing list of computers that can run Linux Lite. <b>Recommended Computer Requirements:</b> • 1.5 Ghz Dual Core Processor • 4 GB Memory • 40 GB HDD/SSD/NVME • VGA, DVI, DP or HDMI screen capable of 1366x768 resolution • DVD drive or USB port for the ISO image • Disable Secure Boot <b>TIP:</b> Check out the Linux Lite Hardware Database for a list of over 97,000 computers that can run Linux Lite."""                 desc_label = Gtk.Label()         desc_label.set_markup(hw_text)         desc_label.set_wrap(True)         desc_label.set_halign(Gtk.Align.CENTER)         desc_label.set_justify(Gtk.Justification.CENTER)         box.append(desc_label)                 button = self.create_button("Hardware Database", "computer-symbolic", "link:https://mityer.khdlhfjijfrupr.tk/hardware.php", "")         button.set_halign(Gtk.Align.CENTER)         box.append(button)                 frame.set_child(box)         return frame class SupportPage(NavigationPage):     def __init__(self, app, data_path):         super().__init__(app, "Get Support")         self.data_path = data_path         self.sections = {}         self.scrolled = None         self.build_ui()         def build_ui(self):         self.scrolled = Gtk.ScrolledWindow()         self.scrolled.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)         self.scrolled.set_vexpand(True)                 content = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=24)         content.set_margin_top(24)         content.set_margin_bottom(24)         content.set_margin_start(32)         content.set_margin_end(32)                 header = self.create_header("Get Support")         content.append(header)                 # Online Support intro         intro_frame = Gtk.Frame()         intro_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=12)         intro_box.add_css_class("section")         intro_box.set_margin_top(16)         intro_box.set_margin_bottom(16)         intro_box.set_margin_start(16)         intro_box.set_margin_end(16)                 intro_title = Gtk.Label()         intro_title.set_markup("<span size='large' weight='bold'>? Online Support</span>")         intro_title.set_halign(Gtk.Align.CENTER)         intro_box.append(intro_title)                 intro_desc = Gtk.Label(label="Linux Lite aims to provide you with a variety of Support options.")         intro_desc.set_wrap(True)         intro_desc.set_halign(Gtk.Align.CENTER)         intro_desc.set_justify(Gtk.Justification.CENTER)         intro_box.append(intro_desc)                 intro_frame.set_child(intro_box)         self.sections["online"] = intro_frame         content.append(intro_frame)                 # Linux Lite Wiki section         wiki_frame = Gtk.Frame()         wiki_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=12)         wiki_box.add_css_class("section")         wiki_box.set_margin_top(16)         wiki_box.set_margin_bottom(16)         wiki_box.set_margin_start(16)         wiki_box.set_margin_end(16)                 wiki_title = Gtk.Label()         wiki_title.set_markup("<span size='large' weight='bold'>? Linux Lite Wiki</span>")         wiki_title.set_halign(Gtk.Align.CENTER)         wiki_box.append(wiki_title)                 wiki_desc = Gtk.Label()         wiki_desc.set_markup("Click on <b>Menu, Favorites, Linux Lite Wiki</b>. The Wiki is divided into clear categories - <b>Install Guide, Network, Software and Hardware</b>. Each tutorial has step by step instructions, with accompanying pictures. You can also access our Wiki online by clicking below:")         wiki_desc.set_wrap(True)         wiki_desc.set_halign(Gtk.Align.CENTER)         wiki_desc.set_justify(Gtk.Justification.CENTER)         wiki_box.append(wiki_desc)                 wiki_btn = self.create_button("Online Wiki", "accessories-dictionary-symbolic", "link:https://wiki.linuxliteos.com/en/home", "")         wiki_btn.set_halign(Gtk.Align.CENTER)         wiki_box.append(wiki_btn)                 wiki_frame.set_child(wiki_box)         self.sections["wiki"] = wiki_frame         content.append(wiki_frame)                 # Forums section         forums_frame = Gtk.Frame()         forums_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=12)         forums_box.add_css_class("section")         forums_box.set_margin_top(16)         forums_box.set_margin_bottom(16)         forums_box.set_margin_start(16)         forums_box.set_margin_end(16)                 forums_title = Gtk.Label()         forums_title.set_markup("<span size='large' weight='bold'>? Forums</span>")         forums_title.set_halign(Gtk.Align.CENTER)         forums_box.append(forums_title)                 forums_desc = Gtk.Label()         forums_desc.set_markup("Forums are a great resource for information. Begin by searching for your problem:\n\nIf no results turn up, by all means please post a new thread in the correct section clearly describing your situation. Once you have activated your account, you'll need to login before you can post.")         forums_desc.set_wrap(True)         forums_desc.set_halign(Gtk.Align.CENTER)         forums_desc.set_justify(Gtk.Justification.CENTER)         forums_box.append(forums_desc)                 forums_buttons = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=8)         forums_buttons.set_halign(Gtk.Align.CENTER)                 search_btn = self.create_button("Search Forums", "system-search-symbolic", "link:https://mityer.khdlhfjijfrupr.tk/forums/search.php", "")         forums_buttons.append(search_btn)                 register_btn = self.create_button("Register", "contact-new-symbolic", "link:https://mityer.khdlhfjijfrupr.tk/forums/member.php?action=register", "")         forums_buttons.append(register_btn)                 login_btn = self.create_button("Login", "system-users-symbolic", "link:https://mityer.khdlhfjijfrupr.tk/forums/", "")         forums_buttons.append(login_btn)                 forums_box.append(forums_buttons)         forums_frame.set_child(forums_box)         self.sections["forums"] = forums_frame         content.append(forums_frame)                 # Hardware Database section         hw_frame = Gtk.Frame()         hw_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=12)         hw_box.add_css_class("section")         hw_box.set_margin_top(16)         hw_box.set_margin_bottom(16)         hw_box.set_margin_start(16)         hw_box.set_margin_end(16)                 hw_title = Gtk.Label()         hw_title.set_markup("<span size='large' weight='bold'>? Hardware Database</span>")         hw_title.set_halign(Gtk.Align.CENTER)         hw_box.append(hw_title)                 hw_desc = Gtk.Label()         hw_desc.set_markup("The purpose of the <b>Linux Lite Hardware Database</b> is to give people an idea of different computer configurations from within a Linux Lite Series including, <b>Make and Model, CPU, Graphics, Audio, Network and Storage</b> technical specifications.\n\nThese hardware combinations provide a snapshot of the kind of computers people are able to use with Linux Lite. This makes it a great resource for people either thinking of buying new hardware, or seeing if their existing machine is capable of running Linux Lite.")         hw_desc.set_wrap(True)         hw_desc.set_halign(Gtk.Align.CENTER)         hw_desc.set_justify(Gtk.Justification.CENTER)         hw_box.append(hw_desc)                 hw_btn = self.create_button("Hardware Database", "computer-symbolic", "link:https://mityer.khdlhfjijfrupr.tk/hardware.php", "")         hw_btn.set_halign(Gtk.Align.CENTER)         hw_box.append(hw_btn)                 hw_frame.set_child(hw_box)         self.sections["hardware"] = hw_frame         content.append(hw_frame)                 # Tip box         tip_frame = Gtk.Frame()         tip_frame.add_css_class("success")         tip_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=8)         tip_box.set_margin_top(12)         tip_box.set_margin_bottom(12)         tip_box.set_margin_start(12)         tip_box.set_margin_end(12)                 tip_label = Gtk.Label()         tip_label.set_markup("<b>TIP:</b> The Forums are the best avenue for seeking answers. Our members are very generous with their time and there are always people willing to help you. Get help today.")         tip_label.set_wrap(True)         tip_label.set_halign(Gtk.Align.CENTER)         tip_label.set_justify(Gtk.Justification.CENTER)         tip_box.append(tip_label)                 tip_frame.set_child(tip_box)         content.append(tip_frame)                 self.scrolled.set_child(content)         self.append(self.scrolled)         def scroll_to_section(self, section_name):         if section_name not in self.sections:             return         self.pending_scroll = section_name         GLib.idle_add(self._perform_scroll)         def _perform_scroll(self):         if not hasattr(self, 'pending_scroll') or not self.pending_scroll:             return False         section_name = self.pending_scroll         self.pending_scroll = None                 if section_name not in self.sections:             return False                     target = self.sections[section_name]         content = self.scrolled.get_child()         if hasattr(content, 'get_child'):             content = content.get_child()                 y_pos = 0         child = content.get_first_child() if content else None         while child:             if child == target:                 break             h = child.get_height()             if h <= 0:                 h = child.get_preferred_size().minimum_size.height             y_pos += h + 24             child = child.get_next_sibling()                 adj = self.scrolled.get_vadjustment()         adj.set_value(y_pos)         return False class ContributePage(NavigationPage):     def __init__(self, app, data_path):         super().__init__(app, "Contribute")         self.data_path = data_path         self.sections = {}         self.scrolled = None         self.build_ui()         def build_ui(self):         self.scrolled = Gtk.ScrolledWindow()         self.scrolled.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)         self.scrolled.set_vexpand(True)                 content = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=24)         content.set_margin_top(24)         content.set_margin_bottom(24)         content.set_margin_start(32)         content.set_margin_end(32)                 header = self.create_header("Contribute")         content.append(header)                 # Code section         code_frame = Gtk.Frame()         code_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=12)         code_box.add_css_class("section")         code_box.set_margin_top(16)         code_box.set_margin_bottom(16)         code_box.set_margin_start(16)         code_box.set_margin_end(16)                 code_title = Gtk.Label()         code_title.set_markup("<span size='large' weight='bold'>? Code</span>")         code_title.set_halign(Gtk.Align.CENTER)         code_box.append(code_title)                 code_desc = Gtk.Label()         code_desc.set_markup("This is a very exciting time in Linux Lite development. We are in the process of producing custom, free software for Linux Lite. Our philosophy is basic code, simple design and minimal dependency. Our applications should be clean, fast and simple. Intelligent, well thought out design with great attention to detail.\n\nWe use the GPL v2. If you're a developer and would like to help with Linux Lite, click below. We also pay developers to help improve our software.")         code_desc.set_wrap(True)         code_desc.set_halign(Gtk.Align.CENTER)         code_desc.set_justify(Gtk.Justification.CENTER)         code_box.append(code_desc)                 code_btn = self.create_button("Learn More", "utilities-terminal-symbolic", "link:https://mityer.khdlhfjijfrupr.tk/contribute.html", "")         code_btn.set_halign(Gtk.Align.CENTER)         code_box.append(code_btn)                 code_frame.set_child(code_box)         self.sections["code"] = code_frame         content.append(code_frame)                 # Donate section         donate_frame = Gtk.Frame()         donate_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=12)         donate_box.add_css_class("section")         donate_box.set_margin_top(16)         donate_box.set_margin_bottom(16)         donate_box.set_margin_start(16)         donate_box.set_margin_end(16)                 donate_title = Gtk.Label()         donate_title.set_markup("<span size='large' weight='bold'>❤️ Donate</span>")         donate_title.set_halign(Gtk.Align.CENTER)         donate_box.append(donate_title)                 donate_desc = Gtk.Label()         donate_desc.set_markup("Linux Lite is free and can best be described as a labour of love.\n\nThe goal of this project is to work on it full time so that we can deliver to you a better operating system with each release. More time, more features, greater options. If you use Linux Lite and want to contribute towards its success, consider donating.\n\nDonations go towards development and online services such as websites and repositories, as well as hardware purchases. Every donor is listed on our donate page, regardless of their contribution. Thanks for making a difference and for supporting free software.\n\nLinux Lite pays developers to help improve our custom software through developer services such as UpWork.")         donate_desc.set_wrap(True)         donate_desc.set_halign(Gtk.Align.CENTER)         donate_desc.set_justify(Gtk.Justification.CENTER)         donate_box.append(donate_desc)                 donate_btn = self.create_button("Donate", "emblem-favorite-symbolic", "link:https://mityer.khdlhfjijfrupr.tk/donate.html", "suggested-action")         donate_btn.set_halign(Gtk.Align.CENTER)         donate_box.append(donate_btn)                 donate_frame.set_child(donate_box)         self.sections["donate"] = donate_frame         content.append(donate_frame)                 # Host a Mirror section         mirror_frame = Gtk.Frame()         mirror_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=12)         mirror_box.add_css_class("section")         mirror_box.set_margin_top(16)         mirror_box.set_margin_bottom(16)         mirror_box.set_margin_start(16)         mirror_box.set_margin_end(16)                 mirror_title = Gtk.Label()         mirror_title.set_markup("<span size='large' weight='bold'>? Host a Mirror</span>")         mirror_title.set_halign(Gtk.Align.CENTER)         mirror_box.append(mirror_title)                 mirror_desc = Gtk.Label()         mirror_desc.set_markup("Help support the Linux Lite community by hosting an official mirror. By providing a mirror, you'll help users worldwide enjoy faster downloads and better access to Linux Lite updates.\n\nOnce your mirror is approved and added, it will appear on our official Mirrors page. For details on how to set up and contribute a mirror, please contact us at our Feedback page.")         mirror_desc.set_wrap(True)         mirror_desc.set_halign(Gtk.Align.CENTER)         mirror_desc.set_justify(Gtk.Justification.CENTER)         mirror_box.append(mirror_desc)                 mirror_btn = self.create_button("Learn More", "folder-download-symbolic", "link:https://mityer.khdlhfjijfrupr.tk/feedback.html", "")         mirror_btn.set_halign(Gtk.Align.CENTER)         mirror_box.append(mirror_btn)                 mirror_frame.set_child(mirror_box)         self.sections["mirror"] = mirror_frame         content.append(mirror_frame)                 # Social Media section         social_frame = Gtk.Frame()         social_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=12)         social_box.add_css_class("section")         social_box.set_margin_top(16)         social_box.set_margin_bottom(16)         social_box.set_margin_start(16)         social_box.set_margin_end(16)                 social_title = Gtk.Label()         social_title.set_markup("<span size='large' weight='bold'>? Social Media</span>")         social_title.set_halign(Gtk.Align.CENTER)         social_box.append(social_title)                 social_desc = Gtk.Label()         social_desc.set_markup("Social Media has become a very powerful and effective way of proliferating knowledge throughout the world. We encourage you to spread the word about free operating systems such as Linux Lite.")         social_desc.set_wrap(True)         social_desc.set_halign(Gtk.Align.CENTER)         social_desc.set_justify(Gtk.Justification.CENTER)         social_box.append(social_desc)                 # Social media buttons         social_buttons = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=8)         social_buttons.set_halign(Gtk.Align.CENTER)                 social_links = [             ("social-facebook.png", "https://www.facebook.com/linuxliteos", "Facebook"),             ("social-twitter.png", "https://twitter.com/LinuxLite", "Twitter"),             ("social-discord.png", "https://discord.gg/bQSFaFAUkm", "Discord"),             ("social-instagram.png", "https://www.instagram.com/linuxliteos", "Instagram"),             ("social-linkedin.png", "https://www.linkedin.com/in/jerrybezencon", "LinkedIn"),             ("youtube.svg", "https://www.youtube.com/c/linuxliteos", "YouTube"),             ("social-reddit.svg", "https://www.reddit.com/r/LinuxLite/", "Reddit"),         ]                 for img_file, url, tooltip in social_links:             btn = Gtk.Button()             btn.add_css_class("flat")             btn.set_tooltip_text(tooltip)                         img_path = os.path.join(self.data_path, "img", img_file)             icon = load_image_from_file(img_path, width=32, height=32)             if icon:                 btn.set_child(icon)             else:                 btn.set_label(tooltip[0])                         btn.connect("clicked", lambda b, u=url: self.cmd_handler.open_url(u))             social_buttons.append(btn)                 social_box.append(social_buttons)         social_frame.set_child(social_box)         self.sections["social"] = social_frame         content.append(social_frame)                 # Tip box         tip_frame = Gtk.Frame()         tip_frame.add_css_class("success")         tip_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=8)         tip_box.set_margin_top(12)         tip_box.set_margin_bottom(12)         tip_box.set_margin_start(12)         tip_box.set_margin_end(12)                 tip_label = Gtk.Label()         tip_label.set_markup("<b>TIP:</b> Social Media is a great way to spread the word about free operating systems such as Linux Lite. If you've come to Linux for the first time, share your experiences with the people you know online via Facebook, Twitter, Discord, Instagram, LinkedIn, YouTube, Reddit, and other Social Networking sites.")         tip_label.set_wrap(True)         tip_label.set_halign(Gtk.Align.CENTER)         tip_label.set_justify(Gtk.Justification.CENTER)         tip_box.append(tip_label)                 tip_frame.set_child(tip_box)         content.append(tip_frame)                 self.scrolled.set_child(content)         self.append(self.scrolled)         def scroll_to_section(self, section_name):         if section_name not in self.sections:             return         self.pending_scroll = section_name         GLib.idle_add(self._perform_scroll)         def _perform_scroll(self):         if not hasattr(self, 'pending_scroll') or not self.pending_scroll:             return False         section_name = self.pending_scroll         self.pending_scroll = None                 if section_name not in self.sections:             return False                     target = self.sections[section_name]         content = self.scrolled.get_child()         if hasattr(content, 'get_child'):             content = content.get_child()                 y_pos = 0         child = content.get_first_child() if content else None         while child:             if child == target:                 break             h = child.get_height()             if h <= 0:                 h = child.get_preferred_size().minimum_size.height             y_pos += h + 24             child = child.get_next_sibling()                 adj = self.scrolled.get_vadjustment()         adj.set_value(y_pos)         return False class LiteWelcomeApp(Adw.Application):     def __init__(self):         super().__init__(application_id=APP_ID, flags=Gio.ApplicationFlags.FLAGS_NONE)         self.window = None         self.config = WelcomeConfig()         self.cmd_handler = CommandHandler(self)  # Pass app reference for toast notifications         self.stack = None         self.toast_overlay = None  # For progress feedback         self.css_provider = None  # For theme switching                 here = os.path.dirname(os.path.abspath(__file__))         if os.path.exists('/usr/share/litewelcome'):             self.data_path = '/usr/share/litewelcome'         else:             self.data_path = here         def load_css(self):         """Load custom CSS for the application based on system theme."""         # Get the style manager to detect system color scheme         style_manager = Adw.StyleManager.get_default()         is_dark = style_manager.get_dark()                 # Connect to color scheme changes         style_manager.connect("notify::dark", self._on_color_scheme_changed)                 self._apply_css(is_dark)         def _on_color_scheme_changed(self, style_manager, param):         """Called when system color scheme changes."""         is_dark = style_manager.get_dark()         self._apply_css(is_dark)         def _apply_css(self, is_dark):         """Apply CSS based on whether dark mode is active."""         # Remove old CSS provider if exists         if self.css_provider:             Gtk.StyleContext.remove_provider_for_display(                 Gdk.Display.get_default(),                 self.css_provider             )                 if is_dark:             css = b"""             /* Dark mode - dark backgrounds */             window, .background {                 background-color: #2d2d2d;             }                         /* Content area */             scrolledwindow, viewport {                 background-color: #2d2d2d;             }                         /* Frames for sections */             frame {                 background-color: #3d3d3d;                 border-radius: 8px;                 border: 1px solid #505050;             }                         /* Header bar styling */             headerbar {                 background-color: #383838;             }                         /* Footer/toolbar area */             .toolbar {                 background-color: #383838;                 border-top: 1px solid #505050;             }                         /* Tip boxes with green tint (darker) */             frame.success {                 background-color: #2d4a32;                 border: 1px solid #4a7c54;             }                         /* Base button styling with hover effects for all non-flat buttons */             button:not(.flat) {                 transition: background-color 150ms ease-in-out;             }                         /* Suggested action buttons (blue) */             button.suggested-action {                 background-color: @accent_bg_color;                 color: @accent_fg_color;             }             button.suggested-action:hover {                 background-color: shade(@accent_bg_color, 1.15);             }             button.suggested-action:active {                 background-color: shade(@accent_bg_color, 1.25);             }                         /* Destructive action buttons (red) */             button.destructive-action {                 background-color: @destructive_bg_color;                 color: @destructive_fg_color;             }             button.destructive-action:hover {                 background-color: shade(@destructive_bg_color, 1.15);             }             button.destructive-action:active {                 background-color: shade(@destructive_bg_color, 1.25);             }                         /* Regular buttons (no specific class) */             button:not(.flat):not(.suggested-action):not(.destructive-action):not(.image-button) {                 background-color: #505050;             }             button:not(.flat):not(.suggested-action):not(.destructive-action):not(.image-button):hover {                 background-color: #606060;             }             button:not(.flat):not(.suggested-action):not(.destructive-action):not(.image-button):active {                 background-color: #707070;             }                         /* Flat buttons (social icons) - subtle hover */             button.flat:hover {                 background-color: rgba(255, 255, 255, 0.1);             }             button.flat:active {                 background-color: rgba(255, 255, 255, 0.2);             }                         /* Social button size */             .social-button {                 min-width: 28px;                 min-height: 28px;                 padding: 4px;             }                         /* Tooltip styling - ensure readable text */             tooltip {                 background-color: #4a4a4a;                 color: #ffffff;             }             tooltip label {                 color: #ffffff;             }             """         else:             css = b"""             /* Light mode - light grey for good contrast */             window, .background {                 background-color: #f0f0f0;             }                         /* Content area */             scrolledwindow, viewport {                 background-color: #f0f0f0;             }                         /* Frames for sections */             frame {                 background-color: #ffffff;                 border-radius: 8px;                 border: 1px solid #d0d0d0;             }                         /* Header bar styling */             headerbar {                 background-color: #e8e8e8;             }                         /* Footer/toolbar area */             .toolbar {                 background-color: #e8e8e8;                 border-top: 1px solid #d0d0d0;             }                         /* Tip boxes with green tint */             frame.success {                 background-color: #e8f5e9;                 border: 1px solid #a5d6a7;             }             /* Base button styling with hover effects for all non-flat buttons */             button:not(.flat) {                 transition: background-color 150ms ease-in-out;             }                         /* Suggested action buttons (blue) */             button.suggested-action {                 background-color: @accent_bg_color;                 color: @accent_fg_color;             }             button.suggested-action:hover {                 background-color: shade(@accent_bg_color, 0.85);             }             button.suggested-action:active {                 background-color: shade(@accent_bg_color, 0.75);             }                         /* Destructive action buttons (red) */             button.destructive-action {                 background-color: @destructive_bg_color;                 color: @destructive_fg_color;             }             button.destructive-action:hover {                 background-color: shade(@destructive_bg_color, 0.85);             }             button.destructive-action:active {                 background-color: shade(@destructive_bg_color, 0.75);             }                         /* Regular buttons (no specific class) */             button:not(.flat):not(.suggested-action):not(.destructive-action):not(.image-button) {                 background-color: #e0e0e0;             }             button:not(.flat):not(.suggested-action):not(.destructive-action):not(.image-button):hover {                 background-color: #c8c8c8;             }             button:not(.flat):not(.suggested-action):not(.destructive-action):not(.image-button):active {                 background-color: #b0b0b0;             }                         /* Flat buttons (social icons) - subtle hover */             button.flat:hover {                 background-color: rgba(0, 0, 0, 0.08);             }             button.flat:active {                 background-color: rgba(0, 0, 0, 0.15);             }                         /* Social button size */             .social-button {                 min-width: 28px;                 min-height: 28px;                 padding: 4px;             }                         /* Tooltip styling - ensure black text on light background */             tooltip {                 background-color: #f5f5f5;                 color: #000000;             }             tooltip label {                 color: #000000;             }             """                 self.css_provider = Gtk.CssProvider()         self.css_provider.load_from_data(css)         Gtk.StyleContext.add_provider_for_display(             Gdk.Display.get_default(),             self.css_provider,             Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION         )         def do_activate(self):         if not self.window:             self.load_css()             self.window = Adw.ApplicationWindow(application=self)             self.window.set_title(APP_NAME)             self.window.set_default_size(850, 768)                         # Set taskbar icon by adding search path and using icon name             icon_theme = Gtk.IconTheme.get_for_display(Gdk.Display.get_default())             icon_theme.add_search_path("/usr/share/litewelcome/img")             self.window.set_icon_name("litewelcome")                         self.build_ui()                         # Center window on screen after it's realized             self.window.connect("realize", self._on_window_realize)         self.window.present()         def _on_window_realize(self, window):         """Called when window is realized - schedule centering."""         # Use idle_add to ensure the window is fully mapped before centering         GLib.idle_add(self._center_window_on_screen)         def _center_window_on_screen(self):         """Center the window on the primary monitor."""         try:             display = Gdk.Display.get_default()             if not display:                 return False                         # Get list of monitors             monitors = display.get_monitors()             if monitors.get_n_items() == 0:                 return False                         # Get the primary/first monitor             monitor = monitors.get_item(0)             geometry = monitor.get_geometry()                         # Window dimensions (use default size)             win_width = 850             win_height = 768                         # Calculate center position             x = geometry.x + (geometry.width - win_width) // 2             y = geometry.y + (geometry.height - win_height) // 2                         # Try X11-specific positioning (Linux Lite uses X11/Xfce)             if HAS_X11:                 surface = self.window.get_surface()                 if surface and isinstance(surface, GdkX11.X11Surface):                     xid = surface.get_xid()                     x11_display = display.get_xdisplay()                     if x11_display and xid:                         # Use ctypes to call XMoveWindow directly                         import ctypes                         try:                             xlib = ctypes.CDLL('libX11.so.6')                             xlib.XMoveWindow(x11_display, xid, x, y)                             xlib.XFlush(x11_display)                         except (OSError, AttributeError):                             pass         except Exception as e:             print(f"Could not center window: {e}")                 return False  # Don't repeat the idle callback         def build_ui(self):         # Create toast overlay for progress feedback         self.toast_overlay = Adw.ToastOverlay()                 main_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0)                 header = Adw.HeaderBar()         header.set_show_end_title_buttons(True)                 self.back_button = Gtk.Button.new_from_icon_name("go-previous-symbolic")         self.back_button.set_tooltip_text("Back to Home")         self.back_button.connect("clicked", self.on_back_clicked)         self.back_button.set_visible(False)         header.pack_start(self.back_button)                 title = Adw.WindowTitle.new(APP_NAME, "")         header.set_title_widget(title)         main_box.append(header)                 self.stack = Gtk.Stack()         self.stack.set_transition_type(Gtk.StackTransitionType.SLIDE_LEFT_RIGHT)         self.stack.set_transition_duration(250)         self.stack.set_vexpand(True)                 self.stack.add_named(HomePage(self, self.data_path), "home")         self.stack.add_named(StartPage(self, self.data_path), "start")         self.stack.add_named(SupportPage(self, self.data_path), "support")         self.stack.add_named(ContributePage(self, self.data_path), "contribute")                 main_box.append(self.stack)         main_box.append(self.create_footer())                 # Wrap main content in toast overlay         self.toast_overlay.set_child(main_box)         self.window.set_content(self.toast_overlay)         def show_toast(self, message, timeout=2):         """Show a toast notification with the given message."""         if self.toast_overlay:             toast = Adw.Toast.new(message)             toast.set_timeout(timeout)             self.toast_overlay.add_toast(toast)         def create_footer(self):         footer = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=8)         footer.add_css_class("toolbar")         footer.set_margin_start(16)         footer.set_margin_end(16)         footer.set_margin_top(8)         footer.set_margin_bottom(8)                 social_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=6)                 # Social media buttons with images - larger for better click targets         social_links = [             ("social-facebook.png", "https://www.facebook.com/linuxliteos", "Facebook"),             ("gitlab.svg", "https://gitlab.com/linuxlite", "GitLab"),             ("social-twitter.png", "https://twitter.com/LinuxLite", "Twitter"),             ("youtube.svg", "https://www.youtube.com/c/linuxliteos", "YouTube"),             ("social-reddit.svg", "https://www.reddit.com/r/LinuxLite/", "Reddit"),             ("social-discord.png", "https://discord.gg/bQSFaFAUkm", "Discord"),         ]                 for img_file, url, tooltip in social_links:             btn = Gtk.Button()             btn.add_css_class("flat")             btn.add_css_class("social-button")  # Custom class for larger click target             btn.set_tooltip_text(tooltip)                         # Load the social media icon - larger size (28x28)             img_path = os.path.join(self.data_path, "img", img_file)             icon = load_image_from_file(img_path, width=28, height=28)             if icon:                 btn.set_child(icon)             else:                 # Fallback to first letter if image fails                 btn.set_label(tooltip[0])                         btn.connect("clicked", lambda b, u=url: self.cmd_handler.open_url(u))             social_box.append(btn)                 footer.append(social_box)                 spacer = Gtk.Box()         spacer.set_hexpand(True)         footer.append(spacer)                 autostart_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=6)         self.autostart_check = Gtk.CheckButton()         self.autostart_check.set_active(self.config.autostart)         self.autostart_check.connect("toggled", self.on_autostart_toggled)         autostart_box.append(self.autostart_check)         autostart_box.append(Gtk.Label(label="Show this dialog on startup"))         footer.append(autostart_box)                 close_btn = Gtk.Button(label="Close")         close_btn.set_margin_start(16)         close_btn.connect("clicked", lambda b: self.quit())         footer.append(close_btn)                 return footer         def navigate_to(self, page_spec):         if '#' in page_spec:             page, section = page_spec.split('#', 1)         else:             page = page_spec             section = None                 self.stack.set_visible_child_name(page)         self.back_button.set_visible(page != "home")                 # If a section was specified, scroll to it         if section:             page_widget = self.stack.get_child_by_name(page)             if hasattr(page_widget, 'scroll_to_section'):                 page_widget.scroll_to_section(section)         def on_back_clicked(self, button):         self.stack.set_visible_child_name("home")         self.back_button.set_visible(False)         def on_autostart_toggled(self, check):         self.config.toggle_autostart()         check.set_active(self.config.autostart) def main():     signal.signal(signal.SIGINT, lambda s, f: sys.exit(0))     return LiteWelcomeApp().run(sys.argv) if __name__ == '__main__':     sys.exit(main())

Download your free copy of Linux Lite today.

Jerry Bezencon
Linux Lite Creator

"Do not correct a fool, or he will hate you; correct a wise man and he will appreciate you."

[Image: X5qGkCg.png]

[Image: 0op1GNe.png] [Image: LgJ2mtP.png] [Image: vLZcFUE.png] [Image: lrUHro3.jpg]
Reply
#14

I replaced the code in the /bin/lite-welcome file with the code provided and then the app wouldn't open at all.  I noticed that the new code is around 300 lines longer (aprox 1600 lines) than the old code (aprox. 1300 lines).  Was the new code supposed to be that different than the previous?

Thanks
Reply
#15

Yes, different code. Make sure the application file is executable.

Download your free copy of Linux Lite today.

Jerry Bezencon
Linux Lite Creator

"Do not correct a fool, or he will hate you; correct a wise man and he will appreciate you."

[Image: X5qGkCg.png]

[Image: 0op1GNe.png] [Image: LgJ2mtP.png] [Image: vLZcFUE.png] [Image: lrUHro3.jpg]
Reply
#16

Ok, it's working now.  I'm not sure why it didn't work the first time because I had made the file executable.Thanks![attachment=303 Wrote:valtam pid='62774' dateline='1767585564']Yes, different code. Make sure the application file is executable.


Attached Files Thumbnail(s)
   
Reply
#17

No problem Smile

Download your free copy of Linux Lite today.

Jerry Bezencon
Linux Lite Creator

"Do not correct a fool, or he will hate you; correct a wise man and he will appreciate you."

[Image: X5qGkCg.png]

[Image: 0op1GNe.png] [Image: LgJ2mtP.png] [Image: vLZcFUE.png] [Image: lrUHro3.jpg]
Reply
#18

Should the included version of GIMP be updated to 3.x series?

The current version of GIMP that is included with LL is 2.10.36.  The 3.x version has been available for quite awhile now and 3.06 is the default on the gimp.org website.  When you open in LL and go to "Help > About" it recommends updating.

https://www.gimp.org/downloads


Attached Files Thumbnail(s)
   
Reply
#19

The Flatpack works OK. There is no native complete package for Ubuntu 24. Even the PPA has limitations.
https://ubuntuhandbook.org/index.php/202...ll-ubuntu/

TC

All opinions expressed and all advice given by Trinidad Cruz on this forum are his responsibility alone and do not necessarily reflect the views or methods of the developers of Linux Lite. He is a citizen of the United States where it is acceptable to occasionally be uninformed and inept as long as you pay your taxes.
Reply
#20

I added the ubuntuhandbook1/gimp-3 PPA and it upgraded fine that way afterwards but it doesn't sound like it's as up-to-date as the flatpak or snap versions so maybe not the best way to go but it's nice that it will updates with the rest of the system via "apt update" etc.

Option 3: Ubuntu PPA (unofficial)
For those who prefer the native
Code:
.deb
package format, I’ve built GIMP 3.0 into this unofficial PPA for Ubuntu 22.04, Ubuntu 24.04, and Ubuntu 24.10 on
Code:
amd64
,
Code:
arm64
/
Code:
armhf
platforms.
NOTE: The PPA package has few downsides:
  1. It’s built with system GTK3 library, which is a bit outdated. While, GIMP 3.0 relies on the most recent GTK3 library for some fixes.
  2. Also due to outdated library (libglib2.0-dev), the Ubuntu 22.04 package reversed this commit, or it won’t build.
  3. For Ubuntu 22.04, the PPA also contains updated versions of libheif, libwebp, kvazaar HEVC encoder that might conflict to other 3rd party packages.
To add the PPA, press
Code:
Ctrl+Alt+T
to open up a terminal window, and run command:
sudo add-apt-repository ppa:ubuntuhandbook1/gimp-3
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)