Compatibility with latest qtile, fixes to widgets, etc...

This commit is contained in:
Kevin Alberts 2021-11-22 19:42:03 +01:00
parent a033bde573
commit 6a265ea3b6
6 changed files with 78 additions and 50 deletions

View file

@ -121,8 +121,5 @@ def main(qtile):
else: else:
qtile.cmd_warning() qtile.cmd_warning()
# Save qtile instance in theme
Theme.qtile = qtile
# Save theme instance in qtile # Save theme instance in qtile
qtile.theme_instance = Theme qtile.theme_instance = Theme

View file

@ -16,12 +16,10 @@ class Config(BaseConfig):
# Default Applications # Default Applications
app_terminal = "terminator" app_terminal = "terminator"
#app_launcher = "/home/kevin/bin/dmenu_wal.sh" app_launcher = "/home/kevin/bin/dmenu_wal.sh"
app_launcher = "dmenu_run -i -p '»' -nb '" + background + "' -fn 'Noto Sans-11' -nf '" + inactive_light + \
"' -sb '" + highlight + "' -sf '" + foreground + "'"
web_browser = "firefox-developer-edition" web_browser = "firefox-developer-edition"
file_manager = "thunar" file_manager = "thunar"
app_chat = "/home/kevin/bin/ramboxpro" app_chat = "/usr/bin/ramboxpro"
app_irc = "quasselclient" app_irc = "quasselclient"
app_mail = "thunderbird" app_mail = "thunderbird"
cmd_brightness_up = "sudo /usr/bin/xbacklight -inc 10" cmd_brightness_up = "sudo /usr/bin/xbacklight -inc 10"
@ -94,8 +92,8 @@ class Config(BaseConfig):
# Thermal indicator variables # Thermal indicator variables
thermal_threshold = 75 thermal_threshold = 75
thermal_sensor = "Package id 0" thermal_sensor = "Tdie"
thermal_chip = "coretemp-isa-0000" thermal_chip = "zenpower-pci-00c3"
# CPU graph variables # CPU graph variables
cpu_graph_colour = '#ff0000' cpu_graph_colour = '#ff0000'
@ -122,8 +120,8 @@ 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_sink = "alsa_output.pci-0000_04_00.0.pro-output-0" volume_pulse_sink = "alsa_output.usb-Burr-Brown_from_TI_USB_Audio_CODEC-00.analog-stereo"
volume_pulse_sink2 = "alsa_output.usb-Burr-Brown_from_TI_USB_Audio_CODEC-00.pro-output-0" volume_pulse_sink2 = "alsa_output.pci-0000_0e_00.4.analog-stereo"
volume_is_bluetooth_icon = False volume_is_bluetooth_icon = False
volume_update_interval = 0.2 volume_update_interval = 0.2
@ -152,7 +150,7 @@ class Config(BaseConfig):
do_keyboard_updates = False do_keyboard_updates = False
# Show audio visualizer # Show audio visualizer
show_audio_visualizer = False show_audio_visualizer = True
kill_unnecessary_glava_processes = True kill_unnecessary_glava_processes = True
# Show thermal widget # Show thermal widget

View file

@ -9,7 +9,7 @@ logger.error("Importing qtile theme requirements...")
from libqtile.config import Key, Screen, Group, Drag, Click, Match from libqtile.config import Key, Screen, Group, Drag, Click, Match
from libqtile.command import lazy from libqtile.command import lazy
from libqtile import layout, bar, widget from libqtile import layout, bar, widget, qtile
logger.error("Importing theme util functions...") logger.error("Importing theme util functions...")
@ -83,13 +83,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
Match(title='origin.exe', wm_class='Wine'), # Wine Origin game launcher
]) ])
def set_debug_text(self, text): def set_debug_text(self, text):
for field in self.debug_textfields: for field in self.debug_textfields:
field.text = text field.text = text
for bar in self.debug_bars: for bar in self.debug_bars:
if self.qtile is not None: if qtile is not None:
bar.draw() bar.draw()
def log_debug(self, text): def log_debug(self, text):
@ -144,7 +145,7 @@ class Kuro(BaseTheme):
Key([self.mod, "shift"], 'f', lazy.window.toggle_floating()), Key([self.mod, "shift"], 'f', lazy.window.toggle_floating()),
# Pinned toggle # Pinned toggle
Key([self.mod], 'p', lazy.function(self.toggle_pinned)), Key([self.mod, "shift"], 'p', lazy.function(self.toggle_pinned)),
# Toggle between split and unsplit sides of stack. # Toggle between split and unsplit sides of stack.
# Split = all windows displayed # Split = all windows displayed
@ -513,22 +514,22 @@ class Kuro(BaseTheme):
else: else:
utils.execute("arandr") utils.execute("arandr")
def reinitialize_visualizers(self, qtile=None): def reinitialize_visualizers(self):
if Config.get("show_audio_visualizer", False): if Config.get("show_audio_visualizer", False):
logger.warning("Reinitializing visualizers...") logger.warning("Reinitializing visualizers...")
for screen in self.qtile.screens: for screen in qtile.screens:
for widget in screen.top.widgets: for widget in screen.top.widgets:
if isinstance(widget, kuro.utils.widgets.AudioVisualizerWidget): if isinstance(widget, kuro.utils.widgets.AudioVisualizerWidget):
if widget.client is not None: if widget.client is not None:
widget.client.kill() widget.client.kill()
widget.client = None widget.client = None
widget.screen = None widget.screen = None
self.update_visualizers(qtile=qtile) self.update_visualizers()
def update_visualizers(self, qtile=None): def update_visualizers(self):
if Config.get("show_audio_visualizer", False): if Config.get("show_audio_visualizer", False):
logger.warning("Updating visualizers..") logger.warning("Updating visualizers..")
for screen in self.qtile.screens: for screen in qtile.screens:
for widget in screen.top.widgets: for widget in screen.top.widgets:
if isinstance(widget, kuro.utils.widgets.AudioVisualizerWidget): if isinstance(widget, kuro.utils.widgets.AudioVisualizerWidget):
if widget.client is None: if widget.client is None:
@ -577,13 +578,20 @@ class Kuro(BaseTheme):
# QTile base callbacks # QTile base callbacks
def callback_startup_once(self, *args, **kwargs): def callback_startup_once(self, *args, **kwargs):
self.update_wallpaper(self.qtile) if not hasattr(qtile, 'theme_instance'):
# Save theme instance in qtile
qtile.theme_instance = self
self.update_wallpaper(qtile)
# Setup audio # Setup audio
# p = utils.execute_once(["qjackctl"]) # p = utils.execute_once(["qjackctl"])
# p.wait() # p.wait()
def callback_startup(self): def callback_startup(self):
if not hasattr(qtile, 'theme_instance'):
# Save theme instance in qtile
qtile.theme_instance = self
if self.current_wallpaper: if self.current_wallpaper:
p = utils.execute_once(["wal", "-n", "-i", "{}".format(self.current_wallpaper)]) p = utils.execute_once(["wal", "-n", "-i", "{}".format(self.current_wallpaper)])
p.wait() p.wait()
@ -596,7 +604,7 @@ class Kuro(BaseTheme):
except KeyError: except KeyError:
wallpaper = None wallpaper = None
if wallpaper: if wallpaper:
Kuro.set_wallpaper(self.qtile, wallpaper) Kuro.set_wallpaper(qtile, wallpaper)
else: else:
p = utils.execute_once("nitrogen --restore") p = utils.execute_once("nitrogen --restore")
p.wait() p.wait()
@ -610,6 +618,9 @@ class Kuro(BaseTheme):
self.log_info("Starting notification daemon...") self.log_info("Starting notification daemon...")
utils.execute_once("dunst") utils.execute_once("dunst")
self.log_info("Starting xiccd color profile manager...")
utils.execute_once("xiccd")
# Update color scheme # Update color scheme
self.initialize_colorscheme() self.initialize_colorscheme()
@ -635,9 +646,13 @@ class Kuro(BaseTheme):
initial_windows = [] initial_windows = []
def callback_startup_complete(self, *args, **kwargs): def callback_startup_complete(self, *args, **kwargs):
if not hasattr(qtile, 'theme_instance'):
# Save theme instance in qtile
qtile.theme_instance = self
# Only run on first startup # Only run on first startup
if not self.qtile.no_spawn: if not qtile.no_spawn:
dg = self.qtile.dgroups dg = qtile.dgroups
for r in dg.rules: for r in dg.rules:
pid = -1 pid = -1
# noinspection PyProtectedMember # noinspection PyProtectedMember
@ -651,12 +666,12 @@ class Kuro(BaseTheme):
self.callback_client_new() self.callback_client_new()
# After first startup is complete, start the audio apps that can only be started after boot is complete # After first startup is complete, start the audio apps that can only be started after boot is complete
if not self.qtile.no_spawn: if not qtile.no_spawn:
for app in Config.get("apps_audio_afterstart", []): for app in Config.get("apps_audio_afterstart", []):
utils.execute_once(app) utils.execute_once(app)
# Update color scheme # Update color scheme
Kuro.update_colorscheme(self.qtile) Kuro.update_colorscheme(qtile)
def callback_client_new(self, *args, **kwargs): def callback_client_new(self, *args, **kwargs):
client = args[0] if len(args) > 0 else None client = args[0] if len(args) > 0 else None
@ -664,27 +679,27 @@ class Kuro(BaseTheme):
if len(self.initial_windows) > 0: if len(self.initial_windows) > 0:
init = self.initial_windows.copy() init = self.initial_windows.copy()
for pid, gname in init: for pid, gname in init:
for group in self.qtile.groups: for group in qtile.groups:
if len(group.windows) > 0: if len(group.windows) > 0:
for window in group.windows: for window in group.windows:
w_pid = window.window.get_net_wm_pid() w_pid = window.window.get_net_wm_pid()
self.log_info("Comparing pid {} with window PID {}, window {}".format(pid, w_pid, self.log_info("Comparing pid {} with window PID {}, window {}".format(pid, w_pid,
window.name)) window.name))
if pid == w_pid: if pid == w_pid:
c = self.qtile.dgroups.rules_map.copy() c = qtile.dgroups.rules_map.copy()
for rid, r in c.items(): for rid, r in c.items():
if r.matches(window): if r.matches(window):
self.qtile.dgroups.remove_rule(rid) qtile.dgroups.remove_rule(rid)
self.initial_windows.remove((pid, gname)) self.initial_windows.remove((pid, gname))
self.log_info("Removed group rule for PID {}, window {}".format(pid, self.log_info("Removed group rule for PID {}, window {}".format(pid,
window.name)) window.name))
self.log_info(str(self.qtile.dgroups.rules_map)) self.log_info(str(qtile.dgroups.rules_map))
# Check if it is a visualizer # Check if it is a visualizer
if Config.get("show_audio_visualizer", False): if Config.get("show_audio_visualizer", False):
if client is not None and client.window.get_name() == "GLava": if client is not None and client.window.get_name() == "GLava":
placed = False placed = False
for screen in self.qtile.screens: for screen in qtile.screens:
for widget in screen.top.widgets: for widget in screen.top.widgets:
if not placed and isinstance(widget, kuro.utils.widgets.AudioVisualizerWidget): if not placed and isinstance(widget, kuro.utils.widgets.AudioVisualizerWidget):
if widget.client is None: if widget.client is None:
@ -693,10 +708,10 @@ class Kuro(BaseTheme):
pos_y = 0 + widget.margin_y pos_y = 0 + widget.margin_y
width = viz_info['width'] - (2 * widget.margin_x) width = viz_info['width'] - (2 * widget.margin_x)
height = viz_info['height'] - (2 * widget.margin_y) height = viz_info['height'] - (2 * widget.margin_y)
screen_index = self.qtile.screens.index(screen) screen_index = qtile.screens.index(screen)
logger.warning("Attaching {} {} to {} on screen {}".format(client, client.window.wid, type(widget).__name__, screen_index)) 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 = KuroStatic.create(client, screen, x=pos_x, y=pos_y, width=width, height=height)
c.set_opacity(Config.get("bar_opacity", 1.0)) c.opacity = Config.get("bar_opacity", 1.0)
widget.set_client(c, screen) widget.set_client(c, screen)
placed = True placed = True
if not placed: if not placed:
@ -722,11 +737,11 @@ class Kuro(BaseTheme):
# Detach visualizer from widget if it was a visualizer window # Detach visualizer from widget if it was a visualizer window
if isinstance(client, KuroStatic): if isinstance(client, KuroStatic):
for screen in self.qtile.screens: for screen in qtile.screens:
for widget in screen.top.widgets: for widget in screen.top.widgets:
if isinstance(widget, kuro.utils.widgets.AudioVisualizerWidget): if isinstance(widget, kuro.utils.widgets.AudioVisualizerWidget):
if widget.client == client: if widget.client == client:
screen_index = self.qtile.screens.index(screen) screen_index = qtile.screens.index(screen)
logger.warning("Detaching {} {} from widget {} on screen {}".format(client, client.window.wid, type(widget).__name__, screen_index)) logger.warning("Detaching {} {} from widget {} on screen {}".format(client, client.window.wid, type(widget).__name__, screen_index))
widget.client = None widget.client = None
widget.screen = None widget.screen = None
@ -876,7 +891,7 @@ class Kuro(BaseTheme):
# Update colors in visualizers and restart visualizers # Update colors in visualizers and restart visualizers
with open(Config.get("glava_color_file_path", "~/.config/glava/kurobars_color.glsl"), 'w') as f: 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:])) f.write("#define COLOR {}\n#request setbg {}00".format(colors['color15'], colors['color1'][1:]))
qtile.theme_instance.reinitialize_visualizers() qtile.theme_instance.reinitialize_visualizers()
utils.notify( utils.notify(

View file

@ -7,7 +7,7 @@ import notify2
import six import six
from dbus import DBusException from dbus import DBusException
from libqtile import widget from libqtile import widget
from libqtile.window import Internal from libqtile.backend.x11.window import Internal
from libqtile.bar import Bar from libqtile.bar import Bar
from notify2 import Notification, URGENCY_NORMAL from notify2 import Notification, URGENCY_NORMAL
from libqtile.log_utils import logger from libqtile.log_utils import logger

View file

@ -18,7 +18,7 @@ from libqtile.widget.currentlayout import CurrentLayoutIcon
from libqtile.widget.graph import _Graph from libqtile.widget.graph import _Graph
from libqtile.widget.tasklist import TaskList from libqtile.widget.tasklist import TaskList
from libqtile.widget.wlan import get_status from libqtile.widget.wlan import get_status
from libqtile.window import Window from libqtile.backend.x11.window import Window
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 call_process
@ -260,6 +260,7 @@ class MediaWidget(base.InLoopPollText):
('on_text_pause', '{}', 'The pattern for the text if music is paused.'), ('on_text_pause', '{}', 'The pattern for the text if music is paused.'),
('on_text_stop', '{}', 'The pattern for the text if music is stopped.'), ('on_text_stop', '{}', 'The pattern for the text if music is stopped.'),
('update_interval', 1, 'The update interval.'), ('update_interval', 1, 'The update interval.'),
('max_chars_per_player', 50, 'Maximum characters of text per player.'),
] ]
player_icons = { player_icons = {
@ -333,7 +334,7 @@ class MediaWidget(base.InLoopPollText):
def cmd_update_custom_player(self, player_name, data): def cmd_update_custom_player(self, player_name, data):
# Update firefox player # Update firefox player
if player_name == "firefox": if player_name.startswith("firefox"):
if data['playing'] and data['muted']: if data['playing'] and data['muted']:
self.custom_player_data['firefox']['showing'] = True self.custom_player_data['firefox']['showing'] = True
self.custom_player_data['firefox']['state'] = MediaWidget.Status.PAUSED self.custom_player_data['firefox']['state'] = MediaWidget.Status.PAUSED
@ -355,8 +356,11 @@ class MediaWidget(base.InLoopPollText):
players = [] players = []
# Playerctl players # Playerctl players
command = ["playerctl", "-l"] try:
result = self.call_process(command) result = self.call_process(["playerctl", "-l"])
except subprocess.CalledProcessError:
result = None
if result: if result:
players.extend([x for x in result.split("\n") if x]) players.extend([x for x in result.split("\n") if x])
@ -398,8 +402,14 @@ class MediaWidget(base.InLoopPollText):
text = "Unknown" text = "Unknown"
if cmd_result in ["Playing", "Paused"]: if cmd_result in ["Playing", "Paused"]:
try:
artist = self.call_process(['playerctl', '-p', player, 'metadata', 'artist']).strip() artist = self.call_process(['playerctl', '-p', player, 'metadata', 'artist']).strip()
except subprocess.CalledProcessError:
artist = None
try:
title = self.call_process(['playerctl', '-p', player, 'metadata', 'title']).strip() title = self.call_process(['playerctl', '-p', player, 'metadata', 'title']).strip()
except subprocess.CalledProcessError:
title = None
if artist and title: if artist and title:
text = "{} - {}".format(artist, title) text = "{} - {}".format(artist, title)
@ -419,13 +429,17 @@ class MediaWidget(base.InLoopPollText):
def _get_formatted_text(self, status): def _get_formatted_text(self, status):
if status[0] == MediaWidget.Status.PLAYING: if status[0] == MediaWidget.Status.PLAYING:
return self.on_text_play.format(status[1]) res = self.on_text_play.format(status[1])
elif status[0] == MediaWidget.Status.PAUSED: elif status[0] == MediaWidget.Status.PAUSED:
return self.on_text_pause.format(status[1]) res = self.on_text_pause.format(status[1])
elif status[0] == MediaWidget.Status.STOPPED: elif status[0] == MediaWidget.Status.STOPPED:
return self.on_text_stop.format(status[1]) res = self.on_text_stop.format(status[1])
else: else:
return "Unknown" res = "Unknown"
res = pangocffi.markup_escape_text(res)
if len(res) > self.max_chars_per_player:
res = res[:self.max_chars_per_player] + "..."
return res
def draw(self): def draw(self):
super(MediaWidget, self).draw() super(MediaWidget, self).draw()
@ -437,7 +451,12 @@ class MediaWidget(base.InLoopPollText):
return self.off_text return self.off_text
else: else:
for player in status.keys(): for player in status.keys():
icon = self.player_icons.get(player, player) # Shorten firefox.instance[0-9]+ to just firefox for icon finding
if player.startswith("firefox"):
player_icon = "firefox"
else:
player_icon = player
icon = self.player_icons.get(player_icon, player_icon)
text.append("{} {}".format(icon, self._get_formatted_text(status[player]))) text.append("{} {}".format(icon, self._get_formatted_text(status[player])))
return " | ".join(text) if text else self.off_text return " | ".join(text) if text else self.off_text

View file

@ -1,7 +1,6 @@
from cairocffi.test_xcb import xcffib from cairocffi.test_xcb import xcffib
from libqtile import hook from libqtile import hook
from libqtile.window import Window, Static from libqtile.backend.x11.window import Window, Static
class KuroStatic(Static): class KuroStatic(Static):