Compare commits
	
		
			No commits in common. "master" and "meconopsis" have entirely different histories.
		
	
	
		
			master
			...
			meconopsis
		
	
		
					 13 changed files with 261 additions and 689 deletions
				
			
		
							
								
								
									
										27
									
								
								config.py
									
										
									
									
									
								
							
							
						
						
									
										27
									
								
								config.py
									
										
									
									
									
								
							| 
						 | 
					@ -27,31 +27,33 @@
 | 
				
			||||||
# Import Theme
 | 
					# Import Theme
 | 
				
			||||||
from libqtile import hook
 | 
					from libqtile import hook
 | 
				
			||||||
from libqtile.log_utils import logger
 | 
					from libqtile.log_utils import logger
 | 
				
			||||||
from kuro.utils import load_config_class
 | 
					 | 
				
			||||||
import traceback
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
try:
 | 
					try:
 | 
				
			||||||
    from kuro.theme import Kuro
 | 
					    from kuro.theme import Kuro
 | 
				
			||||||
    Theme = Kuro()
 | 
					    Theme = Kuro()
 | 
				
			||||||
except ImportError as e:
 | 
					except ImportError as e:
 | 
				
			||||||
    logger.error(traceback.format_exc())
 | 
					 | 
				
			||||||
    logger.error("Could not load Kuro Theme. Trying to load BaseTheme. Error: {}".format(e))
 | 
					    logger.error("Could not load Kuro Theme. Trying to load BaseTheme. Error: {}".format(e))
 | 
				
			||||||
    try:
 | 
					    try:
 | 
				
			||||||
        from kuro.base import BaseTheme as Kuro
 | 
					        from kuro.base import BaseTheme as Kuro
 | 
				
			||||||
        Theme = Kuro()
 | 
					        Theme = Kuro()
 | 
				
			||||||
    except ImportError as e:
 | 
					    except ImportError as e:
 | 
				
			||||||
        Kuro = None
 | 
					        Kuro = None
 | 
				
			||||||
        logger.error(traceback.format_exc())
 | 
					 | 
				
			||||||
        raise ImportError("Could not load theme Config or BaseTheme! Error: {}".format(e))
 | 
					        raise ImportError("Could not load theme Config or BaseTheme! Error: {}".format(e))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Import theme configuration
 | 
					# Import theme configuration
 | 
				
			||||||
Config = load_config_class()
 | 
					try:
 | 
				
			||||||
if Config is None:
 | 
					    from kuro.config import Config
 | 
				
			||||||
    raise ImportError("Could not load theme Config or BaseConfig! Error: {}".format(e))
 | 
					except ImportError as e:
 | 
				
			||||||
 | 
					    logger.error("Could not load Kuro Config. Trying to load BaseConfig. Error: {}".format(e))
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        from kuro.base import BaseConfig as Config
 | 
				
			||||||
 | 
					    except ImportError as e:
 | 
				
			||||||
 | 
					        Config = None
 | 
				
			||||||
 | 
					        raise ImportError("Could not load theme Config or BaseConfig! Error: {}".format(e))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
try:
 | 
					try:
 | 
				
			||||||
    logger.warning("Initializing theme...")
 | 
					    logger.warning("Initializing theme...")
 | 
				
			||||||
    logger.warning(f"Using config variables for '{Config.get('config_name', '????')}'")
 | 
					 | 
				
			||||||
    # Initialize the Theme
 | 
					    # Initialize the Theme
 | 
				
			||||||
    Theme.initialize()
 | 
					    Theme.initialize()
 | 
				
			||||||
    logger.warning("Initialize done")
 | 
					    logger.warning("Initialize done")
 | 
				
			||||||
| 
						 | 
					@ -91,11 +93,7 @@ try:
 | 
				
			||||||
    groups = Theme.groups
 | 
					    groups = Theme.groups
 | 
				
			||||||
    layouts = Theme.layouts
 | 
					    layouts = Theme.layouts
 | 
				
			||||||
    widget_defaults = Theme.widget_defaults
 | 
					    widget_defaults = Theme.widget_defaults
 | 
				
			||||||
    if Config.get("use_fake_screens", False):
 | 
					    screens = Theme.screens
 | 
				
			||||||
        logger.warning(f"This host uses fake screens!")
 | 
					 | 
				
			||||||
        fake_screens = Theme.screens
 | 
					 | 
				
			||||||
    else:
 | 
					 | 
				
			||||||
        screens = Theme.screens
 | 
					 | 
				
			||||||
    dgroups_key_binder = Theme.dgroups_key_binder
 | 
					    dgroups_key_binder = Theme.dgroups_key_binder
 | 
				
			||||||
    dgroups_app_rules = Theme.dgroups_app_rules
 | 
					    dgroups_app_rules = Theme.dgroups_app_rules
 | 
				
			||||||
    main = Theme.main
 | 
					    main = Theme.main
 | 
				
			||||||
| 
						 | 
					@ -112,13 +110,10 @@ try:
 | 
				
			||||||
except Exception as e:
 | 
					except Exception as e:
 | 
				
			||||||
    Theme = None
 | 
					    Theme = None
 | 
				
			||||||
    Config = None
 | 
					    Config = None
 | 
				
			||||||
    logger.error(traceback.format_exc())
 | 
					 | 
				
			||||||
    raise AttributeError("Could not configure theme! Error: {}".format(e))
 | 
					    raise AttributeError("Could not configure theme! Error: {}".format(e))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def main(qtile):
 | 
					def main(qtile):
 | 
				
			||||||
    Config.initialize(qtile)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # set logging level
 | 
					    # set logging level
 | 
				
			||||||
    if Config.get('debug', False):
 | 
					    if Config.get('debug', False):
 | 
				
			||||||
        if Config.get('verbose', False):
 | 
					        if Config.get('verbose', False):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										17
									
								
								kuro/base.py
									
										
									
									
									
								
							
							
						
						
									
										17
									
								
								kuro/base.py
									
										
									
									
									
								
							| 
						 | 
					@ -1,5 +1,3 @@
 | 
				
			||||||
import time
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from libqtile import layout as libqtile_layout, layout, bar, widget
 | 
					from libqtile import layout as libqtile_layout, layout, bar, widget
 | 
				
			||||||
from libqtile.lazy import lazy
 | 
					from libqtile.lazy import lazy
 | 
				
			||||||
from libqtile.config import Key, Group, Screen, Drag, Click, Match
 | 
					from libqtile.config import Key, Group, Screen, Drag, Click, Match
 | 
				
			||||||
| 
						 | 
					@ -9,21 +7,13 @@ from libqtile.log_utils import logger
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class BaseConfig:
 | 
					class BaseConfig:
 | 
				
			||||||
    config_name = "KuroBase"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def get(cls, key, default):
 | 
					    def get(cls, key, default):
 | 
				
			||||||
        if hasattr(cls, key):
 | 
					        if hasattr(cls, key):
 | 
				
			||||||
            return getattr(cls, key)
 | 
					            return cls.__dict__[key]
 | 
				
			||||||
            #return cls.__dict__[key]
 | 
					 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            return default
 | 
					            return default
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					 | 
				
			||||||
    def initialize(cls, qtile):
 | 
					 | 
				
			||||||
        # Can do extra initialization based on qtile instance here
 | 
					 | 
				
			||||||
        pass
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
class BaseTheme:
 | 
					class BaseTheme:
 | 
				
			||||||
    # Changing variables initialized by function
 | 
					    # Changing variables initialized by function
 | 
				
			||||||
| 
						 | 
					@ -55,7 +45,7 @@ class BaseTheme:
 | 
				
			||||||
    auto_fullscreen = True
 | 
					    auto_fullscreen = True
 | 
				
			||||||
    focus_on_window_activation = "smart"
 | 
					    focus_on_window_activation = "smart"
 | 
				
			||||||
    extensions = []
 | 
					    extensions = []
 | 
				
			||||||
    reconfigure_screens = False
 | 
					    reconfigure_screens = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # XXX: Gasp! We're lying here. In fact, nobody really uses or cares about this
 | 
					    # XXX: Gasp! We're lying here. In fact, nobody really uses or cares about this
 | 
				
			||||||
    # string besides java UI toolkits; you can see several discussions on the
 | 
					    # string besides java UI toolkits; you can see several discussions on the
 | 
				
			||||||
| 
						 | 
					@ -70,9 +60,6 @@ class BaseTheme:
 | 
				
			||||||
    # 'export _JAVA_AWT_WM_NONREPARENTING=1'
 | 
					    # 'export _JAVA_AWT_WM_NONREPARENTING=1'
 | 
				
			||||||
    wmname = "LG3D"
 | 
					    wmname = "LG3D"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self):
 | 
					 | 
				
			||||||
        self.startup_time = time.time()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def initialize(self):
 | 
					    def initialize(self):
 | 
				
			||||||
        logger.info("Initializing widget defaults...")
 | 
					        logger.info("Initializing widget defaults...")
 | 
				
			||||||
        self.widget_defaults = self.init_widget_defaults()
 | 
					        self.widget_defaults = self.init_widget_defaults()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,23 +1,12 @@
 | 
				
			||||||
from kuro.base import BaseConfig
 | 
					from kuro.base import BaseConfig
 | 
				
			||||||
from libqtile.log_utils import logger
 | 
					 | 
				
			||||||
from libqtile.lazy import lazy
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Config variables used in the main configuration
 | 
					# Config variables used in the main configuration
 | 
				
			||||||
class Config(BaseConfig):
 | 
					class Config(BaseConfig):
 | 
				
			||||||
    config_name = "KuroGeneral"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Show debug bar and messages
 | 
					    # Show debug bar and messages
 | 
				
			||||||
    debug = False
 | 
					    debug = False
 | 
				
			||||||
    verbose = False
 | 
					    verbose = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # General variables
 | 
					 | 
				
			||||||
    homedir = "/home/kevin"
 | 
					 | 
				
			||||||
    use_fake_screens = False
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Screen configs (empty = autoconfig, otherwise list of Screen() kwarg dicts)
 | 
					 | 
				
			||||||
    screen_kwargs = []
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Colors
 | 
					    # Colors
 | 
				
			||||||
    foreground = "#ffffff"
 | 
					    foreground = "#ffffff"
 | 
				
			||||||
    background = "#000000"
 | 
					    background = "#000000"
 | 
				
			||||||
| 
						 | 
					@ -26,87 +15,35 @@ class Config(BaseConfig):
 | 
				
			||||||
    inactive_dark = "#333333"
 | 
					    inactive_dark = "#333333"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Predefined commands
 | 
					    # Predefined commands
 | 
				
			||||||
 | 
					    cmd_brightness_up = "sudo /usr/bin/xbacklight -inc 10"
 | 
				
			||||||
 | 
					    cmd_brightness_down = "sudo /usr/bin/xbacklight -dec 10"
 | 
				
			||||||
    cmd_screenshot = "/home/kevin/bin/screenshot.sh"
 | 
					    cmd_screenshot = "/home/kevin/bin/screenshot.sh"
 | 
				
			||||||
    cmd_alt_screenshot = "/home/kevin/bin/screenshot.sh"
 | 
					    cmd_alt_screenshot = "/home/kevin/bin/screenshot.sh"
 | 
				
			||||||
 | 
					    app_terminal = "ghostty"
 | 
				
			||||||
 | 
					    web_browser = "firefox"
 | 
				
			||||||
 | 
					    file_manager = "thunar"
 | 
				
			||||||
 | 
					    app_launcher = "wofi --show drun,run"
 | 
				
			||||||
    lock_command = "bash /home/kevin/bin/lock.sh"
 | 
					    lock_command = "bash /home/kevin/bin/lock.sh"
 | 
				
			||||||
    cliphistory_command = "/home/kevin/bin/cliphistory.sh"
 | 
					    cliphistory_command = "/home/kevin/bin/cliphistory.sh"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Default Applications
 | 
					 | 
				
			||||||
    app_terminal = "terminator"
 | 
					 | 
				
			||||||
    app_launcher = "wofi --show run,drun"
 | 
					 | 
				
			||||||
    app_launcer_x11 = "/home/kevin/bin/dmenu_wal.sh"
 | 
					 | 
				
			||||||
    file_manager = "thunar"
 | 
					 | 
				
			||||||
    visualizer_app = "glava"
 | 
					 | 
				
			||||||
    web_browser = "firefox"
 | 
					 | 
				
			||||||
    network_config = None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Group definitions
 | 
					 | 
				
			||||||
    groups = [
 | 
					 | 
				
			||||||
            {'name': ''},
 | 
					 | 
				
			||||||
            {'name': ''},
 | 
					 | 
				
			||||||
            {'name': ''},
 | 
					 | 
				
			||||||
            {'name': ''},
 | 
					 | 
				
			||||||
            {'name': ''},
 | 
					 | 
				
			||||||
            {'name': ''},
 | 
					 | 
				
			||||||
            {'name': ''},
 | 
					 | 
				
			||||||
            {'name': ''},
 | 
					 | 
				
			||||||
            {'name': ''},
 | 
					 | 
				
			||||||
            {'name': '', 'layout': 'floating', 'options': {'border_focus': '#990000', 'border_normal': '#440000'}}
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Extra keybind definitions
 | 
					 | 
				
			||||||
    extra_keys = [
 | 
					 | 
				
			||||||
        # Display modes
 | 
					 | 
				
			||||||
        {'modifiers': ['mod'], 'key': "Prior", 'action': lazy.spawn("bash /home/kevin/.screenlayout/3scrns_144_rrot.sh")},
 | 
					 | 
				
			||||||
        {'modifiers': ['mod'], 'key': "Next", 'action': lazy.spawn("bash /home/kevin/.screenlayout/3scrns_60_rrot.sh")},
 | 
					 | 
				
			||||||
        {'modifiers': ['mod'], 'key': "Home", 'action': lazy.spawn("bash /home/kevin/bin/monitor_day.sh")},
 | 
					 | 
				
			||||||
        {'modifiers': ['mod'], 'key': "End", 'action': lazy.spawn("bash /home/kevin/bin/monitor_night.sh")},
 | 
					 | 
				
			||||||
        {'modifiers': ['mod'], 'key': "Insert", 'action': lazy.spawn("bash /home/kevin/bin/monitor_gamenight.sh")},
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # Backlight keys
 | 
					 | 
				
			||||||
        {'modifiers': [], 'key': "XF86MonBrightnessUp", 'action': lazy.spawn("sudo /usr/bin/xbacklight -inc 10")},
 | 
					 | 
				
			||||||
        {'modifiers': [], 'key': "XF86MonBrightnessDown", 'action': lazy.spawn("sudo /usr/bin/xbacklight -dec 10")},
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Extra floating window rules
 | 
					 | 
				
			||||||
    extra_float_rules = [
 | 
					 | 
				
			||||||
        # Wine Origin game launcher
 | 
					 | 
				
			||||||
        {'title': 'origin.exe', 'wm_class': 'Wine'},
 | 
					 | 
				
			||||||
        # Homebank popups
 | 
					 | 
				
			||||||
        {'title': 'Add transaction', 'wm_class': 'homebank'},
 | 
					 | 
				
			||||||
        {'title': 'Edit transaction', 'wm_class': 'homebank'},
 | 
					 | 
				
			||||||
        {'title': 'Inherit transaction', 'wm_class': 'homebank'},
 | 
					 | 
				
			||||||
        {'title': 'Multiple edit transactions', 'wm_class': 'homebank'},
 | 
					 | 
				
			||||||
        {'title': 'Transaction splits', 'wm_class': 'homebank'},
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Autostart applications
 | 
					    # Autostart applications
 | 
				
			||||||
    apps_autostart_group = [
 | 
					    apps_autostart_group = [
 | 
				
			||||||
        {'group': "", 'command': ["firefox"]},
 | 
					        {'group': "", 'command': ["firefox"]},
 | 
				
			||||||
        {'group': "", 'command': ["terminator"]},
 | 
					        {'group': "", 'command': ["ghostty", "--gtk-single-instance=true", "--quit-after-last-window-close=false", "--initial-window=true"]},
 | 
				
			||||||
        {'group': "", 'command': ["/usr/bin/rambox"]},
 | 
					        {'group': "", 'command': ["/usr/bin/rambox"]},
 | 
				
			||||||
        {'group': "", 'command': ["thunar"]},
 | 
					        {'group': "", 'command': ["thunar"]},
 | 
				
			||||||
        {'group': "", 'command': ["thunderbird"]},
 | 
					        {'group': "", 'command': ["thunderbird"]},
 | 
				
			||||||
        {'group': "", 'command': ["spotify"]},
 | 
					        {'group': "", 'command': ["spotify"]},
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
    apps_autostart = {
 | 
					    apps_autostart = [
 | 
				
			||||||
        'common': [
 | 
					        # ["ulauncher", "--hide-window", "--no-window-shadow"],  # App launcher background daemon
 | 
				
			||||||
            ["/usr/lib/kdeconnectd"],  # KDE Connect daemon
 | 
					        ["mako"],                       # Notification daemon
 | 
				
			||||||
            ["kdeconnect-indicator"],  # KDE Connect tray
 | 
					        ["kanshi"],                     # Display hotplug
 | 
				
			||||||
            ["vorta"],                 # Vorta backup scheduler
 | 
					        ["wl-paste", "--watch", "cliphist", "store"],  # Clipboard manager
 | 
				
			||||||
        ],
 | 
					        ["/usr/lib/kdeconnectd"],       # KDE Connect daemon
 | 
				
			||||||
        'x11': [
 | 
					        ["kdeconnect-indicator"],       # KDE Connect tray
 | 
				
			||||||
            ["dunst"],          # Notification daemon
 | 
					        ["vorta"],                      # Vorta backup scheduler
 | 
				
			||||||
            ["picom", "-b"],    # Compositor
 | 
					    ]
 | 
				
			||||||
            ["xfce4-clipman"],  # Clipboard manager
 | 
					 | 
				
			||||||
            ["xiccd"],          # Color profile manager
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
        'wayland': [
 | 
					 | 
				
			||||||
            ["mako"],    # Notification daemon
 | 
					 | 
				
			||||||
            ["wl-paste", "--watch", "cliphist", "store"],  # Clipboard manager
 | 
					 | 
				
			||||||
            ["kanshi"],  # Display hotplugging
 | 
					 | 
				
			||||||
        ]
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Keyboard commands
 | 
					    # Keyboard commands
 | 
				
			||||||
    cmd_media_play = "playerctl -i kdeconnect play-pause"
 | 
					    cmd_media_play = "playerctl -i kdeconnect play-pause"
 | 
				
			||||||
| 
						 | 
					@ -116,16 +53,19 @@ class Config(BaseConfig):
 | 
				
			||||||
    cmd_media_volume_up = "pamixer -d 2"
 | 
					    cmd_media_volume_up = "pamixer -d 2"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Display mode commands
 | 
					    # Display mode commands
 | 
				
			||||||
 | 
					    cmd_monitor_mode_3s144 = "bash /home/kevin/.screenlayout/3scrns_144_rrot.sh"
 | 
				
			||||||
 | 
					    cmd_monitor_mode_3s60 = "bash /home/kevin/.screenlayout/3scrns_60_rrot.sh"
 | 
				
			||||||
 | 
					    cmd_monitor_mode_day = "bash /home/kevin/bin/monitor_day.sh"
 | 
				
			||||||
 | 
					    cmd_monitor_mode_night = "bash /home/kevin/bin/monitor_night.sh"
 | 
				
			||||||
 | 
					    cmd_monitor_mode_alt = "bash /home/kevin/bin/monitor_gamenight.sh"
 | 
				
			||||||
    cmd_reconfigure_screens = "kanshictl reload"
 | 
					    cmd_reconfigure_screens = "kanshictl reload"
 | 
				
			||||||
    cmd_wal = ["wallust", "run"]
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Commands
 | 
					    # Commands
 | 
				
			||||||
    x11_wallpaper_config_command = "/home/kevin/bin/wal-nitrogen-noupdate"  # TODO: Remove
 | 
					    wallpaper_config_command = "/bin/true"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Images
 | 
					    # Images
 | 
				
			||||||
    desktop_bg = "/home/kevin/Pictures/wallpapers/desktop.png"
 | 
					    desktop_bg = "/home/kevin/Pictures/wallpapers/desktop.png"
 | 
				
			||||||
    desktop_bg_folder = "/home/kevin/Pictures/wallpapers/desktop_rotation/day"
 | 
					    desktop_bg_folder = "/home/kevin/Pictures/wallpapers/desktop_rotation"
 | 
				
			||||||
    desktop_bg_night_folder = "/home/kevin/Pictures/wallpapers/desktop_rotation/night"
 | 
					 | 
				
			||||||
    # desktop_bg_override = "/home/kevin/Pictures/safe_wallpaper.jpg"
 | 
					    # desktop_bg_override = "/home/kevin/Pictures/safe_wallpaper.jpg"
 | 
				
			||||||
    applauncher_image = "/home/kevin/.config/qtile/kuro/resources/arch.png"
 | 
					    applauncher_image = "/home/kevin/.config/qtile/kuro/resources/arch.png"
 | 
				
			||||||
    custom_layout_icon_paths = ['/home/kevin/.config/qtile/kuro/resources/layout_icons/']
 | 
					    custom_layout_icon_paths = ['/home/kevin/.config/qtile/kuro/resources/layout_icons/']
 | 
				
			||||||
| 
						 | 
					@ -202,10 +142,10 @@ class Config(BaseConfig):
 | 
				
			||||||
    battery_update_delay = 5
 | 
					    battery_update_delay = 5
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Network variables
 | 
					    # Network variables
 | 
				
			||||||
    wifi_interface = "wifi0"
 | 
					    wifi_interface = "wlp3s0"
 | 
				
			||||||
    wifi_theme_path = "/home/kevin/.config/qtile/kuro/resources/wifi"
 | 
					    wifi_theme_path = "/home/kevin/.config/qtile/kuro/resources/wifi"
 | 
				
			||||||
    wifi_update_interval = 5
 | 
					    wifi_update_interval = 5
 | 
				
			||||||
    wired_interface = "eth0"
 | 
					    wired_interface = "enp4s0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # GPU variables
 | 
					    # GPU variables
 | 
				
			||||||
    gpu_theme_path = "/home/kevin/.config/qtile/kuro/resources/gpu"
 | 
					    gpu_theme_path = "/home/kevin/.config/qtile/kuro/resources/gpu"
 | 
				
			||||||
| 
						 | 
					@ -214,7 +154,9 @@ class Config(BaseConfig):
 | 
				
			||||||
    volume_font = "Noto Sans"
 | 
					    volume_font = "Noto Sans"
 | 
				
			||||||
    volume_fontsize = 11
 | 
					    volume_fontsize = 11
 | 
				
			||||||
    volume_theme_path = "/home/kevin/.config/qtile/kuro/resources/volume"
 | 
					    volume_theme_path = "/home/kevin/.config/qtile/kuro/resources/volume"
 | 
				
			||||||
    volume_pulse_sinks = []
 | 
					    volume_pulse_sink = "alsa_output.usb-CSCTEK_USB_Audio_and_HID_A34004801402-00.analog-stereo"
 | 
				
			||||||
 | 
					    volume_pulse_sink2 = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    volume_is_bluetooth_icon = False
 | 
					    volume_is_bluetooth_icon = False
 | 
				
			||||||
    volume_update_interval = 0.2
 | 
					    volume_update_interval = 0.2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -251,18 +193,5 @@ class Config(BaseConfig):
 | 
				
			||||||
    # Show battery widget
 | 
					    # Show battery widget
 | 
				
			||||||
    show_battery_widget = False
 | 
					    show_battery_widget = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Show media widget
 | 
					 | 
				
			||||||
    show_media_widget = True
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Comma-separated list of ignored players in the media widget
 | 
					    # Comma-separated list of ignored players in the media widget
 | 
				
			||||||
    media_ignore_players = "kdeconnect"
 | 
					    media_ignore_players = "kdeconnect"
 | 
				
			||||||
 | 
					 | 
				
			||||||
    @classmethod
 | 
					 | 
				
			||||||
    def initialize(cls, qtile):
 | 
					 | 
				
			||||||
        # Can do extra initialization based on qtile instance here
 | 
					 | 
				
			||||||
        super(Config, cls).initialize(qtile=qtile)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # Replace some apps if launched in X11 mode
 | 
					 | 
				
			||||||
        if qtile.core.name == "x11":
 | 
					 | 
				
			||||||
            logger.warning("Launched in X11 mode, overriding some apps in Config to xorg-variants.")
 | 
					 | 
				
			||||||
            cls.app_launcher = cls.app_launcer_x11
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,45 +0,0 @@
 | 
				
			||||||
from kuro.config import Config as GeneralConfig
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Config(GeneralConfig):
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
    Kuro QTile configuration overrides for Aria
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
    config_name = "Aria"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Default Applications
 | 
					 | 
				
			||||||
    app_terminal = "terminator"
 | 
					 | 
				
			||||||
    app_launcher = "/home/kevin/bin/dmenu_wal.sh"
 | 
					 | 
				
			||||||
    cmd_brightness_up = "true"
 | 
					 | 
				
			||||||
    cmd_brightness_down = "true"
 | 
					 | 
				
			||||||
    cmd_screenshot = "xfce4-screenshooter -r -c -d 1"
 | 
					 | 
				
			||||||
    cmd_alt_screenshot = "xfce4-screenshooter -w -c -d 0"
 | 
					 | 
				
			||||||
    lock_command = "bash /home/kevin/bin/lock.sh"
 | 
					 | 
				
			||||||
    cliphistory_command = "true"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Autostart applications
 | 
					 | 
				
			||||||
    apps_autostart_group = [
 | 
					 | 
				
			||||||
        {'group': "", 'command': ["firefox"]},
 | 
					 | 
				
			||||||
        {'group': "", 'command': ["terminator"]},
 | 
					 | 
				
			||||||
        {'group': "", 'command': ["/usr/bin/rambox"]},
 | 
					 | 
				
			||||||
        {'group': "", 'command': ["thunar"]},
 | 
					 | 
				
			||||||
        {'group': "", 'command': ["thunderbird"]},
 | 
					 | 
				
			||||||
        {'group': "", 'command': ["spotify"]},
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Thermal indicator variables
 | 
					 | 
				
			||||||
    thermal_sensor = "Package id 0"
 | 
					 | 
				
			||||||
    thermal_chip = "coretemp-isa-0000"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Network variables
 | 
					 | 
				
			||||||
    wifi_interface = "wifi0"
 | 
					 | 
				
			||||||
    wired_interface = "enp7s0"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Volume widget variables
 | 
					 | 
				
			||||||
    volume_pulse_sinks = [
 | 
					 | 
				
			||||||
        "alsa_output.pci-0000_00_1f.3.analog-stereo",
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Screen organization
 | 
					 | 
				
			||||||
    laptop_screen_nvidia = "eDP-1-1"
 | 
					 | 
				
			||||||
    laptop_screen_intel = "eDP1"
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,22 +0,0 @@
 | 
				
			||||||
from kuro.config import Config as GeneralConfig
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Config(GeneralConfig):
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
    Kuro QTile configuration overrides for Meconopsis
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
    config_name = "Meconopsis"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Thermal indicator variables
 | 
					 | 
				
			||||||
    thermal_sensor = "Package id 0"
 | 
					 | 
				
			||||||
    thermal_chip = "coretemp-isa-0000"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Network variables
 | 
					 | 
				
			||||||
    wifi_interface = "wlp3s0"
 | 
					 | 
				
			||||||
    wired_interface = "enp4s0"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Volume widget variables
 | 
					 | 
				
			||||||
    volume_pulse_sinks = [
 | 
					 | 
				
			||||||
        # Analog jack
 | 
					 | 
				
			||||||
        "alsa_output.usb-CSCTEK_USB_Audio_and_HID_A34004801402-00.analog-stereo",
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,134 +0,0 @@
 | 
				
			||||||
from kuro.config import Config as GeneralConfig
 | 
					 | 
				
			||||||
import os
 | 
					 | 
				
			||||||
from libqtile.log_utils import logger
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Config(GeneralConfig):
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
    Kuro QTile configuration overrides for Work DBO laptop
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
    config_name = "DBO Power"
 | 
					 | 
				
			||||||
    homedir = "/home/albek00"
 | 
					 | 
				
			||||||
    #modifier = "mod1"  # Non-existing F13 key used by AutoHotKey script
 | 
					 | 
				
			||||||
    use_fake_screens = True
 | 
					 | 
				
			||||||
    fake_screen_count = 2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Default Applications
 | 
					 | 
				
			||||||
    app_terminal = "terminator"
 | 
					 | 
				
			||||||
    app_launcher = "/home/albek00/bin/dmenu_wal.sh"
 | 
					 | 
				
			||||||
    app_launcer_x11 = "/home/albek00/bin/dmenu_wal.sh"
 | 
					 | 
				
			||||||
    cmd_brightness_up = "true"
 | 
					 | 
				
			||||||
    cmd_brightness_down = "true"
 | 
					 | 
				
			||||||
    cmd_screenshot = "xfce4-screenshooter -r -c -d 1"
 | 
					 | 
				
			||||||
    cmd_alt_screenshot = "xfce4-screenshooter -w -c -d 0"
 | 
					 | 
				
			||||||
    lock_command = "true"
 | 
					 | 
				
			||||||
    cliphistory_command = "true"
 | 
					 | 
				
			||||||
    cmd_wal = ["wal", "-n", "-s", "-t", "-i"]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Screen configs (empty = autoconfig, otherwise list of Screen() kwarg dicts)
 | 
					 | 
				
			||||||
    screen_kwargs = [
 | 
					 | 
				
			||||||
        {'x': 0, 'y': 0, 'width': int(os.getenv("QTILE_WIDTH", "3840"))//2, 'height': int(os.getenv("QTILE_HEIGHT", "1080"))},
 | 
					 | 
				
			||||||
        {'x': int(os.getenv("QTILE_WIDTH", "3840"))//2, 'y': 0, 'width': int(os.getenv("QTILE_WIDTH", "3840"))//2, 'height': int(os.getenv("QTILE_HEIGHT", "1080"))},
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
    margin_layout = [8, 8, 2, 8]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Group definitions
 | 
					 | 
				
			||||||
    groups = [
 | 
					 | 
				
			||||||
        {'name': ''},
 | 
					 | 
				
			||||||
        {'name': ''},
 | 
					 | 
				
			||||||
        {'name': ''},
 | 
					 | 
				
			||||||
        {'name': ''},
 | 
					 | 
				
			||||||
        {'name': ''},
 | 
					 | 
				
			||||||
        {'name': ''},
 | 
					 | 
				
			||||||
        {'name': ''},
 | 
					 | 
				
			||||||
        {'name': ''},
 | 
					 | 
				
			||||||
        {'name': ''},
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Extra keybind definitions
 | 
					 | 
				
			||||||
    extra_keys = []
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Extra floating window rules
 | 
					 | 
				
			||||||
    extra_float_rules = []
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Autostart applications
 | 
					 | 
				
			||||||
    apps_autostart_group = [
 | 
					 | 
				
			||||||
        {'group': "", 'command': ["firefox"]},
 | 
					 | 
				
			||||||
        {'group': "", 'command': ["terminator"]},
 | 
					 | 
				
			||||||
        {'group': "", 'command': ["subl"]},
 | 
					 | 
				
			||||||
        {'group': "", 'command': ["smerge"]},
 | 
					 | 
				
			||||||
        {'group': "", 'command': ["thunar"]},
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Hide unnecessary widgets
 | 
					 | 
				
			||||||
    show_temperature = False
 | 
					 | 
				
			||||||
    show_media_widget = False
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Network variables
 | 
					 | 
				
			||||||
    wifi_interface = None
 | 
					 | 
				
			||||||
    wired_interface = "enP20755p0s0"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Volume widget variables
 | 
					 | 
				
			||||||
    volume_pulse_sinks = [
 | 
					 | 
				
			||||||
        "RDPSink",
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Override directories to proper homedir. Half of these are probably not even used but meh
 | 
					 | 
				
			||||||
    x11_wallpaper_config_command = "/home/albek00/bin/wal-nitrogen-noupdate"
 | 
					 | 
				
			||||||
    desktop_bg = "/home/albek00/Pictures/wallpapers/desktop.png"
 | 
					 | 
				
			||||||
    desktop_bg_folder = "/home/albek00/Pictures/wallpapers/desktop_rotation/day"
 | 
					 | 
				
			||||||
    desktop_bg_night_folder = "/home/albek00/Pictures/wallpapers/desktop_rotation/night"
 | 
					 | 
				
			||||||
    # desktop_bg_override = "/home/albek00/Pictures/safe_wallpaper.jpg"
 | 
					 | 
				
			||||||
    applauncher_image = "/home/albek00/.config/qtile/kuro/resources/arch.png"
 | 
					 | 
				
			||||||
    custom_layout_icon_paths = ['/home/albek00/.config/qtile/kuro/resources/layout_icons/']
 | 
					 | 
				
			||||||
    glava_color_file_path = "/home/albek00/.config/glava/kurobars_color.glsl"
 | 
					 | 
				
			||||||
    battery_theme_path = "/home/albek00/.config/qtile/kuro/resources/battery"
 | 
					 | 
				
			||||||
    wifi_theme_path = "/home/albek00/.config/qtile/kuro/resources/wifi"
 | 
					 | 
				
			||||||
    gpu_theme_path = "/home/albek00/.config/qtile/kuro/resources/gpu"
 | 
					 | 
				
			||||||
    volume_theme_path = "/home/albek00/.config/qtile/kuro/resources/volume"
 | 
					 | 
				
			||||||
    bluevol_theme_path = "/home/albek00/.config/qtile/kuro/resources/bluetooth_volume"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @classmethod
 | 
					 | 
				
			||||||
    def initialize(cls, qtile):
 | 
					 | 
				
			||||||
        super(Config, cls).initialize(qtile=qtile)
 | 
					 | 
				
			||||||
        # Add keyboard remapping to autostart apps
 | 
					 | 
				
			||||||
        cls.apps_autostart['common'].append(["xmodmap", "-e", "keycode 191 = Super_L"])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # Determine screens programatically
 | 
					 | 
				
			||||||
        qtile_width = int(os.getenv("QTILE_WIDTH", "3840"))
 | 
					 | 
				
			||||||
        qtile_height = int(os.getenv("QTILE_HEIGHT", "1080"))
 | 
					 | 
				
			||||||
        logger.warning(f"Determining screens for size {qtile_width}x{qtile_height}...")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # Home office, 1920x1080 horizontal right and 1080x1920 vertical left
 | 
					 | 
				
			||||||
        if qtile_width == 3000 and (qtile_height > 1912 and qtile_height <= 1920):
 | 
					 | 
				
			||||||
            cls.screen_kwargs = [
 | 
					 | 
				
			||||||
                {'x': 0, 'y': 839, 'width': 1920, 'height': qtile_height-839},
 | 
					 | 
				
			||||||
                {'x': 1920, 'y': 0, 'width': 1080, 'height': qtile_height},
 | 
					 | 
				
			||||||
            ]
 | 
					 | 
				
			||||||
        # Dual 1680x1050
 | 
					 | 
				
			||||||
        elif qtile_width == 3360 and (qtile_height > 1040 and qtile_height <= 1050):
 | 
					 | 
				
			||||||
            cls.screen_kwargs = [
 | 
					 | 
				
			||||||
                {'x': 0, 'y': 0, 'width': 1680, 'height': 1050},
 | 
					 | 
				
			||||||
                {'x': 1680, 'y': 0, 'width': 1680, 'height': 1050},
 | 
					 | 
				
			||||||
            ]
 | 
					 | 
				
			||||||
        # Dual 1920x1080
 | 
					 | 
				
			||||||
        elif qtile_width == 3840 and (qtile_height > 1070 and qtile_height <= 1080):
 | 
					 | 
				
			||||||
            cls.screen_kwargs = [
 | 
					 | 
				
			||||||
                {'x': 0, 'y': 0, 'width': 1920, 'height': 1080},
 | 
					 | 
				
			||||||
                {'x': 1920, 'y': 0, 'width': 1920, 'height': 1080},
 | 
					 | 
				
			||||||
            ]
 | 
					 | 
				
			||||||
        # Single 1920x1080
 | 
					 | 
				
			||||||
        elif qtile_width == 1920 and (qtile_height > 1070 and qtile_height <= 1080):
 | 
					 | 
				
			||||||
            cls.screen_kwargs = [{'x': 0, 'y': 0, 'width': 1920, 'height': 1080}]
 | 
					 | 
				
			||||||
            cls.fake_screen_count = 1
 | 
					 | 
				
			||||||
        # Single 1680x1050
 | 
					 | 
				
			||||||
        elif qtile_width == 1680 and (qtile_height > 1040 and qtile_height <= 1050):
 | 
					 | 
				
			||||||
            cls.screen_kwargs = [{'x': 0, 'y': 0, 'width': 1680, 'height': 1050}]
 | 
					 | 
				
			||||||
            cls.fake_screen_count = 1
 | 
					 | 
				
			||||||
        # Else, configure for 1 large screen
 | 
					 | 
				
			||||||
        else:
 | 
					 | 
				
			||||||
            cls.screen_kwargs = [{'x': 0, 'y': 0, 'width': qtile_width, 'height': qtile_height}]
 | 
					 | 
				
			||||||
            cls.fake_screen_count = 1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        logger.warning(f"Kwargs: {cls.screen_kwargs}")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,36 +0,0 @@
 | 
				
			||||||
from kuro.config import Config as GeneralConfig
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Config(GeneralConfig):
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
    Kuro QTile configuration overrides for Meconopsis
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
    config_name = "Temari"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Default Applications
 | 
					 | 
				
			||||||
    #app_terminal = "terminator"
 | 
					 | 
				
			||||||
    cmd_brightness_up = "brightnessctl -d intel_backlight set +5%"
 | 
					 | 
				
			||||||
    cmd_brightness_down = "brightnessctl -d intel_backlight set 5%-"
 | 
					 | 
				
			||||||
    network_config = "nm-connection-editor"
 | 
					 | 
				
			||||||
    #lock_command = "bash /home/kevin/bin/lock.sh"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Thermal indicator variables
 | 
					 | 
				
			||||||
    thermal_sensor = "Package id 0"
 | 
					 | 
				
			||||||
    thermal_chip = "coretemp-isa-0000"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Network variables
 | 
					 | 
				
			||||||
    wifi_interface = "wlp0s20f3"
 | 
					 | 
				
			||||||
    wired_interface = "enp7s0"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Volume widget variables
 | 
					 | 
				
			||||||
    volume_pulse_sinks = [
 | 
					 | 
				
			||||||
        # Analog jack
 | 
					 | 
				
			||||||
        "alsa_output.pci-0000_00_1f.3.analog-stereo",
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Screen organization
 | 
					 | 
				
			||||||
    laptop_screen_nvidia = "eDP-1-1"
 | 
					 | 
				
			||||||
    laptop_screen_intel = "eDP1"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Show battery widget
 | 
					 | 
				
			||||||
    show_battery_widget = True
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,26 +0,0 @@
 | 
				
			||||||
from kuro.config import Config as GeneralConfig
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Config(GeneralConfig):
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
    Kuro QTile configuration overrides for Violet
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
    config_name = "Violet"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Thermal indicator variables
 | 
					 | 
				
			||||||
    thermal_sensor = "Tdie"
 | 
					 | 
				
			||||||
    thermal_chip = "zenpower-pci-00c3"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Network variables
 | 
					 | 
				
			||||||
    wifi_interface = None
 | 
					 | 
				
			||||||
    wired_interface = "br1"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Volume widget variables
 | 
					 | 
				
			||||||
    volume_pulse_sinks = [
 | 
					 | 
				
			||||||
        # Behringer USB mixer
 | 
					 | 
				
			||||||
        "alsa_output.usb-Burr-Brown_from_TI_USB_Audio_CODEC-00.analog-stereo-output",
 | 
					 | 
				
			||||||
        # Motherboard output (Starship/Matisse)
 | 
					 | 
				
			||||||
        "alsa_output.pci-0000_0e_00.4.iec958-stereo",
 | 
					 | 
				
			||||||
        # PCIe card output (CMI8738/CMI8768 PCI Audio)
 | 
					 | 
				
			||||||
        "alsa_output.pci-0000_08_00.0.analog-stereo",
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
							
								
								
									
										313
									
								
								kuro/theme.py
									
										
									
									
									
								
							
							
						
						
									
										313
									
								
								kuro/theme.py
									
										
									
									
									
								
							| 
						 | 
					@ -1,8 +1,6 @@
 | 
				
			||||||
import json
 | 
					import json
 | 
				
			||||||
import os
 | 
					import os
 | 
				
			||||||
import random
 | 
					import random
 | 
				
			||||||
import time
 | 
					 | 
				
			||||||
import datetime
 | 
					 | 
				
			||||||
import socket
 | 
					import socket
 | 
				
			||||||
import subprocess
 | 
					import subprocess
 | 
				
			||||||
from typing import Optional
 | 
					from typing import Optional
 | 
				
			||||||
| 
						 | 
					@ -40,11 +38,14 @@ from kuro.utils import layouts as kuro_layouts
 | 
				
			||||||
 | 
					
 | 
				
			||||||
logger.warning("Importing configuration...")
 | 
					logger.warning("Importing configuration...")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from kuro.utils import load_config_class
 | 
					try:
 | 
				
			||||||
Config = load_config_class()
 | 
					    from kuro.config import Config
 | 
				
			||||||
if Config is None:
 | 
					except ImportError:
 | 
				
			||||||
    raise ImportError("Could not load theme Config or BaseConfig! Error: {}".format(e))
 | 
					    try:
 | 
				
			||||||
Config.initialize(qtile)
 | 
					        from kuro.baseconfig import BaseConfig as Config
 | 
				
			||||||
 | 
					    except ImportError:
 | 
				
			||||||
 | 
					        Config = None
 | 
				
			||||||
 | 
					        raise ImportError("Could not load theme Config or BaseConfig!")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
logger.warning("Imports done")
 | 
					logger.warning("Imports done")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -56,6 +57,9 @@ class Kuro(BaseTheme):
 | 
				
			||||||
    # Screen count
 | 
					    # Screen count
 | 
				
			||||||
    num_screens = 0
 | 
					    num_screens = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Top bars
 | 
				
			||||||
 | 
					    topbars = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Static windows
 | 
					    # Static windows
 | 
				
			||||||
    static_windows = []
 | 
					    static_windows = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -82,8 +86,14 @@ class Kuro(BaseTheme):
 | 
				
			||||||
            Match(wm_class='ssh-askpass'),  # ssh-askpass
 | 
					            Match(wm_class='ssh-askpass'),  # ssh-askpass
 | 
				
			||||||
            Match(title='branchdialog'),  # gitk
 | 
					            Match(title='branchdialog'),  # gitk
 | 
				
			||||||
            Match(title='pinentry'),  # GPG key password entry
 | 
					            Match(title='pinentry'),  # GPG key password entry
 | 
				
			||||||
            # Extra rules from host-specific Config
 | 
					            Match(title='origin.exe', wm_class='Wine'),  # Wine Origin game launcher
 | 
				
			||||||
            *[Match(**rule) for rule in Config.get('extra_float_rules', [])]
 | 
					
 | 
				
			||||||
 | 
					            # Homebank popups
 | 
				
			||||||
 | 
					            Match(title='Add transaction', wm_class='homebank'),
 | 
				
			||||||
 | 
					            Match(title='Edit transaction', wm_class='homebank'),
 | 
				
			||||||
 | 
					            Match(title='Inherit transaction', wm_class='homebank'),
 | 
				
			||||||
 | 
					            Match(title='Multiple edit transactions', wm_class='homebank'),
 | 
				
			||||||
 | 
					            Match(title='Transaction splits', wm_class='homebank'),
 | 
				
			||||||
        ]
 | 
					        ]
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -100,7 +110,7 @@ class Kuro(BaseTheme):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def init_keys(self):
 | 
					    def init_keys(self):
 | 
				
			||||||
        logger.warning("Initializing keys")
 | 
					        logger.warning("Initializing keys")
 | 
				
			||||||
        keys = [
 | 
					        return [
 | 
				
			||||||
            # Switch between windows in current stack pane
 | 
					            # Switch between windows in current stack pane
 | 
				
			||||||
            Key([self.mod], "k", lazy.layout.down()),
 | 
					            Key([self.mod], "k", lazy.layout.down()),
 | 
				
			||||||
            Key([self.mod], "j", lazy.layout.up()),
 | 
					            Key([self.mod], "j", lazy.layout.up()),
 | 
				
			||||||
| 
						 | 
					@ -145,6 +155,17 @@ class Kuro(BaseTheme):
 | 
				
			||||||
            # Lock shortcut
 | 
					            # Lock shortcut
 | 
				
			||||||
            Key([self.mod], "l", lazy.spawn(Config.get('lock_command', "i3lock"))),
 | 
					            Key([self.mod], "l", lazy.spawn(Config.get('lock_command', "i3lock"))),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            # Display modes
 | 
				
			||||||
 | 
					            Key([self.mod], "Prior", lazy.spawn(Config.get('cmd_monitor_mode_3s144', 'true'))),
 | 
				
			||||||
 | 
					            Key([self.mod], "Next", lazy.spawn(Config.get('cmd_monitor_mode_3s60', 'true'))),
 | 
				
			||||||
 | 
					            Key([self.mod], "Home", lazy.spawn(Config.get('cmd_monitor_mode_day', 'true'))),
 | 
				
			||||||
 | 
					            Key([self.mod], "End", lazy.spawn(Config.get('cmd_monitor_mode_night', 'true'))),
 | 
				
			||||||
 | 
					            Key([self.mod], "Insert", lazy.spawn(Config.get('cmd_monitor_mode_alt', 'true'))),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            # Backlight keys
 | 
				
			||||||
 | 
					            Key([], "XF86MonBrightnessUp", lazy.spawn(Config.get('cmd_brightness_up', 'xbacklight -inc 10'))),
 | 
				
			||||||
 | 
					            Key([], "XF86MonBrightnessDown", lazy.spawn(Config.get('cmd_brightness_down', 'xbacklight -dec 10'))),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # Media keys
 | 
					            # Media keys
 | 
				
			||||||
            Key([], "XF86AudioPlay", lazy.spawn(Config.get('cmd_media_play', 'true'))),
 | 
					            Key([], "XF86AudioPlay", lazy.spawn(Config.get('cmd_media_play', 'true'))),
 | 
				
			||||||
            Key([], "XF86AudioNext", lazy.spawn(Config.get('cmd_media_next', 'true'))),
 | 
					            Key([], "XF86AudioNext", lazy.spawn(Config.get('cmd_media_next', 'true'))),
 | 
				
			||||||
| 
						 | 
					@ -201,32 +222,27 @@ class Kuro(BaseTheme):
 | 
				
			||||||
            # Spawn a popup, and despawn it after 3 seconds
 | 
					            # Spawn a popup, and despawn it after 3 seconds
 | 
				
			||||||
            Key([self.mod, "control"], "p", lazy.function(test_popups)),
 | 
					            Key([self.mod, "control"], "p", lazy.function(test_popups)),
 | 
				
			||||||
        ]
 | 
					        ]
 | 
				
			||||||
        # Extra keybinds from host-specific Config
 | 
					 | 
				
			||||||
        keys.extend([
 | 
					 | 
				
			||||||
            Key([(self.mod if m == 'mod' else m) for m in key['modifiers']], key['key'], key['action'])
 | 
					 | 
				
			||||||
            for key in Config.get('extra_keys', [])
 | 
					 | 
				
			||||||
        ])
 | 
					 | 
				
			||||||
        return keys
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def init_groups(self):
 | 
					    def init_groups(self):
 | 
				
			||||||
        logger.warning("Initializing groups")
 | 
					        logger.warning("Initializing groups")
 | 
				
			||||||
        # http://fontawesome.io/cheatsheet
 | 
					        # http://fontawesome.io/cheatsheet
 | 
				
			||||||
        groups = []
 | 
					        groups = [
 | 
				
			||||||
 | 
					            Group(""),
 | 
				
			||||||
        for group in Config.get('groups', [{'name': '1'}]):
 | 
					            Group(""),
 | 
				
			||||||
            if 'layout' in group:
 | 
					            Group(""),
 | 
				
			||||||
                if group['layout'] == "floating":
 | 
					            Group(""),
 | 
				
			||||||
                    groups.append(Group(
 | 
					            Group(""),
 | 
				
			||||||
                        group['name'],
 | 
					            Group(""),
 | 
				
			||||||
                        layout="floating",
 | 
					            Group(""),
 | 
				
			||||||
                        layouts=[
 | 
					            Group(""),
 | 
				
			||||||
                            layout.Floating(**group.get('options', {}))
 | 
					            Group(""),
 | 
				
			||||||
                        ]
 | 
					            Group("", layout='floating', layouts=[
 | 
				
			||||||
                    ))
 | 
					                layout.Floating(
 | 
				
			||||||
                else:
 | 
					                    border_focus="#990000",
 | 
				
			||||||
                    logger.warning(f"Unknown group layout for group '{group['name']}': {group['layout']}")
 | 
					                    border_normal="#440000"
 | 
				
			||||||
            else:
 | 
					                )
 | 
				
			||||||
                groups.append(Group(group['name']))
 | 
					            ])
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
        return groups
 | 
					        return groups
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def init_layouts(self):
 | 
					    def init_layouts(self):
 | 
				
			||||||
| 
						 | 
					@ -276,8 +292,8 @@ class Kuro(BaseTheme):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def initialize_colorscheme(self):
 | 
					    def initialize_colorscheme(self):
 | 
				
			||||||
        colors = None
 | 
					        colors = None
 | 
				
			||||||
        if os.path.isfile(f"{Config.get('homedir', '~')}/.cache/wal/colors.json"):
 | 
					        if os.path.isfile("/home/kevin/.cache/wal/colors.json"):
 | 
				
			||||||
            with open(f"{Config.get('homedir', '~')}/.cache/wal/colors.json", 'r') as f:
 | 
					            with open("/home/kevin/.cache/wal/colors.json", 'r') as f:
 | 
				
			||||||
                try:
 | 
					                try:
 | 
				
			||||||
                    colors = json.load(f)['colors']
 | 
					                    colors = json.load(f)['colors']
 | 
				
			||||||
                except KeyError:
 | 
					                except KeyError:
 | 
				
			||||||
| 
						 | 
					@ -293,34 +309,25 @@ class Kuro(BaseTheme):
 | 
				
			||||||
            Config.bar_background = colors['color1']
 | 
					            Config.bar_background = colors['color1']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def reinit_screens(self):
 | 
					    def reinit_screens(self):
 | 
				
			||||||
        if Config.get("use_fake_screens", False):
 | 
					        # Re-initalize bars
 | 
				
			||||||
            logger.warning(f"Using fake screens!")
 | 
					        self.topbars.clear()
 | 
				
			||||||
            self.num_screens = Config.get("fake_screen_count", 1)
 | 
					
 | 
				
			||||||
        else:
 | 
					        if qtile.core.name == "x11":
 | 
				
			||||||
            self.num_screens = max(1, utils.get_screen_count())
 | 
					            self.num_screens = max(1, utils.get_screen_count())
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            self.num_screens = max(1, len(qtile.core.get_screen_info()))
 | 
				
			||||||
        logger.warning(f"Detected {self.num_screens} screens.")
 | 
					        logger.warning(f"Detected {self.num_screens} screens.")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        screen_kwargs = Config.get("screen_kwargs", [])
 | 
					        screens = []
 | 
				
			||||||
 | 
					 | 
				
			||||||
        for x in range(self.num_screens):
 | 
					        for x in range(self.num_screens):
 | 
				
			||||||
            logger.warning(f"Reconfiguring bars for screen {x}")
 | 
					            logger.warning("Initializing bars for screen {}".format(x))
 | 
				
			||||||
 | 
					            topbar = self.build_bar_for_screen(x)
 | 
				
			||||||
 | 
					            self.topbars.append(topbar)
 | 
				
			||||||
 | 
					            screens.append(Screen(top=topbar))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            try:
 | 
					        self.screens.clear()
 | 
				
			||||||
                screen = self.screens[x]
 | 
					        for s in screens:
 | 
				
			||||||
            except IndexError:
 | 
					            self.screens.append(s)
 | 
				
			||||||
                try:
 | 
					 | 
				
			||||||
                    kwargs = screen_kwargs[x]
 | 
					 | 
				
			||||||
                    logger.warning(f"Config for screen {x}: {kwargs}")
 | 
					 | 
				
			||||||
                except IndexError:
 | 
					 | 
				
			||||||
                    logger.warning(f"No kwarg config for screen {x}")
 | 
					 | 
				
			||||||
                    kwargs = {}
 | 
					 | 
				
			||||||
                screen = Screen(**kwargs)
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            if screen.top is None:
 | 
					 | 
				
			||||||
                screen.top = self.build_bar_for_screen(x)
 | 
					 | 
				
			||||||
            topbar = screen.top
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            self.screens.append(screen)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def update_keys(self):
 | 
					    def update_keys(self):
 | 
				
			||||||
        logger.warning("Updating keys")
 | 
					        logger.warning("Updating keys")
 | 
				
			||||||
| 
						 | 
					@ -395,61 +402,60 @@ class Kuro(BaseTheme):
 | 
				
			||||||
        ]
 | 
					        ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Media widget(s)
 | 
					        # Media widget(s)
 | 
				
			||||||
        if Config.get('show_media_widget', False):
 | 
					        widgets.extend([
 | 
				
			||||||
            widgets.extend([
 | 
					            # An MPRIS widget that shows the media play status as an icon.
 | 
				
			||||||
                # An MPRIS widget that shows the media play status as an icon.
 | 
					            widget.Mpris2(
 | 
				
			||||||
                widget.Mpris2(
 | 
					                font=Config.get('font_groupbox', 'Arial'),
 | 
				
			||||||
                    font=Config.get('font_groupbox', 'Arial'),
 | 
					                fontsize=Config.get('fontsize_groupbox', 15),
 | 
				
			||||||
                    fontsize=Config.get('fontsize_groupbox', 15),
 | 
					                format="",
 | 
				
			||||||
                    format="",
 | 
					                scroll=False,
 | 
				
			||||||
                    scroll=False,
 | 
					                playing_text="",
 | 
				
			||||||
                    playing_text="",
 | 
					                paused_text="",
 | 
				
			||||||
                    paused_text="",
 | 
					                stopped_text="",
 | 
				
			||||||
                    stopped_text="",
 | 
					                no_metadata_text="",
 | 
				
			||||||
                    no_metadata_text="",
 | 
					                name=f"media_icon{screen_num}",
 | 
				
			||||||
                    name=f"media_icon{screen_num}",
 | 
					                mouse_callbacks={
 | 
				
			||||||
                    mouse_callbacks={
 | 
					                    "Button1": lazy.widget[f"media_icon{screen_num}"].play_pause(),
 | 
				
			||||||
                        "Button1": lazy.widget[f"media_icon{screen_num}"].play_pause(),
 | 
					                    "Button3": lazy.widget[f"media_icon{screen_num}"].next(),
 | 
				
			||||||
                        "Button3": lazy.widget[f"media_icon{screen_num}"].next(),
 | 
					                    "Button4": lambda: None,
 | 
				
			||||||
                        "Button4": lambda: None,
 | 
					                    "Button5": lambda: None,
 | 
				
			||||||
                        "Button5": lambda: None,
 | 
					                }
 | 
				
			||||||
                    }
 | 
					            ),
 | 
				
			||||||
                ),
 | 
					            # An MPRIS widget that shows the currently playing song information in a nice format.
 | 
				
			||||||
                # An MPRIS widget that shows the currently playing song information in a nice format.
 | 
					            widget.Mpris2(
 | 
				
			||||||
                widget.Mpris2(
 | 
					                font=Config.get('font_topbar', 'Arial'),
 | 
				
			||||||
                    font=Config.get('font_topbar', 'Arial'),
 | 
					                fontsize=Config.get('fontsize_topbar', 15),
 | 
				
			||||||
                    fontsize=Config.get('fontsize_topbar', 15),
 | 
					                format="<b>{xesam:title}</b> - {xesam:artist} - <i>{xesam:album}</i>",
 | 
				
			||||||
                    format="<b>{xesam:title}</b> - {xesam:artist} - <i>{xesam:album}</i>",
 | 
					                scroll=True,
 | 
				
			||||||
                    scroll=True,
 | 
					                width=300,  # Maximum width before widget starts scrolling
 | 
				
			||||||
                    width=300,  # Maximum width before widget starts scrolling
 | 
					                playing_text="{track}",
 | 
				
			||||||
                    playing_text="{track}",
 | 
					                paused_text="{track}",
 | 
				
			||||||
                    paused_text="{track}",
 | 
					                stopped_text="",
 | 
				
			||||||
                    stopped_text="",
 | 
					                no_metadata_text="No metadata available",
 | 
				
			||||||
                    no_metadata_text="No metadata available",
 | 
					                name=f"media_text{screen_num}",
 | 
				
			||||||
                    name=f"media_text{screen_num}",
 | 
					                mouse_callbacks={
 | 
				
			||||||
                    mouse_callbacks={
 | 
					                    "Button1": lazy.widget[f"media_icon{screen_num}"].play_pause(),
 | 
				
			||||||
                        "Button1": lazy.widget[f"media_icon{screen_num}"].play_pause(),
 | 
					                    "Button3": lazy.widget[f"media_icon{screen_num}"].next(),
 | 
				
			||||||
                        "Button3": lazy.widget[f"media_icon{screen_num}"].next(),
 | 
					                    "Button4": lambda: None,
 | 
				
			||||||
                        "Button4": lambda: None,
 | 
					                    "Button5": lambda: None,
 | 
				
			||||||
                        "Button5": lambda: None,
 | 
					                }
 | 
				
			||||||
                    }
 | 
					            ),
 | 
				
			||||||
                ),
 | 
					            # An MPRIS widget masquerading as a text widget, that only shows "|" when media is playing or paused.
 | 
				
			||||||
                # An MPRIS widget masquerading as a text widget, that only shows "|" when media is playing or paused.
 | 
					            widget.Mpris2(
 | 
				
			||||||
                widget.Mpris2(
 | 
					                fontsize=14,
 | 
				
			||||||
                    fontsize=14,
 | 
					                format="",
 | 
				
			||||||
                    format="",
 | 
					                scroll=False,
 | 
				
			||||||
                    scroll=False,
 | 
					                playing_text="|",
 | 
				
			||||||
                    playing_text="|",
 | 
					                paused_text="|",
 | 
				
			||||||
                    paused_text="|",
 | 
					                stopped_text="",
 | 
				
			||||||
                    stopped_text="",
 | 
					                no_metadata_text="",
 | 
				
			||||||
                    no_metadata_text="",
 | 
					                mouse_callbacks={
 | 
				
			||||||
                    mouse_callbacks={
 | 
					                    "Button1": lambda: None,
 | 
				
			||||||
                        "Button1": lambda: None,
 | 
					                    "Button4": lambda: None,
 | 
				
			||||||
                        "Button4": lambda: None,
 | 
					                    "Button5": lambda: None,
 | 
				
			||||||
                        "Button5": lambda: None,
 | 
					                }
 | 
				
			||||||
                    }
 | 
					            )
 | 
				
			||||||
                )
 | 
					        ])
 | 
				
			||||||
            ])
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Sensor widgets
 | 
					        # Sensor widgets
 | 
				
			||||||
        sensor_widgets = []
 | 
					        sensor_widgets = []
 | 
				
			||||||
| 
						 | 
					@ -493,10 +499,19 @@ class Kuro(BaseTheme):
 | 
				
			||||||
            ])
 | 
					            ])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Volume widget(s)
 | 
					        # Volume widget(s)
 | 
				
			||||||
        for sink_name in Config.get('volume_pulse_sinks', []):
 | 
					        widgets.append(
 | 
				
			||||||
 | 
					            kuro.utils.widgets.VolumeInfoWidget(
 | 
				
			||||||
 | 
					                pulse_sink=Config.get('volume_pulse_sink', None),
 | 
				
			||||||
 | 
					                fontsize_left=18,
 | 
				
			||||||
 | 
					                fontsize_right=11,
 | 
				
			||||||
 | 
					                font_left=Config.get('font_groupbox', None),
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        # Violet has multiple volume widgets
 | 
				
			||||||
 | 
					        if socket.gethostname() in ["Violet"]:
 | 
				
			||||||
            widgets.append(
 | 
					            widgets.append(
 | 
				
			||||||
                kuro.utils.widgets.VolumeInfoWidget(
 | 
					                kuro.utils.widgets.VolumeInfoWidget(
 | 
				
			||||||
                    pulse_sink=sink_name,
 | 
					                    pulse_sink=Config.get('volume_pulse_sink2', None),
 | 
				
			||||||
                    fontsize_left=18,
 | 
					                    fontsize_left=18,
 | 
				
			||||||
                    fontsize_right=11,
 | 
					                    fontsize_right=11,
 | 
				
			||||||
                    font_left=Config.get('font_groupbox', None),
 | 
					                    font_left=Config.get('font_groupbox', None),
 | 
				
			||||||
| 
						 | 
					@ -509,8 +524,7 @@ class Kuro(BaseTheme):
 | 
				
			||||||
            kuro.utils.widgets.NetworkInfoWidget(
 | 
					            kuro.utils.widgets.NetworkInfoWidget(
 | 
				
			||||||
                fontsize_left=16, fontsize_right=14,
 | 
					                fontsize_left=16, fontsize_right=14,
 | 
				
			||||||
                wireless_interface=Config.get('wifi_interface', None),
 | 
					                wireless_interface=Config.get('wifi_interface', None),
 | 
				
			||||||
                wired_interface=Config.get('wired_interface', None),
 | 
					                wired_interface=Config.get('wired_interface', None)
 | 
				
			||||||
                config_application=Config.get('network_config', None),
 | 
					 | 
				
			||||||
            ),
 | 
					            ),
 | 
				
			||||||
        ])
 | 
					        ])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -535,7 +549,7 @@ class Kuro(BaseTheme):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Layout switcher, clock and Screen ID
 | 
					        # Layout switcher, clock and Screen ID
 | 
				
			||||||
        widgets.extend([
 | 
					        widgets.extend([
 | 
				
			||||||
            widget.CurrentLayout(mode="icon", custom_icon_paths=Config.get('custom_layout_icon_paths', [])),
 | 
					            widget.CurrentLayoutIcon(custom_icon_paths=Config.get('custom_layout_icon_paths', [])),
 | 
				
			||||||
            widget.Clock(format="%a %d %b ", **self.widget_defaults),
 | 
					            widget.Clock(format="%a %d %b ", **self.widget_defaults),
 | 
				
			||||||
            widget.Clock(
 | 
					            widget.Clock(
 | 
				
			||||||
                format="<b>%H</b>:%M",
 | 
					                format="<b>%H</b>:%M",
 | 
				
			||||||
| 
						 | 
					@ -580,13 +594,12 @@ class Kuro(BaseTheme):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        logger.warning("Restoring wallpaper...")
 | 
					        logger.warning("Restoring wallpaper...")
 | 
				
			||||||
        if self.current_wallpaper:
 | 
					        if self.current_wallpaper:
 | 
				
			||||||
            p = utils.execute_once([*Config.get('cmd_wal', ['wallust', 'run']), "{}".format(self.current_wallpaper)])
 | 
					            p = utils.execute_once(["wallust", "run", "{}".format(self.current_wallpaper)])
 | 
				
			||||||
            if p:
 | 
					            p.wait()
 | 
				
			||||||
                p.wait()
 | 
					 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            wallpaper = None
 | 
					            wallpaper = None
 | 
				
			||||||
            if os.path.isfile(f"{Config.get('homedir', '~')}/.cache/wal/colors.json"):
 | 
					            if os.path.isfile("/home/kevin/.cache/wal/colors.json"):
 | 
				
			||||||
                with open(f"{Config.get('homedir', '~')}/.cache/wal/colors.json", 'r') as f:
 | 
					                with open("/home/kevin/.cache/wal/colors.json", 'r') as f:
 | 
				
			||||||
                    try:
 | 
					                    try:
 | 
				
			||||||
                        wallpaper = json.load(f)['wallpaper']
 | 
					                        wallpaper = json.load(f)['wallpaper']
 | 
				
			||||||
                    except KeyError:
 | 
					                    except KeyError:
 | 
				
			||||||
| 
						 | 
					@ -598,6 +611,7 @@ class Kuro(BaseTheme):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Update color scheme
 | 
					        # Update color scheme
 | 
				
			||||||
        self.update_colorscheme()
 | 
					        self.update_colorscheme()
 | 
				
			||||||
 | 
					        self.startup_completed = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def callback_startup_complete(self, *args, **kwargs):
 | 
					    def callback_startup_complete(self, *args, **kwargs):
 | 
				
			||||||
        logger.warning("Callback Startup Complete")
 | 
					        logger.warning("Callback Startup Complete")
 | 
				
			||||||
| 
						 | 
					@ -608,20 +622,14 @@ class Kuro(BaseTheme):
 | 
				
			||||||
        # Update color scheme
 | 
					        # Update color scheme
 | 
				
			||||||
        self.update_colorscheme()
 | 
					        self.update_colorscheme()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Setup XDG Desktop Portal on Wayland
 | 
					        # Setup XDG Desktop Portal
 | 
				
			||||||
        if qtile.core.name == "wayland":
 | 
					        self.setup_xdg_desktop_portal()
 | 
				
			||||||
            self.setup_xdg_desktop_portal()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # After first startup is complete, autostart configured apps
 | 
					        # After first startup is complete, autostart configured apps
 | 
				
			||||||
        logger.warning("Autostarting apps...")
 | 
					        logger.warning("Autostarting apps...")
 | 
				
			||||||
        for category in Config.get("apps_autostart", {}).keys():
 | 
					        for app in Config.get("apps_autostart", []):
 | 
				
			||||||
            if qtile.core.name == category or category == "common":
 | 
					            logger.warning(f"Starting '{app}'...")
 | 
				
			||||||
                logger.warning(f"Autostarting apps for {category}...")
 | 
					            utils.execute_once(app)
 | 
				
			||||||
                for app in Config.get("apps_autostart", {}).get(category, []):
 | 
					 | 
				
			||||||
                    logger.warning(f"Starting '{app}'...")
 | 
					 | 
				
			||||||
                    utils.execute_once(app)
 | 
					 | 
				
			||||||
            else:
 | 
					 | 
				
			||||||
                logger.warning(f"Skipping autostart apps for {category}, because core is {qtile.core.name}...")
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for app in Config.get("apps_autostart_group", []):
 | 
					        for app in Config.get("apps_autostart_group", []):
 | 
				
			||||||
            if all(x in app.keys() for x in ["group", "command"]):
 | 
					            if all(x in app.keys() for x in ["group", "command"]):
 | 
				
			||||||
| 
						 | 
					@ -631,14 +639,10 @@ class Kuro(BaseTheme):
 | 
				
			||||||
                logger.warning(f"Invalid app in 'apps_autostart_group', "
 | 
					                logger.warning(f"Invalid app in 'apps_autostart_group', "
 | 
				
			||||||
                               f"must have 'group' and 'command' keys: {app}...")
 | 
					                               f"must have 'group' and 'command' keys: {app}...")
 | 
				
			||||||
        logger.warning("Autostart complete")
 | 
					        logger.warning("Autostart complete")
 | 
				
			||||||
        cur_time = time.time()
 | 
					 | 
				
			||||||
        logger.warning(f"QTile startup completed! Started up in {(cur_time - self.startup_time):.1f} seconds!")
 | 
					 | 
				
			||||||
        self.startup_completed = True
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def callback_client_managed(self, *args, **kwargs):
 | 
					    def callback_client_managed(self, *args, **kwargs):
 | 
				
			||||||
        client: Optional[Window] = args[0] if len(args) > 0 else None
 | 
					        client: Optional[Window] = args[0] if len(args) > 0 else None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # TODO: Move get_pid to an utility function
 | 
					 | 
				
			||||||
        w_pid = None
 | 
					        w_pid = None
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            w_pid = client.get_pid()
 | 
					            w_pid = client.get_pid()
 | 
				
			||||||
| 
						 | 
					@ -667,14 +671,9 @@ class Kuro(BaseTheme):
 | 
				
			||||||
            del client.is_static_window
 | 
					            del client.is_static_window
 | 
				
			||||||
            self.static_windows.remove(client)
 | 
					            self.static_windows.remove(client)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def callback_screen_change(self, *args, **kwargs):
 | 
					    def callback_screens_reconfigured(self, *args, **kwargs):
 | 
				
			||||||
        logger.warning(f"Screen configuration changed, reinitializing screens")
 | 
					        logger.warning(f"Re-configuring screens!")
 | 
				
			||||||
        self.reinit_screens()
 | 
					        self.reinit_screens()
 | 
				
			||||||
        qtile.reconfigure_screens()
 | 
					 | 
				
			||||||
        #qtile.reconfigure_screens()  # Twice, see: https://github.com/qtile/qtile/issues/4673#issuecomment-2196459114
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #def callback_screens_reconfigured(self, *args, **kwargs):
 | 
					 | 
				
			||||||
        logger.warning(f"Screens were reconfgured, updating wallpapers and color scheme")
 | 
					 | 
				
			||||||
        self.set_wallpaper(self.current_wallpaper)
 | 
					        self.set_wallpaper(self.current_wallpaper)
 | 
				
			||||||
        self.update_colorscheme()
 | 
					        self.update_colorscheme()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -713,14 +712,6 @@ class Kuro(BaseTheme):
 | 
				
			||||||
    def set_random_wallpaper(self, *args, **kwargs):
 | 
					    def set_random_wallpaper(self, *args, **kwargs):
 | 
				
			||||||
        wallpapers = []
 | 
					        wallpapers = []
 | 
				
			||||||
        wallpaper_dir = Config.get("desktop_bg_folder", "")
 | 
					        wallpaper_dir = Config.get("desktop_bg_folder", "")
 | 
				
			||||||
 | 
					 | 
				
			||||||
        # Use a wallpaper from the night folder after 9PM and before 6AM
 | 
					 | 
				
			||||||
        wallpaper_night_dir = Config.get("desktop_bg_night_folder", "")
 | 
					 | 
				
			||||||
        if wallpaper_night_dir and os.path.isdir(wallpaper_night_dir):
 | 
					 | 
				
			||||||
            cur_time = datetime.datetime.now()
 | 
					 | 
				
			||||||
            if cur_time.hour > 21 or cur_time.hour < 6:
 | 
					 | 
				
			||||||
                wallpaper_dir = wallpaper_night_dir
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            wallpapers = [x for x in os.listdir(wallpaper_dir) if ".vertical." not in x]
 | 
					            wallpapers = [x for x in os.listdir(wallpaper_dir) if ".vertical." not in x]
 | 
				
			||||||
        except os.error as e:
 | 
					        except os.error as e:
 | 
				
			||||||
| 
						 | 
					@ -731,16 +722,14 @@ class Kuro(BaseTheme):
 | 
				
			||||||
                wallpaper_file = Config.get("desktop_bg_override", "")
 | 
					                wallpaper_file = Config.get("desktop_bg_override", "")
 | 
				
			||||||
            else:
 | 
					            else:
 | 
				
			||||||
                wallpaper_file = os.path.join(wallpaper_dir, random.choice(wallpapers))
 | 
					                wallpaper_file = os.path.join(wallpaper_dir, random.choice(wallpapers))
 | 
				
			||||||
                logger.warning(f"Selected new wallpaper: {wallpaper_file}")
 | 
					 | 
				
			||||||
            self.set_wallpaper(wallpaper_file)
 | 
					            self.set_wallpaper(wallpaper_file)
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            logger.warning("Random wallpaper requested but no wallpapers are available.")
 | 
					            logger.warning("Random wallpaper requested but no wallpapers are available.")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def set_wallpaper(self, filename):
 | 
					    def set_wallpaper(self, filename):
 | 
				
			||||||
        if qtile.core.name == "x11":
 | 
					        if qtile.core.name == "x11":
 | 
				
			||||||
            p = utils.execute_once(f"{Config.get('x11_wallpaper_config_command', 'wal-nitrogen-noupdate')} {filename}")
 | 
					            p = utils.execute_once(f"{Config.get('wallpaper_config_command', 'wal-nitrogen-noupdate')} {filename}")
 | 
				
			||||||
            if p:
 | 
					            p.wait()
 | 
				
			||||||
                p.wait()
 | 
					 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            # Wayland can set wallpaper in qtile directly per screen
 | 
					            # Wayland can set wallpaper in qtile directly per screen
 | 
				
			||||||
            for screen_i, screen in enumerate(qtile.screens):
 | 
					            for screen_i, screen in enumerate(qtile.screens):
 | 
				
			||||||
| 
						 | 
					@ -759,13 +748,12 @@ class Kuro(BaseTheme):
 | 
				
			||||||
    def update_colorscheme(self, *args, **kwargs):
 | 
					    def update_colorscheme(self, *args, **kwargs):
 | 
				
			||||||
        if self.current_wallpaper:
 | 
					        if self.current_wallpaper:
 | 
				
			||||||
            logger.warning(f"Updating wal colors for wallpaper {self.current_wallpaper}")
 | 
					            logger.warning(f"Updating wal colors for wallpaper {self.current_wallpaper}")
 | 
				
			||||||
            p = utils.execute_once([*Config.get('cmd_wal', ['wallust', 'run']), "{}".format(self.current_wallpaper)])
 | 
					            p = utils.execute_once(["wallust", "run", "{}".format(self.current_wallpaper)])
 | 
				
			||||||
            if p:
 | 
					            p.wait()
 | 
				
			||||||
                p.wait()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        colors = None
 | 
					        colors = None
 | 
				
			||||||
        if os.path.isfile(f"{Config.get('homedir', '~')}/.cache/wal/colors.json"):
 | 
					        if os.path.isfile("/home/kevin/.cache/wal/colors.json"):
 | 
				
			||||||
            with open(f"{Config.get('homedir', '~')}/.cache/wal/colors.json", 'r') as f:
 | 
					            with open("/home/kevin/.cache/wal/colors.json", 'r') as f:
 | 
				
			||||||
                try:
 | 
					                try:
 | 
				
			||||||
                    colors = json.load(f)['colors']
 | 
					                    colors = json.load(f)['colors']
 | 
				
			||||||
                except KeyError:
 | 
					                except KeyError:
 | 
				
			||||||
| 
						 | 
					@ -851,8 +839,7 @@ class Kuro(BaseTheme):
 | 
				
			||||||
            try:
 | 
					            try:
 | 
				
			||||||
                logger.warning(f"Calling 'pywalfox update'...")
 | 
					                logger.warning(f"Calling 'pywalfox update'...")
 | 
				
			||||||
                p = utils.execute(["pywalfox", "update"])
 | 
					                p = utils.execute(["pywalfox", "update"])
 | 
				
			||||||
                if p:
 | 
					                p.wait()
 | 
				
			||||||
                    p.wait()
 | 
					 | 
				
			||||||
            except subprocess.SubprocessError as e:
 | 
					            except subprocess.SubprocessError as e:
 | 
				
			||||||
                logger.error(f"Error running 'pywalfox update': {e}")
 | 
					                logger.error(f"Error running 'pywalfox update': {e}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,31 +0,0 @@
 | 
				
			||||||
import importlib
 | 
					 | 
				
			||||||
import socket
 | 
					 | 
				
			||||||
import traceback
 | 
					 | 
				
			||||||
from libqtile.log_utils import logger
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def load_config_class():
 | 
					 | 
				
			||||||
    # Try to import host-specific configuration first
 | 
					 | 
				
			||||||
    hostname = socket.gethostname().lower()
 | 
					 | 
				
			||||||
    if hostname:
 | 
					 | 
				
			||||||
        try:
 | 
					 | 
				
			||||||
            host_module = importlib.import_module(f"kuro.config.{hostname}")
 | 
					 | 
				
			||||||
            return getattr(host_module, "Config")
 | 
					 | 
				
			||||||
        except ImportError:
 | 
					 | 
				
			||||||
            pass
 | 
					 | 
				
			||||||
    logger.warning(f"No host-specific configuration available for {hostname}. Loading general config...")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # If no config yet, load general Kuro Config object
 | 
					 | 
				
			||||||
    try:
 | 
					 | 
				
			||||||
        conf_module = importlib.import_module("kuro.config")
 | 
					 | 
				
			||||||
        return getattr(conf_module, "Config")
 | 
					 | 
				
			||||||
    except ImportError as e:
 | 
					 | 
				
			||||||
        logger.error(traceback.format_exc())
 | 
					 | 
				
			||||||
    logger.error("Could not load Kuro Config. Trying to load BaseConfig. Error: {}".format(e))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # If no config yet, load fallback BaseConfig
 | 
					 | 
				
			||||||
    try:
 | 
					 | 
				
			||||||
        base_module = importlib.import_module("kuro.base")
 | 
					 | 
				
			||||||
        return getattr(base_module, "BaseConfig")
 | 
					 | 
				
			||||||
    except ImportError as e:
 | 
					 | 
				
			||||||
        logger.error(traceback.format_exc())
 | 
					 | 
				
			||||||
    return None
 | 
					 | 
				
			||||||
| 
						 | 
					@ -65,7 +65,7 @@ def start_in_group(theme, qtile, group: str, command: List[str], floating: bool
 | 
				
			||||||
        theme.autostart_app_rules[proc.pid] = rule_id
 | 
					        theme.autostart_app_rules[proc.pid] = rule_id
 | 
				
			||||||
        return proc
 | 
					        return proc
 | 
				
			||||||
    except FileNotFoundError as e:
 | 
					    except FileNotFoundError as e:
 | 
				
			||||||
        logger.error(f"Could not execute {command}, FileNotFoundError - {e}")
 | 
					        logger.error(f"Could not execute {process}, FileNotFoundError - {e}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def start_in_group_once(theme, qtile, group: str, command: List[str], floating: bool = False,
 | 
					def start_in_group_once(theme, qtile, group: str, command: List[str], floating: bool = False,
 | 
				
			||||||
| 
						 | 
					@ -90,12 +90,17 @@ def get_screen_count():
 | 
				
			||||||
            logger.info("Using xrandr to detect screen count")
 | 
					            logger.info("Using xrandr to detect screen count")
 | 
				
			||||||
            output = subprocess.check_output("xrandr -q".split()).decode('utf-8')
 | 
					            output = subprocess.check_output("xrandr -q".split()).decode('utf-8')
 | 
				
			||||||
            output = [x for x in output.split("\n") if " connected" in x]
 | 
					            output = [x for x in output.split("\n") if " connected" in x]
 | 
				
			||||||
            return max(1, len(output))
 | 
					 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            return max(1, len(qtile.core.get_screen_info()))
 | 
					            logger.info("Using lsmon (wallutils) to detect screen count")
 | 
				
			||||||
 | 
					            output = subprocess.check_output(["lsmon"]).decode('utf-8')
 | 
				
			||||||
 | 
					            output = output.split("\n")
 | 
				
			||||||
    except subprocess.CalledProcessError:
 | 
					    except subprocess.CalledProcessError:
 | 
				
			||||||
        pass
 | 
					        return 1
 | 
				
			||||||
    return 1
 | 
					
 | 
				
			||||||
 | 
					    if output:
 | 
				
			||||||
 | 
					        return len(output)
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        return 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def bar_separator(config):
 | 
					def bar_separator(config):
 | 
				
			||||||
| 
						 | 
					@ -105,17 +110,17 @@ def bar_separator(config):
 | 
				
			||||||
                      )
 | 
					                      )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def init_notify(qtile):
 | 
					def init_notify(qtile):
 | 
				
			||||||
    #if qtile and qtile.theme_instance and qtile.theme_instance.startup_completed:
 | 
					    if qtile and qtile.theme_instance and qtile.theme_instance.startup_completed:
 | 
				
			||||||
    try:
 | 
					        try:
 | 
				
			||||||
        if not notify2.is_initted():
 | 
					            if not notify2.is_initted():
 | 
				
			||||||
            logger.warning("Initializing Notify2")
 | 
					                logger.warning("Initializing Notify2")
 | 
				
			||||||
            notify2.init("QTileWM")
 | 
					                notify2.init("QTileWM")
 | 
				
			||||||
    except DBusException:
 | 
					        except DBusException:
 | 
				
			||||||
        logger.error(f"Failed to initialize Notify2 (DBus error), retrying later.")
 | 
					            logger.error(f"Failed to initialize Notify2 (DBus error), retrying later.")
 | 
				
			||||||
    except Exception:
 | 
					        except Exception:
 | 
				
			||||||
        logger.error(f"Failed to initialize Notify2 (Generic error), retrying later.")
 | 
					            logger.error(f"Failed to initialize Notify2 (Generic error), retrying later.")
 | 
				
			||||||
    #else:
 | 
					    else:
 | 
				
			||||||
    #    logger.warning(f"Not initializing Notify2 yet, QTile startup not completed.")
 | 
					        logger.warning(f"Not initializing Notify2 yet, QTile startup not completed.")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def notify(qtile, title, content, urgency=URGENCY_NORMAL, timeout=5000, image=None):
 | 
					def notify(qtile, title, content, urgency=URGENCY_NORMAL, timeout=5000, image=None):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -17,7 +17,7 @@ from libqtile.widget.groupbox import GroupBox
 | 
				
			||||||
from libqtile.command.base import expose_command
 | 
					from libqtile.command.base import expose_command
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from kuro.utils.general import notify, BUTTON_LEFT, BUTTON_MIDDLE, BUTTON_RIGHT, BUTTON_DOWN, BUTTON_UP, BUTTON_MUTE, \
 | 
					from kuro.utils.general import notify, BUTTON_LEFT, BUTTON_MIDDLE, BUTTON_RIGHT, BUTTON_DOWN, BUTTON_UP, BUTTON_MUTE, \
 | 
				
			||||||
    call_process, execute
 | 
					    call_process
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class DualPaneTextboxBase(base._Widget):
 | 
					class DualPaneTextboxBase(base._Widget):
 | 
				
			||||||
| 
						 | 
					@ -201,18 +201,18 @@ class DualPaneTextboxBase(base._Widget):
 | 
				
			||||||
            self.changed = False
 | 
					            self.changed = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @expose_command()
 | 
					    @expose_command()
 | 
				
			||||||
    def set_font(self, font=None, fontsize_left=None, fontsize_right=None, fontshadow=None):
 | 
					    def set_font(self, font=None, fontsize_left=0, fontsize_right=0, fontshadow=""):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
            Change the font used by this widget. If font is None, the current
 | 
					            Change the font used by this widget. If font is None, the current
 | 
				
			||||||
            font is used.
 | 
					            font is used.
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        if font is not None:
 | 
					        if font is not None:
 | 
				
			||||||
            self.font = font
 | 
					            self.font = font
 | 
				
			||||||
        if fontsize_left is not None:
 | 
					        if fontsize_left != 0:
 | 
				
			||||||
            self.fontsize_left = fontsize_left
 | 
					            self.fontsize_left = fontsize_left
 | 
				
			||||||
        if fontsize_right is not None:
 | 
					        if fontsize_right != 0:
 | 
				
			||||||
            self.fontsize_right = fontsize_right
 | 
					            self.fontsize_right = fontsize_right
 | 
				
			||||||
        if fontshadow is not None:
 | 
					        if fontshadow != "":
 | 
				
			||||||
            self.fontshadow = fontshadow
 | 
					            self.fontshadow = fontshadow
 | 
				
			||||||
        self.bar.draw()
 | 
					        self.bar.draw()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -621,7 +621,6 @@ class NetworkInfoWidget(DualPaneTextboxBase):
 | 
				
			||||||
        ('critical_color', "#ffffff", "Color when value is critical"),
 | 
					        ('critical_color', "#ffffff", "Color when value is critical"),
 | 
				
			||||||
        ('wireless_interface', "wifi0", "Wireless interface device name"),
 | 
					        ('wireless_interface', "wifi0", "Wireless interface device name"),
 | 
				
			||||||
        ('wired_interface', "enp7s0", "Wired interface device name"),
 | 
					        ('wired_interface', "enp7s0", "Wired interface device name"),
 | 
				
			||||||
        ('config_application', None, "Application to launch when right/middle clicking"),
 | 
					 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, **config):
 | 
					    def __init__(self, **config):
 | 
				
			||||||
| 
						 | 
					@ -650,70 +649,62 @@ class NetworkInfoWidget(DualPaneTextboxBase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _update_values(self):
 | 
					    def _update_values(self):
 | 
				
			||||||
        # Wifi
 | 
					        # Wifi
 | 
				
			||||||
        if self.wireless_interface:
 | 
					        try:
 | 
				
			||||||
            try:
 | 
					            essid, quality = get_status(self.wireless_interface)
 | 
				
			||||||
                essid, quality = get_status(self.wireless_interface)
 | 
					            status = iwlib.get_iwconfig(self.wireless_interface)
 | 
				
			||||||
                status = iwlib.get_iwconfig(self.wireless_interface)
 | 
					            self.wireless_ips = netifaces.ifaddresses(self.wireless_interface)
 | 
				
			||||||
                self.wireless_ips = netifaces.ifaddresses(self.wireless_interface)
 | 
					            disconnected = essid is None
 | 
				
			||||||
                disconnected = essid is None
 | 
					            percent = math.ceil(((quality or 0) / 70) * 100)
 | 
				
			||||||
                percent = math.ceil(((quality or 0) / 70) * 100)
 | 
					            self.wireless_quality = quality
 | 
				
			||||||
                self.wireless_quality = quality
 | 
					            self.wireless_signal = percent
 | 
				
			||||||
                self.wireless_signal = percent
 | 
					            self.wireless_name = essid
 | 
				
			||||||
                self.wireless_name = essid
 | 
					            self.wireless_connected = not disconnected
 | 
				
			||||||
                self.wireless_connected = not disconnected
 | 
					            self.wireless_accesspoint = status.get('Access Point', b'Unknown').decode()
 | 
				
			||||||
                self.wireless_accesspoint = status.get('Access Point', b'Unknown').decode()
 | 
					            self.wireless_frequency = status.get('Frequency', b'Unknown').decode()
 | 
				
			||||||
                self.wireless_frequency = status.get('Frequency', b'Unknown').decode()
 | 
					            self.wireless_ipv4 = self.wireless_ips.get(netifaces.AF_INET, [{'addr': ""}])[0]['addr']
 | 
				
			||||||
                self.wireless_ipv4 = self.wireless_ips.get(netifaces.AF_INET, [{'addr': ""}])[0]['addr']
 | 
					            self.wireless_ipv6 = self.wireless_ips.get(netifaces.AF_INET6, [{'addr': ""}])[0]['addr']
 | 
				
			||||||
                self.wireless_ipv6 = self.wireless_ips.get(netifaces.AF_INET6, [{'addr': ""}])[0]['addr']
 | 
					            self.wireless_mac = self.wireless_ips.get(netifaces.AF_LINK, [{'addr': ""}])[0]['addr']
 | 
				
			||||||
                self.wireless_mac = self.wireless_ips.get(netifaces.AF_LINK, [{'addr': ""}])[0]['addr']
 | 
					        except EnvironmentError:
 | 
				
			||||||
            except EnvironmentError:
 | 
					            pass
 | 
				
			||||||
                pass
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Wired
 | 
					        # Wired
 | 
				
			||||||
        if self.wired_interface:
 | 
					        try:
 | 
				
			||||||
 | 
					            self.wired_ips = netifaces.ifaddresses(self.wired_interface)
 | 
				
			||||||
 | 
					            self.wired_ipv4 = self.wired_ips.get(netifaces.AF_INET, [{'addr': ""}])[0]['addr']
 | 
				
			||||||
 | 
					            self.wired_ipv6 = self.wired_ips.get(netifaces.AF_INET6, [{'addr': ""}])[0]['addr']
 | 
				
			||||||
 | 
					            self.wired_mac = self.wired_ips.get(netifaces.AF_LINK, [{'addr': ""}])[0]['addr']
 | 
				
			||||||
 | 
					            command = ["ip", "link", "show", "{}".format(self.wired_interface)]
 | 
				
			||||||
            try:
 | 
					            try:
 | 
				
			||||||
                self.wired_ips = netifaces.ifaddresses(self.wired_interface)
 | 
					                eth_status = call_process(command)
 | 
				
			||||||
                self.wired_ipv4 = self.wired_ips.get(netifaces.AF_INET, [{'addr': ""}])[0]['addr']
 | 
					            except subprocess.CalledProcessError as e:
 | 
				
			||||||
                self.wired_ipv6 = self.wired_ips.get(netifaces.AF_INET6, [{'addr': ""}])[0]['addr']
 | 
					                logger.error(f"Error while calling {command} - {e}")
 | 
				
			||||||
                self.wired_mac = self.wired_ips.get(netifaces.AF_LINK, [{'addr': ""}])[0]['addr']
 | 
					                return
 | 
				
			||||||
                command = ["ip", "link", "show", "{}".format(self.wired_interface)]
 | 
					            m = self.wired_up_regex.search(eth_status)
 | 
				
			||||||
                try:
 | 
					            if m:
 | 
				
			||||||
                    eth_status = call_process(command)
 | 
					                 self.wired_connected = "UP" in m.group(1)
 | 
				
			||||||
                except subprocess.CalledProcessError as e:
 | 
					            else:
 | 
				
			||||||
                    logger.error(f"Error while calling {command} - {e}")
 | 
					                self.wired_connected = False
 | 
				
			||||||
                    return
 | 
					 | 
				
			||||||
                m = self.wired_up_regex.search(eth_status)
 | 
					 | 
				
			||||||
                if m:
 | 
					 | 
				
			||||||
                     self.wired_connected = "UP" in m.group(1)
 | 
					 | 
				
			||||||
                else:
 | 
					 | 
				
			||||||
                    self.wired_connected = False
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            except (EnvironmentError, ValueError):
 | 
					        except (EnvironmentError, ValueError):
 | 
				
			||||||
                pass
 | 
					            pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def update(self):
 | 
					    def update(self):
 | 
				
			||||||
        self._update_values()
 | 
					        self._update_values()
 | 
				
			||||||
        self.draw()
 | 
					        self.draw()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def draw(self):
 | 
					    def draw(self):
 | 
				
			||||||
        if self.wireless_interface:
 | 
					        if self.wireless_connected:
 | 
				
			||||||
            if self.wireless_connected:
 | 
					            strength = ""
 | 
				
			||||||
                strength = ""
 | 
					            if self.wireless_signal < 66:
 | 
				
			||||||
                if self.wireless_signal < 66:
 | 
					                strength = ""
 | 
				
			||||||
                    strength = ""
 | 
					            if self.wireless_signal < 33:
 | 
				
			||||||
                if self.wireless_signal < 33:
 | 
					                strength = ""
 | 
				
			||||||
                    strength = ""
 | 
					            self.text_left = strength
 | 
				
			||||||
                self.text_left = strength
 | 
					 | 
				
			||||||
            else:
 | 
					 | 
				
			||||||
                self.text_left = ""
 | 
					 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            self.text_left = ""
 | 
					            self.text_left = ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if self.wired_interface:
 | 
					        if self.wired_connected:
 | 
				
			||||||
            if self.wired_connected:
 | 
					            self.text_right = ""
 | 
				
			||||||
                self.text_right = ""
 | 
					 | 
				
			||||||
            else:
 | 
					 | 
				
			||||||
                self.text_right = ""
 | 
					 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            self.text_right = ""
 | 
					            self.text_right = ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -748,9 +739,6 @@ class NetworkInfoWidget(DualPaneTextboxBase):
 | 
				
			||||||
                notify(None, title, "{}\n\n{}".format(wifi_text, wired_text))
 | 
					                notify(None, title, "{}\n\n{}".format(wifi_text, wired_text))
 | 
				
			||||||
            else:
 | 
					            else:
 | 
				
			||||||
                notify(None, title, "\n{}".format(wired_text))
 | 
					                notify(None, title, "\n{}".format(wired_text))
 | 
				
			||||||
        if button == BUTTON_RIGHT or button == BUTTON_MIDDLE:
 | 
					 | 
				
			||||||
            if self.config_application:
 | 
					 | 
				
			||||||
                execute(self.config_application)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class BatteryInfoWidget(DualPaneTextboxBase):
 | 
					class BatteryInfoWidget(DualPaneTextboxBase):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,34 +4,9 @@ notification-daemon
 | 
				
			||||||
otf-font-awesome
 | 
					otf-font-awesome
 | 
				
			||||||
python-osc
 | 
					python-osc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
qtile-extras
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# /optional/
 | 
					# /optional/
 | 
				
			||||||
playerctl
 | 
					playerctl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
xfce4-screenshooter
 | 
					xfce4-screenshooter
 | 
				
			||||||
xfce4-clipman-plugin
 | 
					xfce4-clipman-plugin
 | 
				
			||||||
wireless_tools
 | 
					wireless_tools
 | 
				
			||||||
 | 
					 | 
				
			||||||
# Utilities
 | 
					 | 
				
			||||||
kdeconnect      # KDE Connect
 | 
					 | 
				
			||||||
vorta           # Backup scheduler
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Xorg-only
 | 
					 | 
				
			||||||
picom           # Compositor
 | 
					 | 
				
			||||||
xfce4-clipman   # Clipboard manager
 | 
					 | 
				
			||||||
dunst           # Notification daemon
 | 
					 | 
				
			||||||
xiccd           # Color profile manager
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Wayland-only
 | 
					 | 
				
			||||||
xorg-xwayland
 | 
					 | 
				
			||||||
python-pywlroots
 | 
					 | 
				
			||||||
wofi                # dmenu replacement
 | 
					 | 
				
			||||||
grim                # Screenshot utility
 | 
					 | 
				
			||||||
swappy              # Screenshot editor
 | 
					 | 
				
			||||||
slurp               # Region selector
 | 
					 | 
				
			||||||
cliphist            # Clipboard history
 | 
					 | 
				
			||||||
mako                # Notifications daemon
 | 
					 | 
				
			||||||
kanshi              # Display hotplugging
 | 
					 | 
				
			||||||
wallutils           # Display/wallpaper utilities (lsmon)
 | 
					 | 
				
			||||||
papirus-icon-theme  # Icon theme
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue