Multiple changes
This commit is contained in:
parent
5b7475e50f
commit
8c070c86a5
7 changed files with 1052 additions and 709 deletions
270
kuro/theme.py
270
kuro/theme.py
|
@ -7,6 +7,9 @@ from libqtile.command import lazy
|
|||
from libqtile import layout, bar, widget
|
||||
|
||||
# Import theme util functions
|
||||
from xcffib.xproto import WindowError
|
||||
|
||||
import kuro.utils.widgets
|
||||
from kuro.utils import general as utils
|
||||
|
||||
# Import variables
|
||||
|
@ -14,6 +17,7 @@ from kuro.base import BaseTheme
|
|||
from kuro.utils.general import display_wm_class, test_popups
|
||||
from kuro.utils.kb_backlight import handle_focus_change as kb_handle_focus_change
|
||||
from kuro.utils import layouts as kuro_layouts
|
||||
from kuro.utils.windows import KuroStatic
|
||||
|
||||
try:
|
||||
from kuro.config import Config
|
||||
|
@ -43,6 +47,12 @@ class Kuro(BaseTheme):
|
|||
# Top bars
|
||||
topbars = []
|
||||
|
||||
# Visualizers
|
||||
audio_visualizers = []
|
||||
|
||||
# Static windows
|
||||
static_windows = []
|
||||
|
||||
# Current wallpaper path
|
||||
current_wallpaper = None
|
||||
|
||||
|
@ -52,6 +62,24 @@ class Kuro(BaseTheme):
|
|||
# Window manager name
|
||||
wmname = "QTile"
|
||||
|
||||
# Floating layout override
|
||||
floating_layout = kuro_layouts.KuroFloating(float_rules=[
|
||||
{'wmclass': 'confirm'},
|
||||
{'wmclass': 'dialog'},
|
||||
{'wmclass': 'download'},
|
||||
{'wmclass': 'error'},
|
||||
{'wmclass': 'file_progress'},
|
||||
{'wmclass': 'notification'},
|
||||
{'wmclass': 'splash'},
|
||||
{'wmclass': 'toolbar'},
|
||||
{'wmclass': 'confirmreset'}, # gitk
|
||||
{'wmclass': 'makebranch'}, # gitk
|
||||
{'wmclass': 'maketag'}, # gitk
|
||||
{'wname': 'branchdialog'}, # gitk
|
||||
{'wname': 'pinentry'}, # GPG key password entry
|
||||
{'wmclass': 'ssh-askpass'}, # ssh-askpass
|
||||
])
|
||||
|
||||
def set_debug_text(self, text):
|
||||
for field in self.debug_textfields:
|
||||
field.text = text
|
||||
|
@ -157,6 +185,9 @@ class Kuro(BaseTheme):
|
|||
# Reorganize screens
|
||||
Key([self.mod, "control"], "s", lazy.function(self.update_screens)),
|
||||
|
||||
# Toggle static windows
|
||||
Key([self.mod], "p", lazy.function(self.toggle_window_static)),
|
||||
|
||||
|
||||
##
|
||||
# Debug keyboard shortcuts
|
||||
|
@ -166,6 +197,12 @@ class Kuro(BaseTheme):
|
|||
# Redraw the top bar
|
||||
Key([self.mod, "shift", "control"], "r", lazy.function(self.redraw_bar)),
|
||||
|
||||
# Update visualizer widgets
|
||||
Key([self.mod, "shift", "control"], "v", lazy.function(self.reinitialize_visualizers)),
|
||||
|
||||
# Show extensive window info
|
||||
Key([self.mod, "shift", "control"], "i", lazy.function(self.show_window_info)),
|
||||
|
||||
# Spawn a popup, and despawn it after 3 seconds
|
||||
Key([self.mod, "control"], "p", lazy.function(test_popups)),
|
||||
]
|
||||
|
@ -179,7 +216,7 @@ class Kuro(BaseTheme):
|
|||
groups.append(Group("", spawn=Config.get('web_browser', "xterm links")))
|
||||
groups.append(Group("", spawn=Config.get('app_terminal', "xterm")))
|
||||
groups.append(Group(""))
|
||||
groups.append(Group("", spawn="franz4-bin"))
|
||||
groups.append(Group("", spawn="franz"))
|
||||
groups.append(Group("", spawn="quasselclient"))
|
||||
groups.append(Group("", spawn=Config.get('file_manager', "thunar")))
|
||||
groups.append(Group("", spawn="thunderbird"))
|
||||
|
@ -194,6 +231,7 @@ class Kuro(BaseTheme):
|
|||
|
||||
return [
|
||||
kuro_layouts.KuroWmii(
|
||||
theme=self,
|
||||
border_focus=Config.get('colour_border_focus', "#ffffff"),
|
||||
border_focus_stack=Config.get('colour_border_normal', "#777777"),
|
||||
border_normal=Config.get('colour_border_normal', "#777777"),
|
||||
|
@ -222,7 +260,7 @@ class Kuro(BaseTheme):
|
|||
self.log_debug("Initializing screens")
|
||||
|
||||
self.num_screens = utils.get_screen_count()
|
||||
if self.num_screens == 0:
|
||||
if self.num_screens <= 0:
|
||||
self.num_screens = 1
|
||||
|
||||
screens = []
|
||||
|
@ -245,7 +283,7 @@ class Kuro(BaseTheme):
|
|||
),
|
||||
widget.Prompt(**self.widget_defaults),
|
||||
|
||||
widget.TaskList(
|
||||
kuro.utils.widgets.KuroTaskList(
|
||||
border=Config.get('tasklist_border', '#ffffff'),
|
||||
borderwidth=Config.get('tasklist_borderwidth', 1),
|
||||
font=Config.get('tasklist_font', 'Arial'),
|
||||
|
@ -260,21 +298,23 @@ class Kuro(BaseTheme):
|
|||
])
|
||||
|
||||
if Config.get('show_audio_visualizer', False):
|
||||
widgets.append(utils.AudioVisualizerWidget(
|
||||
widgets.append(kuro.utils.widgets.AudioVisualizerWidget(
|
||||
graph_color=Config.get('visualizer_graph_color', "#ffffff"),
|
||||
fill_color=Config.get('visualizer_fill_color', "#ffffff.3"),
|
||||
border_color=Config.get('visualizer_border_color', "#000000"),
|
||||
border_width=Config.get('visualizer_graph_width', 0),
|
||||
line_width=Config.get('visualizer_line_width', 1),
|
||||
frequency=0.05
|
||||
margin_x=1,
|
||||
margin_y=1,
|
||||
frequency=1
|
||||
))
|
||||
|
||||
widgets.extend([
|
||||
utils.MediaWidget(),
|
||||
kuro.utils.widgets.MediaWidget(),
|
||||
|
||||
utils.SeparatorWidget(),
|
||||
kuro.utils.widgets.SeparatorWidget(),
|
||||
|
||||
utils.ThermalSensorWidget(
|
||||
kuro.utils.widgets.ThermalSensorWidget(
|
||||
font=Config.get('font_topbar', 'Arial'),
|
||||
fontsize=Config.get('fontsize_topbar', 16),
|
||||
foreground=Config.get('thermal_colour', '#ffffff'),
|
||||
|
@ -325,7 +365,7 @@ class Kuro(BaseTheme):
|
|||
frequency=2,
|
||||
),
|
||||
|
||||
utils.KuroBatteryIcon(
|
||||
kuro.utils.widgets.KuroBatteryIcon(
|
||||
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'),
|
||||
|
@ -334,14 +374,14 @@ class Kuro(BaseTheme):
|
|||
update_delay=Config.get('battery_update_delay', 30)
|
||||
),
|
||||
|
||||
utils.WifiIconWidget(
|
||||
kuro.utils.widgets.WifiIconWidget(
|
||||
interface=Config.get('wifi_interface', 'wlp4s0'),
|
||||
theme_path=Config.get('wifi_theme_path', '/home/docs/checkouts/readthedocs.org/user_builds/qtile'
|
||||
'/checkouts/latest/libqtile/resources/battery-icons'),
|
||||
update_interval=Config.get('wifi_update_interval', 30)
|
||||
),
|
||||
|
||||
utils.PulseVolumeWidget(
|
||||
kuro.utils.widgets.PulseVolumeWidget(
|
||||
cardid=Config.get('volume_cardid', None),
|
||||
channel=Config.get('volume_channel', 'Master'),
|
||||
device=Config.get('volume_device', None),
|
||||
|
@ -358,7 +398,7 @@ class Kuro(BaseTheme):
|
|||
update_interval=Config.get('volume_update_interval', 0.2)
|
||||
),
|
||||
|
||||
utils.PulseVolumeWidget(
|
||||
kuro.utils.widgets.PulseVolumeWidget(
|
||||
cardid=Config.get('bluevol_cardid', None),
|
||||
channel=Config.get('bluevol_channel', 'Master'),
|
||||
device=Config.get('bluevol_device', None),
|
||||
|
@ -376,14 +416,14 @@ class Kuro(BaseTheme):
|
|||
)
|
||||
])
|
||||
|
||||
# Systray only on first screen
|
||||
# Systray can only be on one screen, so put it on the first
|
||||
if x == 0:
|
||||
widgets.append(widget.Systray(**self.widget_defaults))
|
||||
|
||||
widgets.extend([
|
||||
utils.KuroCurrentLayoutIcon(custom_icon_paths=Config.get('custom_layout_icon_paths', [])),
|
||||
kuro.utils.widgets.KuroCurrentLayoutIcon(custom_icon_paths=Config.get('custom_layout_icon_paths', [])),
|
||||
widget.Clock(format="%a %d %b, %H:%M", **self.widget_defaults),
|
||||
utils.CheckUpdatesYay(
|
||||
kuro.utils.widgets.CheckUpdatesYay(
|
||||
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}'),
|
||||
|
@ -456,26 +496,18 @@ class Kuro(BaseTheme):
|
|||
|
||||
# Keys for the Wmii layout
|
||||
self.keys.extend([
|
||||
Key(
|
||||
[self.mod, "shift", "control"], "l",
|
||||
lazy.layout.grow_right()
|
||||
),
|
||||
Key(
|
||||
[self.mod, "shift"], "l",
|
||||
lazy.layout.shuffle_right()
|
||||
),
|
||||
Key(
|
||||
[self.mod, "shift", "control"], "h",
|
||||
lazy.layout.grow_left()
|
||||
),
|
||||
Key(
|
||||
[self.mod, "shift"], "h",
|
||||
lazy.layout.shuffle_left()
|
||||
),
|
||||
Key(
|
||||
[self.mod], "s",
|
||||
lazy.layout.toggle_split()
|
||||
)
|
||||
Key([self.mod, "shift"], "j", lazy.layout.shuffle_down()),
|
||||
Key([self.mod, "shift"], "k", lazy.layout.shuffle_up()),
|
||||
Key([self.mod, "shift"], "h", lazy.layout.shuffle_left()),
|
||||
Key([self.mod, "shift"], "l", lazy.layout.shuffle_right()),
|
||||
|
||||
Key([self.mod, "shift", "control"], "j", lazy.layout.grow_down()),
|
||||
Key([self.mod, "shift", "control"], "k", lazy.layout.grow_up()),
|
||||
Key([self.mod, "shift", "control"], "h", lazy.layout.grow_left()),
|
||||
Key([self.mod, "shift", "control"], "l", lazy.layout.grow_right()),
|
||||
|
||||
Key([self.mod], "s", lazy.layout.toggle_split()),
|
||||
Key([self.mod], "n", lazy.layout.normalize()),
|
||||
])
|
||||
|
||||
# Util functions
|
||||
|
@ -505,20 +537,68 @@ class Kuro(BaseTheme):
|
|||
elif laptop_screen is not None and len(screens) > 1:
|
||||
utils.execute("arandr")
|
||||
|
||||
def reinitialize_visualizers(self, qtile=None):
|
||||
if Config.get("show_audio_visualizer", False):
|
||||
logger.warning("Reinitializing visualizers...")
|
||||
for screen in self.qtile.screens:
|
||||
for widget in screen.top.widgets:
|
||||
if isinstance(widget, kuro.utils.widgets.AudioVisualizerWidget):
|
||||
if widget.client is not None:
|
||||
widget.client.kill()
|
||||
widget.client = None
|
||||
widget.screen = None
|
||||
self.update_visualizers(qtile=qtile)
|
||||
|
||||
def update_visualizers(self, qtile=None):
|
||||
if Config.get("show_audio_visualizer", False):
|
||||
logger.warning("Updating visualizers..")
|
||||
for screen in self.qtile.screens:
|
||||
for widget in screen.top.widgets:
|
||||
if isinstance(widget, kuro.utils.widgets.AudioVisualizerWidget):
|
||||
if widget.client is None:
|
||||
logger.warning("Spawning for screen {}".format(screen))
|
||||
utils.execute(Config.get('visualizer_app', "glava"))
|
||||
else:
|
||||
widget.update_graph()
|
||||
|
||||
def show_window_info(self, qtile):
|
||||
window = qtile.currentWindow if qtile else None
|
||||
|
||||
import pprint
|
||||
if window:
|
||||
info = window.cmd_inspect() or None
|
||||
name = window.name
|
||||
|
||||
utils.notify(title="Window properties {}".format(name),
|
||||
content="{}".format(pprint.pformat(vars(window))))
|
||||
|
||||
if info:
|
||||
info = pprint.pformat(info)
|
||||
utils.notify(title="Window info of {}".format(name),
|
||||
content="{}".format(info))
|
||||
|
||||
# @staticmethod
|
||||
def toggle_window_static(self, qtile):
|
||||
window = qtile.currentWindow
|
||||
if window in self.static_windows:
|
||||
utils.notify("Unpinned {}".format(window.name), "{} has been unpinned".format(window.name))
|
||||
self.static_windows.remove(window)
|
||||
del window.is_static_window
|
||||
else:
|
||||
utils.notify("Pinned {}".format(window.name), "{} has been pinned".format(window.name))
|
||||
self.static_windows.append(window)
|
||||
window.is_static_window = True
|
||||
|
||||
window.floating = True
|
||||
|
||||
# QTile base callbacks
|
||||
def callback_startup_once(self, *args, **kwargs):
|
||||
pass
|
||||
#Kuro.update_screens(self.qtile)
|
||||
|
||||
def callback_startup(self):
|
||||
utils.execute("sleep 3")
|
||||
|
||||
# self.log_info("Restoring previous wallpaper...")
|
||||
# utils.execute_once("nitrogen --restore")
|
||||
self.update_wallpaper(self.qtile)
|
||||
|
||||
def callback_startup(self):
|
||||
if self.current_wallpaper:
|
||||
utils.execute_once(["wal", "-n", "-i", "{}".format(self.current_wallpaper)])
|
||||
p = utils.execute_once(["wal", "-n", "-i", "{}".format(self.current_wallpaper)])
|
||||
p.wait()
|
||||
else:
|
||||
|
||||
wallpaper = None
|
||||
|
@ -531,30 +611,29 @@ class Kuro(BaseTheme):
|
|||
if wallpaper:
|
||||
Kuro.set_wallpaper(self.qtile, wallpaper)
|
||||
else:
|
||||
utils.execute_once("nitrogen --restore")
|
||||
p = utils.execute_once("nitrogen --restore")
|
||||
p.wait()
|
||||
|
||||
self.log_info("Starting compositor...")
|
||||
utils.execute_once("compton -b")
|
||||
# self.log_info("Starting compositor...")
|
||||
# utils.execute_once("compton -b")
|
||||
|
||||
# Update color scheme
|
||||
self.initialize_colorscheme()
|
||||
|
||||
# Update color scheme
|
||||
Kuro.update_colorscheme(self.qtile)
|
||||
|
||||
# display = os.environ['DISPLAY']
|
||||
#
|
||||
# if not display:
|
||||
# display = ":0"
|
||||
#
|
||||
# # Start compton for each screen
|
||||
# for x in range(self.num_screens):
|
||||
# self.log_info("Launching compton for screen {}.{}".format(display, x))
|
||||
# utils.execute_once("compton --config ~/.config/compton.conf -b -d {}.{}".format(display, x))
|
||||
|
||||
# def callback_screen_change(self, *args, **kwargs):
|
||||
# self.num_screens = utils.get_screen_count()
|
||||
# return True
|
||||
# for window in self.static_windows:
|
||||
# window.togroup()
|
||||
|
||||
def callback_setgroup(self, *args, **kwargs):
|
||||
for window in self.static_windows:
|
||||
# Only move if the window is not currently on any screen.
|
||||
if window.group.screen is None:
|
||||
try:
|
||||
window.togroup()
|
||||
except WindowError as e:
|
||||
logger.warning("Could not move static window {}, removing from list: {}".format(window.name, e))
|
||||
del window.is_static_window
|
||||
self.static_windows.remove(window)
|
||||
|
||||
def callback_focus_change(self, *args, **kwargs):
|
||||
if self.do_keyboard_updates:
|
||||
|
@ -599,6 +678,56 @@ class Kuro(BaseTheme):
|
|||
window.name))
|
||||
self.log_info(str(self.qtile.dgroups.rules_map))
|
||||
|
||||
# Check if it is a visualizer
|
||||
if Config.get("show_audio_visualizer", False):
|
||||
client = args[0] if len(args) > 0 else None
|
||||
if client is not None and client.window.get_name() == "GLava":
|
||||
placed = False
|
||||
for screen in self.qtile.screens:
|
||||
for widget in screen.top.widgets:
|
||||
if not placed and isinstance(widget, kuro.utils.widgets.AudioVisualizerWidget):
|
||||
if widget.client is None:
|
||||
viz_info = widget.info()
|
||||
pos_x = viz_info['offset'] + widget.margin_x - 1
|
||||
pos_y = 0 + widget.margin_y - 1
|
||||
width = viz_info['width'] - (2 * (widget.margin_x - 1))
|
||||
height = viz_info['height'] - (2 * (widget.margin_y - 1))
|
||||
screen_index = self.qtile.screens.index(screen)
|
||||
logger.warning("Attaching {} {} to {} on screen {}".format(client, client.window.wid, type(widget).__name__, screen_index))
|
||||
c = KuroStatic.create(client, screen, x=pos_x, y=pos_y, width=width, height=height)
|
||||
c.setOpacity(Config.get("bar_opacity", 1.0))
|
||||
widget.set_client(c, screen)
|
||||
placed = True
|
||||
if not placed:
|
||||
if Config.get("kill_unnecessary_glava_processes", False):
|
||||
logger.warning("Killing GLava {} because there is no widget where it can fit".format(client))
|
||||
utils.notify("Glava", "Killing new GLava process because there is no screen without a visualizer")
|
||||
client.kill()
|
||||
else:
|
||||
logger.warning("Not repositioning GLava {} because there is no widget where it can fit".format(client))
|
||||
utils.notify("Glava", "Not repisitioning new GLava process because there is no screen without a visualizer")
|
||||
|
||||
def callback_client_killed(self, *args, **kwargs):
|
||||
client = args[0]
|
||||
logger.warning("Client {} Killed".format(client))
|
||||
|
||||
# Detach visualizer from widget if it was a visualizer window
|
||||
if isinstance(client, KuroStatic):
|
||||
for screen in self.qtile.screens:
|
||||
for widget in screen.top.widgets:
|
||||
if isinstance(widget, kuro.utils.widgets.AudioVisualizerWidget):
|
||||
if widget.client == client:
|
||||
screen_index = self.qtile.screens.index(screen)
|
||||
logger.warning("Detaching {} {} from widget {} on screen {}".format(client, client.window.wid, type(widget).__name__, screen_index))
|
||||
widget.client = None
|
||||
widget.screen = None
|
||||
|
||||
# If this window was static, remove it from the static window list
|
||||
if hasattr(client, "is_static_window") and client.is_static_window:
|
||||
logger.warning("Removing static window {}".format(client.name))
|
||||
del client.is_static_window
|
||||
self.static_windows.remove(client)
|
||||
|
||||
@staticmethod
|
||||
def update_wallpaper(qtile):
|
||||
wallpapers = []
|
||||
|
@ -617,7 +746,8 @@ class Kuro(BaseTheme):
|
|||
|
||||
@staticmethod
|
||||
def set_wallpaper(qtile, filename):
|
||||
utils.execute_once("wal-nitrogen {}".format(filename))
|
||||
p = utils.execute_once("wal-nitrogen-noupdate {}".format(filename))
|
||||
p.wait()
|
||||
qtile.theme_instance.current_wallpaper = filename
|
||||
Kuro.update_colorscheme(qtile)
|
||||
|
||||
|
@ -644,6 +774,7 @@ class Kuro(BaseTheme):
|
|||
Config.highlight = colors['color3']
|
||||
Config.inactive_light = colors['color4']
|
||||
Config.inactive_dark = colors['color5']
|
||||
Config.bar_background = colors['color1']
|
||||
|
||||
@staticmethod
|
||||
def update_colorscheme(qtile):
|
||||
|
@ -651,7 +782,8 @@ class Kuro(BaseTheme):
|
|||
:type qtile: libqtile.manager.Qtile
|
||||
"""
|
||||
if qtile.theme_instance.current_wallpaper:
|
||||
utils.execute(["wal", "-n", "-i", "{}".format(qtile.theme_instance.current_wallpaper)])
|
||||
p = utils.execute(["wal", "-n", "-i", "{}".format(qtile.theme_instance.current_wallpaper)])
|
||||
p.wait()
|
||||
|
||||
colors = None
|
||||
if os.path.isfile("/home/kevin/.cache/wal/colors.json"):
|
||||
|
@ -668,6 +800,7 @@ class Kuro(BaseTheme):
|
|||
Config.highlight = colors['color3']
|
||||
Config.inactive_light = colors['color4']
|
||||
Config.inactive_dark = colors['color5']
|
||||
Config.bar_background = colors['color1']
|
||||
|
||||
# Update border colors in layouts
|
||||
for group in qtile.groups:
|
||||
|
@ -687,7 +820,7 @@ class Kuro(BaseTheme):
|
|||
try:
|
||||
w._update_drawer()
|
||||
except Exception as e:
|
||||
logger.error("Error while updating drawer: {}".format(e))
|
||||
logger.error("Error while updating drawer for widget {}: {}".format(w, e))
|
||||
|
||||
if hasattr(w, 'foreground'):
|
||||
w.foreground = colors['color15']
|
||||
|
@ -722,12 +855,17 @@ class Kuro(BaseTheme):
|
|||
if hasattr(w, 'other_screen_border'):
|
||||
w.other_screen_border = colors['color8']
|
||||
|
||||
if isinstance(w, utils.AudioVisualizerWidget):
|
||||
if isinstance(w, kuro.utils.widgets.AudioVisualizerWidget):
|
||||
w.graph_color = colors['color15']
|
||||
w.fill_color = colors['color8']
|
||||
|
||||
bar.draw()
|
||||
|
||||
# Update colors in visualizers and restart visualizers
|
||||
with open(Config.get("glava_color_file_path", "~/.config/glava/kurobars_color.glsl"), 'w') as f:
|
||||
f.write("#define COLOR {}\n#request setbg {}".format(colors['color15'], colors['color1'][1:]))
|
||||
qtile.theme_instance.reinitialize_visualizers()
|
||||
|
||||
utils.notify(
|
||||
"Updated colorscheme!",
|
||||
"active: {}, inactive: {}".format(colors['color15'], colors['color1'])
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue