From 270f3e6d77cc720b1b3f3c529b1b6aa5c63578a2 Mon Sep 17 00:00:00 2001 From: Michael Kantor Date: Tue, 9 Jan 2024 22:02:20 -0500 Subject: Recreated git repo as screenshots were too large. --- config.py | 751 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 751 insertions(+) create mode 100644 config.py (limited to 'config.py') diff --git a/config.py b/config.py new file mode 100644 index 0000000..c783d75 --- /dev/null +++ b/config.py @@ -0,0 +1,751 @@ +import os +import time +import json +import psutil +import subprocess +from random import randint +from threading import Thread + +import cusmodules.holiday +#from cusmodules import holiday +#from cusmodules.cuswidgets import fifo_ticker_gecko +from cusmodules.cuswidgets import ticker_gecko +from typing import List # noqa: F401 +from libqtile import extension +from libqtile.lazy import lazy +from libqtile import layout, bar, widget, hook, qtile +from libqtile.config import Key, KeyChord, Screen, Group, Drag, Click, DropDown, ScratchPad, Match + +from libqtile.utils import send_notification + +from libqtile.core.manager import Qtile +from libqtile.backend.base import Window + +@hook.subscribe.startup_once +def autostart(): + home = os.path.expanduser('~') + holiday = cusmodules.holiday.main() + os.system(f'{home}/.config/qtile/cusmodules/wallpaper.py {holiday}') + subprocess.Popen(f'{home}/.config/qtile/autostart.sh') + +@hook.subscribe.shutdown +def shutdown(): + home = os.path.expanduser('~') + os.system(f"mpc -h {home}/.mpd/socket -p 6600 stop") + +mod = "mod4" +home = os.path.expanduser('~') +#term = 'st' +term = 'alacritty' +browser = 'librewolf' +privatebrowser = f'{browser} --private-window' +mpc = f"mpc -h {home}/.mpd/socket -p 6600" +pythonlogo = '/tmp/python.png' + +terms = ['st', 'kitty', 'cool-retro-term', 'Alacritty'] +terminal_windows = [] +swallowed_wins = [] + +pinned_wins = [] + +fast_swallowed = None + +def pyimage(home): + if os.path.isfile(pythonlogo): + return pythonlogo + + else: + return f'{home}/.config/qtile/pythonlogo.png' + +with open(f"{home}/.cache/wal/colors.json", 'r') as f: + data = json.load(f) + + color = data["colors"] + +def isWhite(color): + whites = [] + h = color.strip('#') + rgb = tuple(int(h[i:i+2], 16) for i in (0, 2, 4)) + + for i in rgb: + whites.append(i in range(235, 255)) + + if False in whites: + return False + + else: + return True + +def invColor(color): + inv = () + h = color.strip('#') + rgb = tuple(int(h[i:i+2], 16) for i in (0, 2, 4)) + + for i in rgb: + g = 255 % i + inv += (g,) + + invert = '%02x%02x%02x' % inv + invcolor = f"#{invert}" + + return invcolor + +def highlight(ogcolor): + h = color.get(ogcolor).strip('#') + rgb = tuple(int(h[i:i+2], 16) for i in (0, 2, 4)) + rgb1, rgb2, rgb3 = rgb + rgb1 = rgb1 +40 + rgb2 = rgb2 +40 + rgb3 = rgb3 +40 + rgb4 = (rgb1, rgb2, rgb3) + tohex = '%02x%02x%02x' % rgb4 + return tohex + +def inactive(ogcolor): + h = color.get(ogcolor).strip('#') + rgb = tuple(int(h[i:i+2], 16) for i in (0, 2, 4)) + rgb1, rgb2, rgb3 = rgb + rgb1 = rgb1 +64 + rgb2 = rgb2 +64 + rgb3 = rgb3 +64 + rgb4 = (rgb1, rgb2, rgb3) + tohex = '%02x%02x%02x' % rgb4 + tohex = '#' + tohex + return tohex + +layouts = [ + layout.MonadTall(margin = 10, border_focus = color.get('color14'), border_normal = color.get('color0')), + layout.Max(), + layout.Stack(margin = 6, border_focus = color.get('color14'), border_normal = color.get('color0'), num_stacks=1), + # Try more layouts by unleashing below layouts. + # layout.Bsp(margin = 10, border_focus = '#00FFFF'), + layout.Columns(margin = 6, border_focus = color.get('color14'), border_normal = color.get('color0')), + layout.Matrix(margin = 6, border_focus = color.get('color14'), border_normal = color.get('color0')), + layout.MonadWide(margin = 10, border_focus = color.get('color14'), border_normal = color.get('color0')), + # layout.RatioTile(), + # layout.Tile(), + layout.TreeTab(sections = [''], active_bg = color.get('color14'), inactive_bg = color.get('color8'), bg_color = color.get('color6')), + layout.Floating(border_focus = color.get('color14'), border_normal = color.get('color0')), + # layout.VerticalTile(), + # layout.Zoomy(), +] + +def reload_conf_cmd(qtile): + qtile.reload_config() + +def pin_win(qtile): + global pinned_wins + + if qtile.current_window in pinned_wins: + pass + + else: + pinned_wins.append(qtile.current_window) + #with open('/tmp/wins.dict', 'w') as f: + # f.write(str(qtile.current_window)) + +def unpin_win(qtile): + global pinned_wins + + pinned_wins.remove(qtile.current_window) + +def move_floating(qtile, xMod, yMod): + x = qtile.current_window.get_position()[0] + xMod + y = qtile.current_window.get_position()[1] + yMod + + qtile.current_window.set_position_floating(x, y) + + with open('/tmp/wins.dict', 'w') as f: + f.write(str(qtile.current_window.get_position())) + +def resize_floating(qtile, xMod, yMod): + x = qtile.current_window.get_size()[0] + xMod + y = qtile.current_window.get_size()[1] + yMod + + qtile.current_window.set_size_floating(x, y) + #qtile.current_window.resize_floating(1, 1) + +def fast_swallow(qtile): + #global fast_swallowed + + #qtile.current_window = fast_swallowed + #with open('/tmp/test.txt', 'w') as f: + #f.write(str(dir(qtile.groups))) + #f.write(str(dir(qtile.groups[10].windows))) + #f.write(str(qtile.groups[10].windows)) + #f.write(str(qtile.groups().get('swallow'))) + + qtile.current_window.togroup('swallow') + #qtile.current_window.hide() + +def fast_unswallow(qtile): + + for i in qtile.groups[10].windows: + i.togroup(qtile.current_group.name) + +def cycle_float(qtile, direc): + pass +# floating_wins = [] +# +# for window in qtile.current_group.windows: +# if window.floating: +# floating_wins.append(window) +# +# if not floating_wins: +# return +# +# try: +# win = floating_wins[floating_wins.index(qtile.current_window) + direc] +# win.focus() +# +# except: +# pass + +@hook.subscribe.setgroup +def move_pin(): + global pinned_wins + global qtile + + for i in pinned_wins: + name = i.info()['name'] + + #if name in qtile.groups().get('swallow').get('windows'): + # break + + i.togroup(str(qtile.current_group.name)) + + if 'mpv' in name: + i.disable_floating() + + #with open('/tmp/wins.dict', 'w') as f: + # f.write(str(qtile.groups().get('swallow').get('windows'))) + +@hook.subscribe.client_name_updated +def defloat_mpv(c): + name = c.info()['name'] + + if 'mpv' in name: + c.disable_floating() + +@hook.subscribe.client_killed +def un_swallow(c): + global terms + global pinned_wins + global terminal_windows + global swallowed_wins + + if c in pinned_wins: + pinned_wins.remove(c) + + if name in terms: + for i in terminal_windows: + if c in i.values(): + terminal_windows.remove(i) + #with open('/tmp/wins.dict', 'w') as f: + # f.write(str(terminal_windows)) + + else: + for i in swallowed_wins: + if c in i.values(): + win_to_deswallow = i.get('swallowed') + + win_to_deswallow.togroup(c.info()['group']) + + swallowed_wins.remove(i) + + +@hook.subscribe.client_managed +def swallow(c): + global term + global terms + global terminal_windows + global swallowed_wins + + if str(c.get_wm_type()) == 'dialog': + return 0 + + name = c.info()['name'] + with open('/tmp/wins.dict', 'w') as f: + f.write(name) + + #with open('/tmp/test.fifo', 'r') as f: + # f.write(name) + + if 'mpv' in name: + c.disable_floating() + + pid = c.window.get_net_wm_pid() + + if pid == None: + pid = os.popen(f'pidof {name}').read().strip('\n').split(' ') + pid = pid[0] + + term_pids = os.popen(f'pidof {term}').read().strip('\n').split(' ') + + pid = str(pid) + ppid = str(psutil.Process(psutil.Process(int(pid)).ppid()).ppid()) + + try: + if ppid in term_pids and ppid != 0: + with open('/tmp/wins.dict', 'w') as f: + f.write('skipping')#name))#.window.get_net_wm_pid())) + + else: + ppid = str(psutil.Process(int(ppid)).ppid()) + with open('/tmp/wins.dict', 'w') as f: + f.write(str(ppid))#name))#.window.get_net_wm_pid())) + + except Exception as e: + pass + #with open('/tmp/wins.dict', 'w') as f: + # f.write(str(ppid))#name))#.window.get_net_wm_pid())) + + if name in terms: + terminal_windows.append({pid:c}) + #os.system('kill -SIGKILL 84993') + #with open('/tmp/wins.dict', 'w') as f: + # f.write(str(terminal_windows))#name))#.window.get_net_wm_pid())) + + elif ppid == 1 or ppid == 0: + return 0 + + else: + for i in terminal_windows: + if str(ppid) in i.keys(): + swallowed_wins.append({'swallowed' : i.get(str(ppid)), + 'swallowed_by': c}) + + win_to_swall = i.get(str(ppid)) + + win_to_swall.togroup('swallow') + + #f.write(str(swallowed_wins))#.window.get_net_wm_pid())) + + else: + pass + + #with open('/tmp/wins.dict', 'w') as f: + # f.write(f"{type(pid)}: {pid}\n{type(ppid)}: {ppid}\n{terminal_windows}\n{swallowed_wins}") + + +keys = [ + # Switch between windows + Key([mod], "h", lazy.layout.left()), + Key([mod], "l", lazy.layout.right()), + + Key([mod], "k", lazy.layout.up()), + Key([mod], "j", lazy.layout.down()), + + + # Move windows up or down in current stack + Key([mod, "shift"], "h", lazy.layout.shuffle_left()), + Key([mod, "shift"], "l", lazy.layout.shuffle_right()), + + Key([mod, "shift"], "k", lazy.layout.shuffle_up()), + Key([mod, "shift"], "j", lazy.layout.shuffle_down()), + + Key([mod, "shift"], "space", lazy.layout.flip()), + + + # Grow and shrink windows + Key([mod, "control"], "k", lazy.layout.grow()), + Key([mod, "control"], "j", lazy.layout.shrink()), + + # Move between Groups + + Key([mod, "mod1"], "k", lazy.screen.next_group()), + Key([mod, "mod1"], "j", lazy.screen.prev_group()), + + # Sound + Key([], "XF86AudioMute", lazy.spawn("amixer -q set Master toggle")), + Key([], "XF86AudioLowerVolume", lazy.spawn("amixer -q sset 'Master' 2%- unmute")), + Key([], "XF86AudioRaiseVolume", lazy.spawn("amixer -q sset 'Master' 2%+ unmute")), + Key([], "XF86AudioPlay", lazy.spawn(f"{mpc} play")), + Key([], "XF86AudioPause", lazy.spawn(f"{mpc} pause")), + Key([], "XF86AudioPrev", lazy.spawn(f"{mpc} prev")), + Key([], "XF86AudioNext", lazy.spawn(f"{mpc} next")), + Key([mod], "m", lazy.spawn("amixer -q set Capture toggle"), lazy.spawn(f"{home}/.config/qtile/mic.sh")), + + Key([mod], "comma", lazy.spawn(f"{mpc} prev")), + Key([mod, "shift"], "comma", lazy.spawn(f"{mpc} seek 0%")), + + Key([mod], "period", lazy.spawn(f"{mpc} next")), + Key([mod, "shift"], "period", lazy.spawn(f"{mpc} repeat")), + + Key([mod, "shift"], "p", lazy.spawn(f"{mpc} toggle")), + + Key([mod], "bracketleft", lazy.spawn(f"{mpc} seek -10")), + Key([mod], "bracketright", lazy.spawn(f"{mpc} seek +10")), + + Key([mod, "shift"], "bracketleft", lazy.spawn(f"{mpc} seek -60")), + Key([mod, "shift"], "bracketright", lazy.spawn(f"{mpc} seek +60")), + + Key([mod, "control"], "bracketleft", lazy.spawn(f"{mpc} volume -5")), + Key([mod, "control"], "bracketright", lazy.spawn(f"{mpc} volume +5")), + + + # Toggle between different layouts as defined below + Key([mod], "Tab", lazy.next_layout()), + Key([mod, "shift"], "f", lazy.window.toggle_floating()), + Key([mod], "space", lazy.window.toggle_fullscreen()), + + # Close Windows + Key([mod], "w", lazy.window.kill()), + + # Qtile Actions + Key([mod, "control"], "r", lazy.restart()), + Key([mod, "control"], "q", lazy.shutdown()), + Key([mod], "b", lazy.hide_show_bar("top")), + + # Programs and misc actions + Key([mod], "Return", lazy.spawn(term)), + Key([mod], "c", lazy.spawn("xterm")), + + Key([mod], "p", lazy.spawn("dmenu_run -p 'Run:'")), + + Key([mod], "r", lazy.group['scratchpad'].dropdown_toggle('term')), + + #Key([mod, "control"], "p", lazy.group['vimpc'].dropdown_toggle('vimpc')), + + Key([mod], "i", lazy.spawn(f"{home}/.config/qtile/cusmodules/appimg.py")), + + Key([mod], "f", lazy.spawn(browser)), + + Key([mod, "shift"], "s", lazy.spawn("flameshot gui")), + + Key([mod, "control"], "f", lazy.spawn(privatebrowser)), + + Key([mod, "control"], "c", lazy.spawn(f"{home}/.config/qtile/cusmodules/colors.py")), + + Key([mod, "control"], "l", lazy.spawn(f'xautolock -locknow')), + Key([mod, "mod1"], "l", lazy.spawn(f'xautolock -toggle')), + + Key([mod, "control"], "n", lazy.spawn(home + "/.config/qtile/cusmodules/wallpaper.py")), + + Key([mod], "z", lazy.function(reload_conf_cmd)), + + Key([mod, 'control'], "z", lazy.function(fast_unswallow)), + + Key([mod, 'shift'], "z", lazy.function(fast_swallow)), + + Key([mod], "n", lazy.function(pin_win)), + + Key([mod, 'shift'], "n", lazy.function(unpin_win)), + + #KeyChord([mod], "x", [ + # Key([], "h", lazy.function(move_floating, -8, 0)), + # Key([], "j", lazy.function(move_floating, 0, 8)), + # Key([], "k", lazy.function(move_floating, 0, -8)), + # Key([], "l", lazy.function(move_floating, 8, 0)), + # Key(['shift'], "h", lazy.function(resize_floating, -8, 0)), + # Key(['shift'], "j", lazy.function(resize_floating, 0, 50)), + # Key(['shift'], "k", lazy.function(resize_floating, 0, -8)), + # Key(['shift'], "l", lazy.function(resize_floating, 50, 0)), + # Key([], "f", lazy.window.toggle_floating()), + # Key([], "period", lazy.function(cycle_float, 1)), + # Key([], "w", lazy.window.kill()), + #], + # name='Floating' + #) + #Key([mod], "y", lazy.window.togroup('scratchpad')), + + #Key([mod], "u", lazy.group['scratchpad'].toscreen()), + + #Key([mod], "x", lazy.function(pinned.append, lazy.window)), + +] + +group_names = [("I", {'layout': 'monadtall'}), + ("II", {'layout': 'monadtall'}), + ("III", {'layout': 'monadtall'}), + ("IV", {'layout': 'monadtall'}), + ("V", {'layout': 'monadtall'}), + ("VI", {'layout': 'monadtall'}), + ("VII", {'layout': 'monadtall'}), + ("VIII", {'layout': 'monadtall'}), + ("IX", {'layout': 'monadtall'})] + +groups = [Group(name, **kwargs) for name, kwargs in group_names] + +groups.append(ScratchPad('swallow')) + +groups.append(ScratchPad('hidden')) + +groups.append(ScratchPad("scratchpad", [ DropDown("term", term, opacity=1) ])) + +groups.append(ScratchPad("vimpc", [ DropDown("vimpc", f"{term} -e vimpc -h {home}/.mpd/socket -p 6600", opacity=1) ])) + +groups.append(Group("X")) + +for i, (name, kwargs) in enumerate(group_names, 1): + keys.append(Key([mod], str(i), lazy.group[name].toscreen())) # Switch to another group + keys.append(Key([mod, "shift"], str(i), lazy.window.togroup(name))) # Send current window to another group + keys.append(Key([mod, "control"], str(i), lazy.window.togroup(name), lazy.group[name].toscreen())) # Send current window to another group + + +keys.append(Key([mod], 'u', lazy.group['swallow'].toscreen())) +keys.append(Key([mod, 'shift'], 'u', lazy.window.togroup('swallow'))) +keys.append(Key([mod, "control"], 'u', lazy.window.togroup("swallow"), lazy.group["swallow"].toscreen())) # Send current window to another group + +keys.append(Key([mod], 'y', lazy.group['hidden'].toscreen())) +keys.append(Key([mod, 'shift'], 'y', lazy.window.togroup('hidden'))) +keys.append(Key([mod, "control"], 'y', lazy.window.togroup("hiddden"), lazy.group["hidden"].toscreen())) # Send current window to another group + +keys.append(Key([mod], '0', lazy.group['X'].toscreen())) +keys.append(Key([mod, 'shift'], '0', lazy.window.togroup('X'))) +keys.append(Key([mod, "control"], '0', lazy.window.togroup('X'), lazy.group['X'].toscreen())) # Send current window to another group + +widget_defaults = { + 'font': 'Nimbus Sans', + 'fontsize': 13, + 'padding': 2, +} + +extension_defaults = widget_defaults.copy() + +lar = u'\ue0b2' +rar = u'\ue0b0' +plf = "Powerline Symbols" + +screens = [ + Screen( + top=bar.Bar( + [ + widget.Image( + filename = pyimage(home), + background = color.get('color7'), + margin = 2, + ), + + widget.TextBox( + text=rar, + background = color.get('color0'), + foreground = color.get('color7'), + font = plf, + padding = 0, + fontsize = 23 + ), + + widget.GroupBox( + margin_y = 6, + margin_x = 0, + padding_y = 5, + padding_x = 3, + borderwidth = 3, + active = '#ffffff', + inactive = inactive('color0'), + rounded = False, + highlight_method = "line", + highlight_color = [color.get('color0').strip('#'), highlight('color0')], + background = color.get('color0'), + this_current_screen_border = color.get('color6'), + ), + + widget.TextBox( + text=rar, + foreground = color.get('color0'), + font = plf, + padding = 0, + fontsize = 23 + ), + + widget.Spacer( + length=550 + ), + + widget.TextBox( + text=u'\ue0ba', + foreground = color.get('color0'), + padding = -0.5, + fontsize = 26 + ), + + widget.Mpd2( + host=f"{home}/.mpd/socket", + status_format='{play_status} {artist} - {title} [{elapsed}/{duration}] | {volume}%', + background = color.get('color0') + ), + + widget.TextBox( + text=u'\ue0bc', + foreground = color.get('color0'), + padding = -0.5, + fontsize = 26 + ), + + widget.Spacer(), + + widget.TextBox( + text=lar, + foreground = color.get('color6'), + font = plf, + padding = -0.5, + fontsize = 23, + ), + + widget.Systray( + background = color.get('color6'), + icon_size = 15), + + widget.TextBox( + text = lar, + background = color.get('color6'), + foreground = color.get('color8'), + font = plf, + padding = -0.5, + fontsize = 23 + ), + + widget.Volume( + background= color.get('color8'), + ), + + widget.Volume( + emoji = True, + background= color.get('color8'), + ), + + widget.Volume( + fmt= ' {} 🎙️', + channel='Capture', + background= color.get('color8'), + ), + + widget.TextBox( + text=lar, + background= color.get('color8'), + foreground = color.get('color6'), + font = plf, + padding = -0.5, + fontsize = 23 + ), + + widget.GenPollText( + func=ticker_gecko.main, + update_interval= 0.5, + foreground = invColor(color.get('color6')) if isWhite(color.get('color6')) else '#FFFFFF', + background = color.get('color6'), + ), + + widget.TextBox( + text = '🪙', + background = color.get('color6'), + ), + + widget.TextBox( + text=lar, + background = color.get('color6'), + foreground = color.get('color8'), + font = plf, + padding = -0.5, + fontsize = 23 + ), + + widget.Memory( + fmt = "{} 💾", + background = color.get('color8'), + ), + + widget.TextBox( + text=lar, + background= color.get('color8'), + foreground = color.get('color6'), + font = plf, + padding = -0.5, + fontsize = 23 + ), + + widget.CPU( + fmt = '{} 💻', + foreground = invColor(color.get('color6')) if isWhite(color.get('color6')) else '#FFFFFF', + background = color.get('color6'), + ), + + widget.TextBox( + text=lar, + background = color.get('color6'), + foreground = color.get('color8'), + font = plf, + padding = -0.5, + fontsize = 23 + ), + + widget.Net( + format= '{down:6.2f}{down_suffix} ⬇️ {up:6.2f}{up_suffix} ⬆️ ', + background = color.get('color8'), + ), + + widget.TextBox( + text=lar, + background = color.get('color8'), + foreground = color.get('color6'), + font = plf, + padding = -0.5, + fontsize = 23 + ), + + widget.Clock( + background = color.get('color6'), + foreground = invColor(color.get('color6')) if isWhite(color.get('color6')) else '#FFFFFF', + format='%m-%d-%Y %a 📅 %I:%M:%S %p 🕒') + ], + 23, + background = (0, 0, 0, 0), + ), + ), +] + +# Drag floating layouts. +mouse = [ + Drag([mod], "Button1", lazy.window.set_position_floating(), + start=lazy.window.get_position()), + Drag([mod], "Button3", lazy.window.set_size_floating(), + start=lazy.window.get_size()), + Click([mod], "Button2", lazy.window.bring_to_front()) +] + +main = None +dgroups_key_binder = None +dgroups_app_rules = [] # type: List +follow_mouse_focus = True +bring_front_click = False +cursor_warp = False +floating_layout = layout.Floating(float_rules=[ + # Run the utility of `xprop` to see the wm class and name of an X client. + *layout.Floating.default_float_rules, + Match(wm_class='confirmreset'), + Match(wm_class='makebranch'), + Match(wm_class='maketag'), + Match(wm_class='ssh-askpass'), + Match(title='branchdialog'), + Match(title='pinentry'), + Match(title='xsnow'), + #{'wmclass': 'confirm'}, + #{'wmclass': 'dialog'}, + #{'wmclass': 'main.py'}, + #{'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 + #{'wname': 'dialog'}, + #{'wmclass': 'ssh-askpass'}, # ssh-askpass +]) +auto_fullscreen = True +focus_on_window_activation = "smart" + +# 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" -- cgit v1.2.1