Base theme, built on a class-based model. 9 workspaces based on function, basic system tray with cpu monitor, battery monitor and update indicator. Built-in multi-monitor support.
							
								
								
									
										1
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							
							
						
						| 
						 | 
					@ -139,3 +139,4 @@ ENV/
 | 
				
			||||||
# Rope project settings
 | 
					# Rope project settings
 | 
				
			||||||
.ropeproject
 | 
					.ropeproject
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.idea
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										94
									
								
								config.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,94 @@
 | 
				
			||||||
 | 
					# Copyright (c) 2010 Aldo Cortesi
 | 
				
			||||||
 | 
					# Copyright (c) 2010, 2014 dequis
 | 
				
			||||||
 | 
					# Copyright (c) 2012 Randall Ma
 | 
				
			||||||
 | 
					# Copyright (c) 2012-2014 Tycho Andersen
 | 
				
			||||||
 | 
					# Copyright (c) 2012 Craig Barnes
 | 
				
			||||||
 | 
					# Copyright (c) 2013 horsik
 | 
				
			||||||
 | 
					# Copyright (c) 2013 Tao Sauvage
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
				
			||||||
 | 
					# of this software and associated documentation files (the "Software"), to deal
 | 
				
			||||||
 | 
					# in the Software without restriction, including without limitation the rights
 | 
				
			||||||
 | 
					# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
				
			||||||
 | 
					# copies of the Software, and to permit persons to whom the Software is
 | 
				
			||||||
 | 
					# furnished to do so, subject to the following conditions:
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# The above copyright notice and this permission notice shall be included in
 | 
				
			||||||
 | 
					# all copies or substantial portions of the Software.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
				
			||||||
 | 
					# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
				
			||||||
 | 
					# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
				
			||||||
 | 
					# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
				
			||||||
 | 
					# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
				
			||||||
 | 
					# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
				
			||||||
 | 
					# SOFTWARE.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Import Theme
 | 
				
			||||||
 | 
					from libqtile import hook
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					try:
 | 
				
			||||||
 | 
					    from kuro.theme import Kuro
 | 
				
			||||||
 | 
					    Theme = Kuro()
 | 
				
			||||||
 | 
					except ImportError:
 | 
				
			||||||
 | 
					    from kuro.base import BaseTheme
 | 
				
			||||||
 | 
					    Kuro = None
 | 
				
			||||||
 | 
					    Theme = BaseTheme()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Import theme configuration
 | 
				
			||||||
 | 
					try:
 | 
				
			||||||
 | 
					    from kuro.config import Config
 | 
				
			||||||
 | 
					except ImportError:
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        from kuro.baseconfig import BaseConfig as Config
 | 
				
			||||||
 | 
					    except ImportError:
 | 
				
			||||||
 | 
					        Config = None
 | 
				
			||||||
 | 
					        raise ImportError("Could not load theme Config or BaseConfig!")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Initialize the Theme
 | 
				
			||||||
 | 
					Theme.initialize()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Hook theme into all hooks we know of
 | 
				
			||||||
 | 
					hook.subscribe.startup_once(Theme.callback_startup_once)
 | 
				
			||||||
 | 
					hook.subscribe.startup(Theme.callback_startup)
 | 
				
			||||||
 | 
					hook.subscribe.startup_complete(Theme.callback_startup_complete)
 | 
				
			||||||
 | 
					hook.subscribe.setgroup(Theme.callback_setgroup)
 | 
				
			||||||
 | 
					hook.subscribe.addgroup(Theme.callback_addgroup)
 | 
				
			||||||
 | 
					hook.subscribe.delgroup(Theme.callback_delgroup)
 | 
				
			||||||
 | 
					hook.subscribe.changegroup(Theme.callback_changegroup)
 | 
				
			||||||
 | 
					hook.subscribe.focus_change(Theme.callback_focus_change)
 | 
				
			||||||
 | 
					hook.subscribe.float_change(Theme.callback_float_change)
 | 
				
			||||||
 | 
					hook.subscribe.group_window_add(Theme.callback_group_window_add)
 | 
				
			||||||
 | 
					hook.subscribe.window_name_change(Theme.callback_window_name_change)
 | 
				
			||||||
 | 
					hook.subscribe.client_new(Theme.callback_client_new)
 | 
				
			||||||
 | 
					hook.subscribe.client_managed(Theme.callback_client_managed)
 | 
				
			||||||
 | 
					hook.subscribe.client_killed(Theme.callback_client_killed)
 | 
				
			||||||
 | 
					hook.subscribe.client_state_changed(Theme.callback_client_state_changed)
 | 
				
			||||||
 | 
					hook.subscribe.client_type_changed(Theme.callback_client_type_changed)
 | 
				
			||||||
 | 
					hook.subscribe.client_focus(Theme.callback_client_focus)
 | 
				
			||||||
 | 
					hook.subscribe.client_mouse_enter(Theme.callback_client_mouse_enter)
 | 
				
			||||||
 | 
					hook.subscribe.client_name_updated(Theme.callback_client_name_updated)
 | 
				
			||||||
 | 
					hook.subscribe.client_urgent_hint_changed(Theme.callback_client_urgent_hint_changed)
 | 
				
			||||||
 | 
					hook.subscribe.layout_change(Theme.callback_layout_change)
 | 
				
			||||||
 | 
					hook.subscribe.net_wm_icon_change(Theme.callback_net_wm_icon_change)
 | 
				
			||||||
 | 
					hook.subscribe.selection_notify(Theme.callback_selection_notify)
 | 
				
			||||||
 | 
					hook.subscribe.selection_change(Theme.callback_selection_change)
 | 
				
			||||||
 | 
					hook.subscribe.screen_change(Theme.callback_screen_change)
 | 
				
			||||||
 | 
					hook.subscribe.current_screen_change(Theme.callback_current_screen_change)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Initialize variables from theme
 | 
				
			||||||
 | 
					keys = Theme.keys
 | 
				
			||||||
 | 
					groups = Theme.groups
 | 
				
			||||||
 | 
					layouts = Theme.layouts
 | 
				
			||||||
 | 
					widget_defaults = Theme.widget_defaults
 | 
				
			||||||
 | 
					screens = Theme.screens
 | 
				
			||||||
 | 
					dgroups_key_binder = Theme.dgroups_key_binder
 | 
				
			||||||
 | 
					dgroups_app_rules = Theme.dgroups_app_rules
 | 
				
			||||||
 | 
					main = Theme.main
 | 
				
			||||||
 | 
					follow_mouse_focus = Theme.follow_mouse_focus
 | 
				
			||||||
 | 
					bring_front_click = Theme.bring_front_click
 | 
				
			||||||
 | 
					cursor_warp = Theme.cursor_warp
 | 
				
			||||||
 | 
					floating_layout = Theme.floating_layout
 | 
				
			||||||
 | 
					auto_fullscreen = Theme.auto_fullscreen
 | 
				
			||||||
 | 
					focus_on_window_activation = Theme.focus_on_window_activation
 | 
				
			||||||
 | 
					extentions = Theme.extensions
 | 
				
			||||||
							
								
								
									
										145
									
								
								kuro/base.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,145 @@
 | 
				
			||||||
 | 
					from libqtile import layout as libqtile_layout
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class BaseConfig:
 | 
				
			||||||
 | 
					    @classmethod
 | 
				
			||||||
 | 
					    def get(cls, key, default):
 | 
				
			||||||
 | 
					        if hasattr(cls, key):
 | 
				
			||||||
 | 
					            return cls.__dict__[key]
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            return default
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class BaseTheme:
 | 
				
			||||||
 | 
					    # Changing variables initialized by function
 | 
				
			||||||
 | 
					    keys = None
 | 
				
			||||||
 | 
					    groups = None
 | 
				
			||||||
 | 
					    layouts = None
 | 
				
			||||||
 | 
					    widget_defaults = None
 | 
				
			||||||
 | 
					    screens = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # 'Static' variables
 | 
				
			||||||
 | 
					    dgroups_key_binder = None
 | 
				
			||||||
 | 
					    dgroups_app_rules = []
 | 
				
			||||||
 | 
					    main = None
 | 
				
			||||||
 | 
					    follow_mouse_focus = True
 | 
				
			||||||
 | 
					    bring_front_click = False
 | 
				
			||||||
 | 
					    cursor_warp = False
 | 
				
			||||||
 | 
					    floating_layout = libqtile_layout.Floating()
 | 
				
			||||||
 | 
					    auto_fullscreen = True
 | 
				
			||||||
 | 
					    focus_on_window_activation = "smart"
 | 
				
			||||||
 | 
					    extensions = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # 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
 | 
				
			||||||
 | 
					    # mailing lists, github issues, and other WM documentation that suggest setting
 | 
				
			||||||
 | 
					    # this string if your java app doesn't work correctly. We may as well just lie
 | 
				
			||||||
 | 
					    # and say that we're a working one by default.
 | 
				
			||||||
 | 
					    #
 | 
				
			||||||
 | 
					    # We choose LG3D to maximize irony: it is a 3D non-reparenting WM written in
 | 
				
			||||||
 | 
					    # java that happens to be on java's whitelist.
 | 
				
			||||||
 | 
					    wmname = "LG3D"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def initialize(self):
 | 
				
			||||||
 | 
					        self.widget_defaults = self.init_widget_defaults()
 | 
				
			||||||
 | 
					        self.keys = self.init_keys()
 | 
				
			||||||
 | 
					        self.groups = self.init_groups()
 | 
				
			||||||
 | 
					        self.layouts = self.init_layouts()
 | 
				
			||||||
 | 
					        self.screens = self.init_screens()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def init_keys(self):
 | 
				
			||||||
 | 
					        return []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def init_groups(self):
 | 
				
			||||||
 | 
					        return []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def init_layouts(self):
 | 
				
			||||||
 | 
					        return []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def init_widget_defaults(self):
 | 
				
			||||||
 | 
					        return {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def init_screens(self):
 | 
				
			||||||
 | 
					        return []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def init_mouse(self):
 | 
				
			||||||
 | 
					        return []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Callbacks
 | 
				
			||||||
 | 
					    def callback_startup_once(self, *args, **kwargs):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def callback_startup(self, *args, **kwargs):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def callback_startup_complete(self, *args, **kwargs):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def callback_setgroup(self, *args, **kwargs):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def callback_addgroup(self, *args, **kwargs):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def callback_delgroup(self, *args, **kwargs):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def callback_changegroup(self, *args, **kwargs):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def callback_focus_change(self, *args, **kwargs):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def callback_float_change(self, *args, **kwargs):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def callback_group_window_add(self, *args, **kwargs):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def callback_window_name_change(self, *args, **kwargs):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def callback_client_new(self, *args, **kwargs):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def callback_client_managed(self, *args, **kwargs):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def callback_client_killed(self, *args, **kwargs):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def callback_client_state_changed(self, *args, **kwargs):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def callback_client_type_changed(self, *args, **kwargs):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def callback_client_focus(self, *args, **kwargs):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def callback_client_mouse_enter(self, *args, **kwargs):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def callback_client_name_updated(self, *args, **kwargs):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def callback_client_urgent_hint_changed(self, *args, **kwargs):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def callback_layout_change(self, *args, **kwargs):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def callback_net_wm_icon_change(self, *args, **kwargs):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def callback_selection_notify(self, *args, **kwargs):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def callback_selection_change(self, *args, **kwargs):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def callback_screen_change(self, *args, **kwargs):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def callback_current_screen_change(self, *args, **kwargs):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
							
								
								
									
										58
									
								
								kuro/config.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,58 @@
 | 
				
			||||||
 | 
					from kuro.base import BaseConfig
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Config variables used in the main configuration
 | 
				
			||||||
 | 
					class Config(BaseConfig):
 | 
				
			||||||
 | 
					    # Show debug messages
 | 
				
			||||||
 | 
					    debug = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Default Applications
 | 
				
			||||||
 | 
					    app_terminal = "terminator"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Images
 | 
				
			||||||
 | 
					    desktop_bg = "/home/kevin/Pictures/wallpapers/desktop.png"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Fonts
 | 
				
			||||||
 | 
					    font_default = "Noto Sans"
 | 
				
			||||||
 | 
					    font_topbar = "Noto Sans"
 | 
				
			||||||
 | 
					    font_clock = "Noto Sans"
 | 
				
			||||||
 | 
					    font_titlebar = "Noto Sans"
 | 
				
			||||||
 | 
					    font_groupbox = "FontAwesome"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Font sizes
 | 
				
			||||||
 | 
					    fontsize_default = 11
 | 
				
			||||||
 | 
					    fontsize_topbar = 11
 | 
				
			||||||
 | 
					    fontsize_clock = 11
 | 
				
			||||||
 | 
					    fontsize_titlebar = 11
 | 
				
			||||||
 | 
					    fontsize_groupbox = 15
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Sizes
 | 
				
			||||||
 | 
					    width_border = 1
 | 
				
			||||||
 | 
					    margin_layout = 4
 | 
				
			||||||
 | 
					    width_groupbox_border = 1
 | 
				
			||||||
 | 
					    height_groupbox = 24
 | 
				
			||||||
 | 
					    margin_groupbox = 0
 | 
				
			||||||
 | 
					    width_spacer = 1
 | 
				
			||||||
 | 
					    padding_spacer = 4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Variables
 | 
				
			||||||
 | 
					    bool_groupbox_disable_drag = True
 | 
				
			||||||
 | 
					    bool_groupbox_rounded_borders = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Colours
 | 
				
			||||||
 | 
					    colour_border_normal = "#333333"
 | 
				
			||||||
 | 
					    colour_border_focus = "#ffffff"
 | 
				
			||||||
 | 
					    colour_groupbox_border_normal = "#333333"
 | 
				
			||||||
 | 
					    colour_groupbox_border_focus = "#aaaaaa"
 | 
				
			||||||
 | 
					    colour_groupbox_icon_active = "#ffffff"
 | 
				
			||||||
 | 
					    colour_groupbox_icon_inactive = "#777777"
 | 
				
			||||||
 | 
					    colour_spacer_background = "#777777"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Battery variables
 | 
				
			||||||
 | 
					    battery_theme_path = "/home/kevin/.config/qtile/kuro/resources/battery"
 | 
				
			||||||
 | 
					    battery_update_delay = 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # CheckUpdates variables
 | 
				
			||||||
 | 
					    updates_display_format = "{updates}"
 | 
				
			||||||
 | 
					    updates_execute_command = "terminator -e 'echo Updating\ via\ yaourt\ -Sayu...; yaourt -Sayu'"
 | 
				
			||||||
 | 
					    updates_colour_available = '#f4d742'
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								kuro/resources/battery/battery-caution-charging.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 2 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								kuro/resources/battery/battery-caution.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.4 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								kuro/resources/battery/battery-full-charged.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 2 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								kuro/resources/battery/battery-full-charging.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 2 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								kuro/resources/battery/battery-full.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.4 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								kuro/resources/battery/battery-good-charging.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 2.1 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								kuro/resources/battery/battery-good.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.3 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								kuro/resources/battery/battery-low-charging.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 2 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								kuro/resources/battery/battery-low.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.4 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								kuro/resources/battery/battery-missing.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 2.2 KiB  | 
							
								
								
									
										201
									
								
								kuro/theme.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,201 @@
 | 
				
			||||||
 | 
					import logging
 | 
				
			||||||
 | 
					import os
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from libqtile.config import Key, Screen, Group, Drag, Click
 | 
				
			||||||
 | 
					from libqtile.command import lazy
 | 
				
			||||||
 | 
					from libqtile import layout, bar, widget
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Import theme util functions
 | 
				
			||||||
 | 
					from kuro import utils
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Import variables
 | 
				
			||||||
 | 
					from kuro.base import BaseTheme
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					try:
 | 
				
			||||||
 | 
					    from kuro.config import Config
 | 
				
			||||||
 | 
					except ImportError:
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        from kuro.baseconfig import BaseConfig as Config
 | 
				
			||||||
 | 
					    except ImportError:
 | 
				
			||||||
 | 
					        Config = None
 | 
				
			||||||
 | 
					        raise ImportError("Could not load theme Config or BaseConfig!")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Initialize logging
 | 
				
			||||||
 | 
					log = logging.getLogger(__name__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Kuro(BaseTheme):
 | 
				
			||||||
 | 
					    # Shorthand for modifier key
 | 
				
			||||||
 | 
					    mod = Config.get("modifier", "mod4")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Show debug messages
 | 
				
			||||||
 | 
					    debug = Config.get('debug', False)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def initialize(self):
 | 
				
			||||||
 | 
					        log.debug("Initializing Kuro Theme...")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        super(Kuro, self).initialize()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Update keys with keys for groups
 | 
				
			||||||
 | 
					        self.update_keys()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def init_keys(self):
 | 
				
			||||||
 | 
					        log.debug("Initializing keys")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return [
 | 
				
			||||||
 | 
					            # Switch between windows in current stack pane
 | 
				
			||||||
 | 
					            Key([self.mod], "k", lazy.layout.down()),
 | 
				
			||||||
 | 
					            Key([self.mod], "j", lazy.layout.up()),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            # Move windows up or down in current stack
 | 
				
			||||||
 | 
					            Key([self.mod, "control"], "k", lazy.layout.shuffle_down()),
 | 
				
			||||||
 | 
					            Key([self.mod, "control"], "j", lazy.layout.shuffle_up()),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            # Switch window focus to other pane(s) of stack
 | 
				
			||||||
 | 
					            Key([self.mod], "space", lazy.layout.next()),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            # Swap panes of split stack
 | 
				
			||||||
 | 
					            Key([self.mod, "shift"], "space", lazy.layout.rotate()),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            # Toggle between split and unsplit sides of stack.
 | 
				
			||||||
 | 
					            # Split = all windows displayed
 | 
				
			||||||
 | 
					            # Unsplit = 1 window displayed, like Max layout, but still with
 | 
				
			||||||
 | 
					            # multiple stack panes
 | 
				
			||||||
 | 
					            Key([self.mod, "shift"], "Return", lazy.layout.toggle_split()),
 | 
				
			||||||
 | 
					            Key([self.mod], "Return", lazy.spawn(Config.get('app_terminal', "xterm"))),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            # Toggle between different layouts as defined below
 | 
				
			||||||
 | 
					            Key([self.mod], "Tab", lazy.next_layout()),
 | 
				
			||||||
 | 
					            Key([self.mod], "w", lazy.window.kill()),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            Key([self.mod, "control"], "r", lazy.restart()),
 | 
				
			||||||
 | 
					            Key([self.mod, "control"], "q", lazy.shutdown()),
 | 
				
			||||||
 | 
					            Key([self.mod], "r", lazy.spawncmd()),
 | 
				
			||||||
 | 
					            # Key([self.mod, "shift"], "e", self.evaluate()),
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def init_groups(self):
 | 
				
			||||||
 | 
					        log.debug("Initializing groups")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # http://fontawesome.io/cheatsheet
 | 
				
			||||||
 | 
					        return [Group(i) for i in ""]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def init_layouts(self):
 | 
				
			||||||
 | 
					        log.debug("Initializing layouts")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return [
 | 
				
			||||||
 | 
					            layout.Matrix(columns=2,
 | 
				
			||||||
 | 
					                          border_focus=Config.get('colour_border_focus', "#ffffff"),
 | 
				
			||||||
 | 
					                          border_normal=Config.get('colour_border_normal', "#777777"),
 | 
				
			||||||
 | 
					                          border_width=Config.get('width_border', "1"),
 | 
				
			||||||
 | 
					                          margin=Config.get('margin_layout', "0"),
 | 
				
			||||||
 | 
					                          ),
 | 
				
			||||||
 | 
					            layout.Max(),
 | 
				
			||||||
 | 
					            layout.Stack(num_stacks=2)
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def init_widget_defaults(self):
 | 
				
			||||||
 | 
					        log.debug("Initializing widget_defaults")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return {
 | 
				
			||||||
 | 
					            "font": Config.get('font_default', "Sans"),
 | 
				
			||||||
 | 
					            "fontsize": Config.get('fontsize_default', 16),
 | 
				
			||||||
 | 
					            "padding": 3,
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def init_screens(self):
 | 
				
			||||||
 | 
					        log.debug("Initializing screens")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        num_screens = utils.get_screen_count()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        screens = []
 | 
				
			||||||
 | 
					        for x in range(num_screens):
 | 
				
			||||||
 | 
					            widgets = []
 | 
				
			||||||
 | 
					            widgets.extend([
 | 
				
			||||||
 | 
					                utils.bar_separator(Config),
 | 
				
			||||||
 | 
					                widget.GroupBox(
 | 
				
			||||||
 | 
					                    active=Config.get('colour_groupbox_icon_active', '#ffffff'),
 | 
				
			||||||
 | 
					                    borderwidth=Config.get('width_groupbox_border', 1),
 | 
				
			||||||
 | 
					                    disable_drag=Config.get('bool_groupbox_disable_drag', False),
 | 
				
			||||||
 | 
					                    font=Config.get('font_groupbox', 'Arial'),
 | 
				
			||||||
 | 
					                    fontsize=Config.get('fontsize_groupbox', 15),
 | 
				
			||||||
 | 
					                    highlight_color=Config.get("colour_groupbox_border_normal", '#444444'),
 | 
				
			||||||
 | 
					                    inactive=Config.get('colour_groupbox_icon_inactive', '#444444'),
 | 
				
			||||||
 | 
					                    rounded=Config.get('bool_groupbox_rounded_borders', True),
 | 
				
			||||||
 | 
					                    this_current_screen_border=Config.get('colour_groupbox_border_focus', '#ffffff'),
 | 
				
			||||||
 | 
					                    this_screen_border=Config.get('colour_groupbox_border_focus', '#ffffff'),
 | 
				
			||||||
 | 
					                    margin=Config.get('margin_groupbox', 0)
 | 
				
			||||||
 | 
					                ),
 | 
				
			||||||
 | 
					                utils.bar_separator(Config),
 | 
				
			||||||
 | 
					                widget.Prompt(**self.widget_defaults),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                widget.WindowName(**self.widget_defaults),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                widget.CPUGraph(
 | 
				
			||||||
 | 
					                    width=25,
 | 
				
			||||||
 | 
					                    border_color="#000000",
 | 
				
			||||||
 | 
					                    border_width=0,
 | 
				
			||||||
 | 
					                    line_width=1,
 | 
				
			||||||
 | 
					                    samples=10,
 | 
				
			||||||
 | 
					                ),
 | 
				
			||||||
 | 
					                widget.BatteryIcon(
 | 
				
			||||||
 | 
					                    battery_name=Config.get('battery_name', 'BAT0'),
 | 
				
			||||||
 | 
					                    energy_full_file=Config.get('battery_energy_full_file', 'charge_full'),
 | 
				
			||||||
 | 
					                    energy_now_file=Config.get('battery_energy_now_file', 'charge_now'),
 | 
				
			||||||
 | 
					                    theme_path=Config.get('battery_theme_path', '/home/docs/checkouts/readthedocs.org/user_builds/qtile/checkouts/latest/libqtile/resources/battery-icons'),
 | 
				
			||||||
 | 
					                    update_delay=Config.get('battery_update_delay', 30)
 | 
				
			||||||
 | 
					                ),
 | 
				
			||||||
 | 
					            ])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            # Systray only on first screen
 | 
				
			||||||
 | 
					            if x == 0:
 | 
				
			||||||
 | 
					                widgets.append(widget.Systray(**self.widget_defaults))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            widgets.extend([
 | 
				
			||||||
 | 
					                utils.bar_separator(Config),
 | 
				
			||||||
 | 
					                widget.Clock(format="%a %d %b, %H:%M", **self.widget_defaults),
 | 
				
			||||||
 | 
					                utils.CheckUpdatesYaourt(
 | 
				
			||||||
 | 
					                    colour_no_updates=Config.get('updates_colour_none', '#ffffff'),
 | 
				
			||||||
 | 
					                    colour_have_updates=Config.get('updates_colour_available', '#ff0000'),
 | 
				
			||||||
 | 
					                    display_format=Config.get('updates_display_format', 'Updates: {updates}'),
 | 
				
			||||||
 | 
					                    execute=Config.get('updates_execute_command', None),
 | 
				
			||||||
 | 
					                    **self.widget_defaults
 | 
				
			||||||
 | 
					                ),
 | 
				
			||||||
 | 
					                widget.TextBox("#{}".format(x), name="default", **self.widget_defaults),
 | 
				
			||||||
 | 
					            ])
 | 
				
			||||||
 | 
					            screens.append(Screen(top=bar.Bar(
 | 
				
			||||||
 | 
					                widgets=widgets,
 | 
				
			||||||
 | 
					                size=Config.get('height_groupbox', 30)
 | 
				
			||||||
 | 
					            )))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return screens
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def init_mouse(self):
 | 
				
			||||||
 | 
					        log.debug("Initializing mouse")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Drag floating layouts.
 | 
				
			||||||
 | 
					        return [
 | 
				
			||||||
 | 
					            Drag([self.mod], "Button1", lazy.window.set_position_floating(),
 | 
				
			||||||
 | 
					                 start=lazy.window.get_position()),
 | 
				
			||||||
 | 
					            Drag([self.mod], "Button3", lazy.window.set_size_floating(),
 | 
				
			||||||
 | 
					                 start=lazy.window.get_size()),
 | 
				
			||||||
 | 
					            Click([self.mod], "Button2", lazy.window.bring_to_front())
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def update_keys(self):
 | 
				
			||||||
 | 
					        log.debug("Updating keys")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for i, g in enumerate(self.groups):
 | 
				
			||||||
 | 
					            # mod1 + number = switch to group
 | 
				
			||||||
 | 
					            self.keys.append(
 | 
				
			||||||
 | 
					                Key([self.mod], str(i + 1), lazy.group[g.name].toscreen())
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            # mod1 + shift + number = switch to & move focused window to group
 | 
				
			||||||
 | 
					            self.keys.append(
 | 
				
			||||||
 | 
					                Key([self.mod, "shift"], str(i + 1), lazy.window.togroup(g.name))
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def callback_startup(self):
 | 
				
			||||||
 | 
					        utils.execute("sleep 3")
 | 
				
			||||||
 | 
					        utils.execute_once("nitrogen --restore")
 | 
				
			||||||
							
								
								
									
										50
									
								
								kuro/utils.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,50 @@
 | 
				
			||||||
 | 
					import re
 | 
				
			||||||
 | 
					import subprocess
 | 
				
			||||||
 | 
					from libqtile import widget, bar
 | 
				
			||||||
 | 
					from libqtile.widget.check_updates import CheckUpdates
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def is_running(process):
 | 
				
			||||||
 | 
					    s = subprocess.Popen(["ps", "axuw"], stdout=subprocess.PIPE)
 | 
				
			||||||
 | 
					    for x in s.stdout:
 | 
				
			||||||
 | 
					        if re.search(process, x.decode('utf-8')):
 | 
				
			||||||
 | 
					            return True
 | 
				
			||||||
 | 
					    return False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def execute(process):
 | 
				
			||||||
 | 
					    return subprocess.Popen(process.split())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def execute_once(process):
 | 
				
			||||||
 | 
					    if not is_running(process):
 | 
				
			||||||
 | 
					        return subprocess.Popen(process.split())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def get_screen_count():
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        output = subprocess.check_output("xrandr -q".split()).decode('utf-8')
 | 
				
			||||||
 | 
					        output = [x for x in output.split("\n") if " connected" in x]
 | 
				
			||||||
 | 
					    except subprocess.CalledProcessError:
 | 
				
			||||||
 | 
					        return 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if output:
 | 
				
			||||||
 | 
					        return len(output)
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        return 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def bar_separator(config):
 | 
				
			||||||
 | 
					    return widget.Sep(foreground=config.get('colour_spacer_background', '#777777'),
 | 
				
			||||||
 | 
					                      linewidth=config.get('width_spacer', 1),
 | 
				
			||||||
 | 
					                      padding=config.get('padding_spacer', 4),
 | 
				
			||||||
 | 
					                      )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class CheckUpdatesYaourt(CheckUpdates):
 | 
				
			||||||
 | 
					    def __init__(self, **config):
 | 
				
			||||||
 | 
					        super(CheckUpdatesYaourt, self).__init__(**config)
 | 
				
			||||||
 | 
					        # Override command and output with yaourt command
 | 
				
			||||||
 | 
					        self.cmd = "yaourt -Qua".split()
 | 
				
			||||||
 | 
					        self.subtr = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||