Refactor usage of qtile object and improvements to media widget

This commit is contained in:
Kevin Alberts 2021-11-22 20:47:16 +01:00
parent 8f4f08e3bf
commit 0f4ef9190a
Signed by: Kurocon
GPG key ID: BCD496FEBA0C6BC1
4 changed files with 62 additions and 36 deletions

View file

@ -127,8 +127,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

@ -19,7 +19,7 @@ class Config(BaseConfig):
app_launcher = "/home/kevin/bin/dmenu_wal.sh" app_launcher = "/home/kevin/bin/dmenu_wal.sh"
web_browser = "firefox-developer-edition" web_browser = "firefox-developer-edition"
file_manager = "thunar" file_manager = "thunar"
app_chat = "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"

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...")
@ -89,7 +89,7 @@ class Kuro(BaseTheme):
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):
@ -496,22 +496,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:
@ -554,13 +554,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()
@ -573,7 +580,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()
@ -612,9 +619,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
@ -628,12 +639,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
@ -641,27 +652,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:
@ -670,10 +681,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:
@ -692,7 +703,6 @@ class Kuro(BaseTheme):
client.window.togroup("") client.window.togroup("")
def callback_client_killed(self, *args, **kwargs): def callback_client_killed(self, *args, **kwargs):
client = args[0] client = args[0]
logger.warning("Client {} Killed".format(client)) logger.warning("Client {} Killed".format(client))
@ -853,7 +863,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

@ -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"]:
artist = self.call_process(['playerctl', '-p', player, 'metadata', 'artist']).strip() try:
title = self.call_process(['playerctl', '-p', player, 'metadata', 'title']).strip()[:50] 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()
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