Last active
February 7, 2024 20:31
-
-
Save TauPan/9c09bd9defc5ac3c9e06 to your computer and use it in GitHub Desktop.
Revisions
-
TauPan revised this gist
Feb 18, 2021 . 1 changed file with 215 additions and 69 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,16 +1,30 @@ # -*- coding: utf-8 -*- import distutils.spawn import os import re import socket import subprocess import xcffib.xproto from libqtile import layout, bar, widget, hook from libqtile.command import lazy from libqtile.config import Key, Screen, Group, Drag, Click # copied from libqtile/resources/default_config.py and adapted by me mod = "mod4" def hostname(): return socket.gethostname() gemini = (hostname == 'gemini') laptop = os.path.exists('/sys/class/power_supply/BAT0/status') # thanks to rogerduran for the implementation of my idea (borrowed # from stumpwm) class PrevFocus(object): @@ -37,7 +51,7 @@ def on_focus(self, window): group_focus["current"] = window def __call__(self, qtile): group = qtile.current_group group_focus = self.groups_focus.get(group.name, {"prev": None}) prev = group_focus["prev"] if prev and group.name == prev.group.name: @@ -62,7 +76,7 @@ def callback(qtile): windows = windows_matching_shuffle(qtile, **kwargs) if windows: window = windows[0] qtile.current_screen.set_group(window.group) window.group.focus(window, False) window.focus(window, False) @@ -80,10 +94,10 @@ def callback(qtile): windows = windows_matching_shuffle(qtile, **kwargs) if windows: window = windows[0] if window.group != qtile.current_group: if window.group.screen: qtile.cmd_to_screen(window.group.screen.index) qtile.current_screen.set_group(window.group) window.group.focus(window, False) return lazy.function(callback) @@ -93,8 +107,8 @@ def callback(qtile): def make_sticky(qtile, *args): window = qtile.current_window screen = qtile.current_screen.index window.static( screen, window.x, @@ -104,7 +118,6 @@ def make_sticky(qtile, *args): def pull_window_here(**kwargs): """pull the matched window to the current group and focus it matching behaviour is the same as in switch_to @@ -113,8 +126,8 @@ def callback(qtile): windows = windows_matching_shuffle(qtile, **kwargs) if windows: window = windows[0] window.togroup(qtile.current_group.name) qtile.current_group.focus(window, False) return lazy.function(callback) @@ -126,16 +139,16 @@ def windows_matching_shuffle(qtile, **kwargs): windows = sorted( [ w for w in qtile.windows_map.values() if w.group and window_match_re(w, **kwargs)], key=lambda ww: ww.window.wid) idx = 0 if qtile.current_window is not None: try: idx = windows.index(qtile.current_window) idx += 1 except ValueError: pass if idx >= len(windows): idx = 0 return windows[idx:] + windows[:idx] @@ -185,40 +198,73 @@ def modifier_window_commands(match, spawn, *keys): for key in keys] TERM_PREFS = [ ('st', 'st.*', '-e'), ('gnome-terminal', 'gnome-terminal-server', '--'), # assuming urxvtd has been run from .xsession: ('urxvtc', 'URxvt', '-e'), # Keybindings in shell are broken because of Meta-d opening a # menu, etc. ('xfce4-terminal', 'xfce4-terminal', '-x'), # Seems to break the terminal for weechat permanently: ('alacritty', 'Alacritty', '-e') ] # See https://stackoverflow.com/questions/377017/test-if-executable-exists-in-python/12611523#12611523 # noqa for term_exec, term_class, term_cmd_prefix in TERM_PREFS: if distutils.spawn.find_executable(term_exec): break keys = ( modifier_window_commands( {'wmclass': term_class}, f"{term_exec} {term_cmd_prefix} tmux -2 new-session -A -s {os.environ.get('TMUX_MAIN_SESSION', '0')} \\; set-window-option -q allow-rename on \\; set-window-option -q automatic-rename on", # noqa 'a', '1') # I used to use Aterm + modifier_window_commands( {'wmclass': "Emacs"}, "em", 'e', '2') # Emacs + modifier_window_commands( {'role': "browser"}, "google-chrome --remote-debugging-port=9222", 'g', '3') # Galeon used to be my browser + modifier_window_commands( {"wmname": ".*pdf$", "wmclass": "(Evince|Acroread|Xpdf|Okular)"}, "evince", 'd') # pDf + modifier_window_commands( {"wmclass": "jetbrains-pycharm"}, "/afs/dfn-cert.de/pet/software/bin/pycharm.sh", "c", '4') # pyCharm + modifier_window_commands( {"wmclass": "dolphin"}, "dolphin", "p") # dolpPhin + modifier_window_commands( {'wmclass': "Thunderbird"}, "thunderbird", 'z') # used to be: chatZilla is started from firefox but I # (normally) don't use firefox for anything else # # since chatZilla is not supported any more, I use thunderbird # chat for IRC + modifier_window_commands( {'wmclass': "Claws-mail"}, "claws-mail", 'm') # claws-Mail + modifier_window_commands( {'wmclass': "keepassxc"}, "keepassxc", 'k') # keepassxc + modifier_window_commands( {'wmclass': "TelegramDesktop"}, "Telegram", 't') # Telegram + [ Key( [mod, "control", "shift"], "Return", lazy.spawn("sh -c 'screen -S tmuxttyS0 -X kill ; (i3lock --ignore-empty-password --show-failed-attempts --tiling --image ~/Bilder/OrionWF1920x1200.png || xlock -mode blank); while pgrep \"(xlock|i3lock)\"; do sleep 2; done; tmux-on-serial'")), # Switch between windows in current stack pane Key( @@ -232,11 +278,13 @@ def modifier_window_commands(match, spawn, *keys): Key( [mod], "Left", lazy.layout.next(), lazy.layout.left() ), Key( [mod], "Right", lazy.layout.previous(), lazy.layout.right() ), # Move windows in current stack pane -> I'd like to have this, but @@ -252,31 +300,42 @@ def modifier_window_commands(match, spawn, *keys): Key( [mod, "shift"], "Left", lazy.layout.client_to_previous(), lazy.layout.shuffle_left() ), Key( [mod, "shift"], "Right", lazy.layout.client_to_next(), lazy.layout.shuffle_right() ), # resize columns Key( [mod, "control", "shift"], "Down", lazy.layout.grow_down() ), Key( [mod, "control", "shift"], "Up", lazy.layout.grow_up() ), Key( [mod, "control", "shift"], "Left", lazy.layout.grow_left() ), Key( [mod, "control", "shift"], "Right", lazy.layout.grow_right() ), # Switch window focus to other pane(s) of stack Key( [mod], "Tab", lazy.layout.previous() ), Key( [mod, "shift"], "Tab", lazy.layout.next() ), # Swap panes of split stack @@ -295,37 +354,97 @@ def modifier_window_commands(match, spawn, *keys): ), Key([mod], "Return", lazy.spawn("xterm")), Key( [mod, "shift"], "plus", lazy.layout.add_column() ), Key( [mod, "shift"], "minus", lazy.layout.remove_column() ), Key( [mod], "n", lazy.layout.normalize ), # Toggle between different layouts as defined below Key([mod], "space", lazy.next_layout()), Key([mod, "shift"], "space", lazy.prev_layout()), Key([mod, "control"], "r", lazy.restart()), Key([mod, "control"], "q", lazy.shutdown()), Key([mod, "shift"], "r", lazy.spawncmd()), Key([mod], "r", lazy.spawn("rofi -show-icons -show combi")), Key([mod], "x", lazy.qtilecmd()), Key([mod], "b", lazy.hide_show_bar()), Key([mod, "control"], "Delete", lazy.window.kill()), # Key([mod], "w", lazy.window.kill()), Key([mod], "y", lazy.function(PrevFocus())), Key([mod, "control"], "Left", lazy.prev_screen()), Key([mod, "control"], "Right", lazy.next_screen()), Key([mod, "control"], "f", lazy.window.toggle_floating()), Key([mod], "f", lazy.window.toggle_fullscreen()), Key([mod], "comma", lazy.window.toggle_minimize()), Key([mod], "period", lazy.window.toggle_maximize()), Key([mod], "s", lazy.spawn("rofi -show-icons -show window")), # not focusable or managable any more, use with caution Key([mod, "control"], "s", lazy.function(make_sticky)), Key([mod, "mod1"], "s", lazy.spawn("sudo -n pm-suspend-hybrid")), Key([mod, "control", "mod1"], "s", lazy.spawn("sudo pm-suspend")), Key(["mod1", "mod4"], "Scroll_Lock", lazy.spawn("/usr/bin/env bash -c '" "autorandr --change; " "setxkbmap -variant basic; " "xmodmap ~/.Xmodmap; xmodmap ~/.Xmodmap.$(hostname)" "'"), lazy.restart()), Key([mod], "odiaeresis", lazy.spawn("playerctl previous")), Key([mod], "adiaeresis", lazy.spawn("playerctl next")), Key([mod], "numbersign", lazy.spawn("playerctl play-pause")), Key(["mod1", "mod4"], 'a', lazy.next_urgent()), Key(["control", "mod1", "mod4"], 'a', lazy.cmd_simulate_keypress([mod], "a")) ] ) if gemini: keys.extend([ Key(["mod5"], "b", lazy.spawn("gemini-brightness -")), Key(["mod5"], "n", lazy.spawn("gemini-brightness +")), Key([], "XF86MonBrightnessDown", lazy.spawn("gemini-brightness -")), Key([], "XF86MonBrightnessUp", lazy.spawn("gemini-brightness +")), Key(["mod5"], "XF86MonBrightnessDown", lazy.spawn("gemini-brightness -")), Key(["mod5"], "XF86MonBrightnessUp", lazy.spawn("gemini-brightness +")), Key(["mod5"], "c", lazy.spawn( "/usr/bin/env bash -c 'aumix -v -||amixer sset Master 1%-'")), Key(["mod5"], "v", lazy.spawn( "/usr/bin/env bash -c 'aumix -v +||amixer sset Master 1%+'")), Key([], "XF86AudioLowerVolume", lazy.spawn( "/usr/bin/env bash -c 'aumix -v -||amixer sset Master 1%-'")), Key([], "XF86AudioRaiseVolume", lazy.spawn( "/usr/bin/env bash -c 'aumix -v +||amixer sset Master 1%+'")), ]) else: keys.extend([ Key([mod], "minus", lazy.spawn( "/usr/bin/env bash -c 'aumix -v -||amixer sset Master 1%-'")), Key([mod], "plus", lazy.spawn( "/usr/bin/env bash -c 'aumix -v +||amixer sset Master 1%+'")), ]) groups = [Group(i, persist=(int(i) < 4), init=(int(i) < 4)) for i in "12345678"] @@ -342,39 +461,58 @@ def modifier_window_commands(match, spawn, *keys): layouts = [ layout.Max(), layout.Columns(name="Columns", num_columns=2, fair=True), layout.RatioTile(), layout.Floating() ] if gemini: widget_defaults = dict( font='Bitstream Vera Sans', fontsize=23, padding=1, ) else: widget_defaults = dict( font='Bitstream Vera Sans', fontsize=16, padding=3, ) def _barstart(): return [ widget.GroupBox(this_current_screen_border='00FF00'), widget.Prompt(), # widget.WindowName(), # either this # or this, not both!: widget.TaskList(highlight_method='block', # I need this for windows without icons: unfocused_border='#333333'), widget.Sep(), # widget.TextBox("Friedel's config", name="config"), ] def _barend(): ret = [ # widget.TextBox("Vol", name="volume_label"), widget.Volume(fmt=" {}", emoji=True, volume_app="pavucontrol"), widget.Volume(volume_app="pavucontrol"), # widget.PulseVolume(volume_app="pavucontrol") ] if laptop: ret += [ widget.BatteryIcon(), widget.Battery(format='{percent:2.0%} {hour:d}:{min:02d}'), ] ret += [ widget.CurrentLayoutIcon(), widget.CurrentLayout(markup=True, fontsize=20, fontshadow='0000FF'), widget.Sep(), widget.Clock(format='🕒 %Y-%m-%d %a %H:%M:%S'), ] return ret screens = [ Screen( @@ -416,6 +554,7 @@ def _barend(): cursor_warp = False floating_layout = layout.Floating() auto_fullscreen = True focus_on_window_activation = "smart" # "never" is also possible # 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 @@ -430,20 +569,21 @@ def _barend(): # see # http://docs.qtile.org/en/latest/manual/faq.html#my-pointer-mouse-cursor-isn-t-the-one-i-expect-it-to-be # noqa # see https://wiki.dfn-cert.de/cgi-bin/wiki.pl/Workstations15.1Not_WorkingYet#toc15 @hook.subscribe.startup def runner(): subprocess.Popen(['xsetroot', '-cursor_name', 'left_ptr']) # prevent xfce4-notifyd windows from jumping around by ignoring them @hook.subscribe.client_new def auto_sticky(window): if window.name == "xfce4-notifyd": if window.group: screen = window.group.screen.index else: screen = window.qtile.current_screen.index window.window.configure(stackmode=xcffib.xproto.StackMode.Above) window.static(screen) @@ -460,7 +600,13 @@ def floating_dialogs(window): @hook.subscribe.client_new def float_plasma(window): if window and window_match_re(window, wmclass="plasmashell"): window.floating = True # from https://github.com/ramnes/qtile-config/blob/98e097cfd8d5dd1ab1858c70babce141746d42a7/config.py#L108 @hook.subscribe.screen_change def set_screens(qtile, event): if not os.path.exists(os.path.expanduser('~/NO-AUTORANDR')): subprocess.run(["autorandr", "--change"]) qtile.cmd_restart() -
TauPan revised this gist
Aug 24, 2017 . 1 changed file with 6 additions and 3 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -123,9 +123,12 @@ def windows_matching_shuffle(qtile, **kwargs): """return a list of windows matching window_match_re with **kwargs, ordered so that the current Window (if it matches) comes last """ windows = sorted( [ w for w in qtile.windowMap.values() if w.group and window_match_re(w, **kwargs)], key=lambda ww: ww.window.wid) idx = 0 if qtile.currentWindow is not None: try: -
TauPan revised this gist
Aug 24, 2017 . 1 changed file with 29 additions and 6 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -88,6 +88,7 @@ def callback(qtile): return lazy.function(callback) switch_window = window_switch_to_screen_or_pull_group @@ -180,28 +181,37 @@ def modifier_window_commands(match, spawn, *keys): for mods, command in mapping for key in keys] keys = ( modifier_window_commands( {'wmclass': "URxvt"}, "urxvtc -e tmux -2 new-session -A -s {} \; set-window-option -q allow-rename on \; set-window-option -q automatic-rename on".format( os.environ.get('TMUX_MAIN_SESSION', '0')), 'a', '1') # I used to use Aterm + modifier_window_commands( {'wmclass': "Emacs"}, "em", 'e', '2') # Emacs + modifier_window_commands( {'role': "browser"}, "chromium --remote-debugging-port=9222", 'g', '3') # Galeon used to be my browser + modifier_window_commands( {"wmname": ".*pdf$", "wmclass": "(Evince|Acroread|Xpdf|Okular)"}, "evince", 'd') # pDf + modifier_window_commands( {"wmclass": "jetbrains-pycharm"}, "/afs/dfn-cert.de/pet/software/pycharm/pycharm-2016.3/bin/pycharm.sh", "c", '4') # pyCharm + modifier_window_commands( {"wmclass": "Dolphin"}, "dolphin", "p") # dolpPhin + [ Key( [mod, "control", "shift"], "Return", lazy.spawn("sh -c 'screen -S tmuxttyS0 -X kill ; xlock -mode blank || xscreensaver-command -lock'")), Key( [mod, "control"], "y", @@ -362,6 +372,7 @@ def _barend(): widget.Clock(format='%Y-%m-%d %a %H:%M:%S'), ] screens = [ Screen( bottom=bar.Bar( @@ -422,6 +433,18 @@ def runner(): subprocess.Popen(['xsetroot', '-cursor_name', 'left_ptr']) # prevent xfce4-notifyd windows from jumping around by ignoring them @hook.subscribe.client_new def auto_sticky(window): if window.name == "xfce4-notifyd": if window.group: screen = window.group.screen.index else: screen = window.qtile.currentScreen.index window.window.configure(stackmode=xcffib.xproto.StackMode.Above) window.static(screen) # from http://qtile.readthedocs.org/en/latest/manual/config/hooks.html#automatic-floating-dialogs @hook.subscribe.client_new def floating_dialogs(window): -
TauPan renamed this gist
Jun 12, 2017 . 1 changed file with 0 additions and 0 deletions.There are no files selected for viewing
File renamed without changes. -
TauPan revised this gist
Jun 12, 2017 . 1 changed file with 196 additions and 171 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,3 +1,4 @@ import os import re from libqtile.config import Key, Screen, Group, Drag, Click @@ -63,11 +64,46 @@ def pull_window_group_here(**kwargs): window = windows[0] qtile.currentScreen.setGroup(window.group) window.group.focus(window, False) window.focus(window, False) return lazy.function(callback) def window_switch_to_screen_or_pull_group(**kwargs): """If the group of the window matched by match_window_re with the given **kwargs is in a visible on another screen, switch to the screen, otherwise pull the group to the current screen """ def callback(qtile): windows = windows_matching_shuffle(qtile, **kwargs) if windows: window = windows[0] if window.group != qtile.currentGroup: if window.group.screen: qtile.cmd_to_screen(window.group.screen.index) qtile.currentScreen.setGroup(window.group) window.group.focus(window, False) return lazy.function(callback) switch_window = window_switch_to_screen_or_pull_group def make_sticky(qtile, *args): window = qtile.currentWindow screen = qtile.currentScreen.index window.static( screen, window.x, window.y, window.width, window.height) def pull_window_here(**kwargs): """pull the matched window to the current group and focus it matching behaviour is the same as in switch_to @@ -129,175 +165,153 @@ def window_match_re(window, wmname=None, wmclass=None, role=None): return False return ret def modifier_window_commands(match, spawn, *keys): # Use switch_window by default (just mod) # Use pull_window_here with additional ctrl # spawn new window with additional shift # Use pull_window_group_here with additional shift (mod, "shift", "control") mapping = ( ([mod], switch_window(**match)), ([mod, "control"], pull_window_here(**match)), ([mod, "shift"], lazy.spawn(spawn)), ([mod, "shift", "control"], pull_window_group_here(**match))) return [Key(mods, key, command) for mods, command in mapping for key in keys] keys = ( modifier_window_commands( {'wmclass': "URxvt"}, "urxvtc -e tmux -2 new-session -A -s {}".format( os.environ.get('TMUX_MAIN_SESSION', '0')), 'a', '1') + modifier_window_commands( {'wmclass': "Emacs"}, "em", 'e', '2') + modifier_window_commands( {'role': "browser"}, "chromium --remote-debugging-port=9222", 'g', '3') + modifier_window_commands( {"wmname": ".*pdf$", "wmclass": "(Evince|Acroread|Xpdf|Okular)"}, "evince", 'd') + [ Key( [mod, "control", "shift"], "Return", lazy.spawn("xscreensaver-command -lock")), Key( [mod, "control"], "y", lazy.spawn("keepass2 --auto-type")), # Switch between windows in current stack pane Key( [mod], "Down", lazy.layout.down() ), Key( [mod], "Up", lazy.layout.up() ), Key( [mod], "Left", lazy.layout.previous() ), Key( [mod], "Right", lazy.layout.next() ), # Move windows in current stack pane -> I'd like to have this, but # move_* commands do not exist Key( [mod, "shift"], "Down", lazy.layout.shuffle_down() ), Key( [mod, "shift"], "Up", lazy.layout.shuffle_up() ), Key( [mod, "shift"], "Left", lazy.layout.client_to_previous() ), Key( [mod, "shift"], "Right", lazy.layout.client_to_next() ), # Move windows up or down in current stack Key( [mod, "control"], "k", lazy.layout.shuffle_down() ), Key( [mod, "control"], "j", lazy.layout.shuffle_up() ), # Switch window focus to other pane(s) of stack Key( [mod], "Tab", lazy.layout.next() ), Key( [mod, "shift"], "Tab", lazy.layout.previous() ), # Swap panes of split stack Key( [mod, "control"], "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( [mod, "shift"], "Return", lazy.layout.toggle_split() ), Key([mod], "Return", lazy.spawn("xterm")), # Toggle between different layouts as defined below Key([mod], "space", lazy.next_layout()), Key([mod, "shift"], "space", lazy.prev_layout()), Key([mod, "control"], "r", lazy.restart()), Key([mod, "control"], "q", lazy.shutdown()), Key([mod], "r", lazy.spawncmd()), Key([mod], "x", lazy.qtilecmd()), Key([mod], "b", lazy.hide_show_bar()), Key([mod, "control"], "Delete", lazy.window.kill()), # Key([mod], "w", lazy.window.kill()), Key([mod], "minus", lazy.spawn( "/usr/bin/env bash -c 'aumix -v -||amixer sset Master 1%-'")), Key([mod], "plus", lazy.spawn( "/usr/bin/env bash -c 'aumix -v +||amixer sset Master 1%+'")), Key([mod], "y", lazy.function(PrevFocus())), Key([mod, "control"], "Left", lazy.prev_screen()), Key([mod, "control"], "Right", lazy.next_screen()), Key([mod, "control"], "f", lazy.window.toggle_floating()), Key([mod], "f", lazy.window.toggle_fullscreen()), # not focusable or managable any more, use with caution Key([mod, "control"], "s", lazy.function(make_sticky)), Key(["shift"], "Scroll_Lock", lazy.spawn("xmodmap ~/.Xmodmap")) ] ) groups = [Group(i, persist=(int(i) < 4), init=(int(i) < 4)) for i in "12345678"] @@ -343,8 +357,6 @@ def _barend(): widget.TextBox("Vol", name="volume_label"), widget.Volume(), widget.BatteryIcon(), widget.CurrentLayout(markup=True, fontsize=20, fontshadow='0000FF'), widget.Sep(), widget.Clock(format='%Y-%m-%d %a %H:%M:%S'), @@ -360,12 +372,17 @@ screens = [ widget.MemoryGraph(), widget.TextBox("N", name="net_label"), widget.NetGraph(), widget.Systray(), widget.Sep(), ] + _barend(), 30)), Screen( bottom=bar.Bar( _barstart() + [ widget.Sep() ] + _barend(), 30)) ] # Drag floating layouts. @@ -413,3 +430,11 @@ def floating_dialogs(window): bubble = window.window.get_wm_window_role() == 'bubble' if dialog or transient or bubble: window.floating = True @hook.subscribe.client_new def float_plasma(window): if window: plasma = window_match_re(window, wmclass="plasmashell") if plasma: window.floating = True -
TauPan renamed this gist
May 11, 2016 . 1 changed file with 141 additions and 44 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -46,7 +46,17 @@ class PrevFocus(object): # taken from # https://github.com/qtile/qtile-examples/blob/master/roger/config.py#L34 # and adapted def pull_window_group_here(**kwargs): """Switch to the *next* window matched by match_window_re with the given **kwargs If you have multiple windows matching the args, switch_to will cycle through them. (Those semantics are similar to the fvwm Next commands with patterns) """ def callback(qtile): windows = windows_matching_shuffle(qtile, **kwargs) if windows: @@ -57,7 +67,25 @@ def switch_to(**kwargs): return lazy.function(callback) def pull_window_here(**kwargs): """pull the matched window to the current group and focus it matching behaviour is the same as in switch_to """ def callback(qtile): windows = windows_matching_shuffle(qtile, **kwargs) if windows: window = windows[0] window.togroup(qtile.currentGroup.name) qtile.currentGroup.focus(window, False) return lazy.function(callback) def windows_matching_shuffle(qtile, **kwargs): """return a list of windows matching window_match_re with **kwargs, ordered so that the current Window (if it matches) comes last """ windows = [w for w in qtile.windowMap.values() if w.group and window_match_re(w, **kwargs)] @@ -74,9 +102,15 @@ def windows_matching_shuffle(qtile, **kwargs): def window_match_re(window, wmname=None, wmclass=None, role=None): """ match windows by name/title, class or role, by regular expressions Multiple conditions will be OR'ed together """ if not (wmname or wmclass or role): raise TypeError( "at least one of name, wmclass or role must be specified" ) ret = False if wmname: @@ -96,42 +130,71 @@ def window_match_re(window, wmname=None, wmclass=None, role=None): return ret keys = [ # Use pull_here by default (just mod) # Use switch_to with additional ctrl # spawn new window with additional shift Key( [mod], "1", pull_window_here(wmclass="URxvt")), Key( [mod, "control"], "1", pull_window_group_here(wmclass="URxvt")), Key( [mod], "a", pull_window_here(wmclass="URxvt")), Key( [mod, "control"], "a", pull_window_group_here(wmclass="URxvt")), Key( [mod, "shift"], "a", lazy.spawn("urxvtc -e screen -xORR -S delgado-main")), Key( [mod], "2", pull_window_here(wmclass="Emacs")), Key( [mod, "control"], "2", pull_window_group_here(wmclass="Emacs")), Key( [mod], "e", pull_window_here(wmclass="Emacs")), Key( [mod, "control"], "e", pull_window_group_here(wmclass="Emacs")), Key( [mod, "shift"], "e", lazy.spawn("em")), Key( [mod], "3", pull_window_here(role="browser")), Key( [mod, "control"], "3", pull_window_group_here(role="browser")), Key( [mod], "g", pull_window_here(role="browser")), Key( [mod, "control"], "g", pull_window_group_here(role="browser")), Key( [mod, "shift"], "g", lazy.spawn("chromium")), Key( [mod], "d", pull_window_here(wmname=".*pdf$", wmclass="(Evince|Acroread|Xpdf|Okular)")), Key( [mod, "control"], "d", pull_window_group_here(wmname=".*pdf$", wmclass="(Evince|Acroread|Xpdf|Okular)")), Key( [mod, "control", "shift"], "Return", lazy.spawn("xscreensaver-command -lock")), Key( [mod, "control"], "y", lazy.spawn("keepass2 --auto-type")), # Switch between windows in current stack pane Key( @@ -145,30 +208,31 @@ keys = [ Key( [mod], "Left", lazy.layout.previous() ), Key( [mod], "Right", lazy.layout.next() ), # Move windows in current stack pane -> I'd like to have this, but # move_* commands do not exist Key( [mod, "shift"], "Down", lazy.layout.shuffle_down() ), Key( [mod, "shift"], "Up", lazy.layout.shuffle_up() ), Key( [mod, "shift"], "Left", lazy.layout.client_to_previous() ), Key( [mod, "shift"], "Right", lazy.layout.client_to_next() ), # Move windows up or down in current stack @@ -193,7 +257,7 @@ keys = [ # Swap panes of split stack Key( [mod, "control"], "space", lazy.layout.rotate() ), @@ -208,12 +272,16 @@ keys = [ Key([mod], "Return", lazy.spawn("xterm")), # Toggle between different layouts as defined below Key([mod], "space", lazy.next_layout()), Key([mod, "shift"], "space", lazy.prev_layout()), Key([mod], "w", lazy.window.kill()), Key([mod, "control"], "r", lazy.restart()), Key([mod, "control"], "q", lazy.shutdown()), Key([mod], "r", lazy.spawncmd()), Key([mod], "x", lazy.qtilecmd()), Key([mod], "b", lazy.hide_show_bar()), Key([mod, "control"], "Delete", lazy.window.kill()), Key([mod], "minus", lazy.spawn( @@ -223,9 +291,16 @@ keys = [ "/usr/bin/env bash -c 'aumix -v +||amixer sset Master 1%+'")), Key([mod], "y", lazy.function(PrevFocus())), Key([mod, "control"], "Left", lazy.prev_screen()), Key([mod, "control"], "Right", lazy.next_screen()), Key([mod, "control"], "f", lazy.window.toggle_floating()), Key([mod], "f", lazy.window.toggle_fullscreen()), Key(["shift"], "Scroll_Lock", lazy.spawn("xmodmap ~/.Xmodmap")) ] groups = [Group(i, persist=(int(i) < 4), init=(int(i) < 4)) for i in "12345678"] for i in groups: # mod + F+ number of group = switch to group @@ -240,9 +315,8 @@ for i in groups: layouts = [ layout.Max(), layout.RatioTile(), layout.Stack(autosplit=True, fair=True), ] widget_defaults = dict( @@ -251,35 +325,47 @@ widget_defaults = dict( padding=3, ) def _barstart(): return [ widget.GroupBox(this_current_screen_border='0000FF'), widget.Prompt(), # widget.WindowName(), # either this widget.TaskList(max_title_width=600, highlight_method='block'), # or this, not both! widget.Sep(), # widget.TextBox("Friedel's config", name="config"), ] def _barend(): return [ widget.TextBox("Vol", name="volume_label"), widget.Volume(), widget.BatteryIcon(), widget.Systray(), widget.Sep(), widget.CurrentLayout(markup=True, fontsize=20, fontshadow='0000FF'), widget.Sep(), widget.Clock(format='%Y-%m-%d %a %H:%M:%S'), ] screens = [ Screen( bottom=bar.Bar( _barstart() + [ widget.TextBox("C", name="cpu_label"), widget.CPUGraph(), widget.TextBox("M", name="memory_label"), widget.MemoryGraph(), widget.TextBox("N", name="net_label"), widget.NetGraph(), widget.Sep(), ] + _barend(), 30)), Screen( bottom=bar.Bar( _barstart() + _barend(), 30)) ] # Drag floating layouts. @@ -296,7 +382,7 @@ dgroups_app_rules = [] main = None follow_mouse_focus = True bring_front_click = True cursor_warp = False floating_layout = layout.Floating() auto_fullscreen = True @@ -311,8 +397,19 @@ auto_fullscreen = True wmname = "LG3D" # see # http://docs.qtile.org/en/latest/manual/faq.html#my-pointer-mouse-cursor-isn-t-the-one-i-expect-it-to-be # noqa @hook.subscribe.startup def runner(): import subprocess subprocess.Popen(['xsetroot', '-cursor_name', 'left_ptr']) # from http://qtile.readthedocs.org/en/latest/manual/config/hooks.html#automatic-floating-dialogs @hook.subscribe.client_new def floating_dialogs(window): dialog = window.window.get_wm_type() == 'dialog' transient = window.window.get_wm_transient_for() bubble = window.window.get_wm_window_role() == 'bubble' if dialog or transient or bubble: window.floating = True -
TauPan revised this gist
Feb 10, 2015 . 1 changed file with 41 additions and 33 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -10,36 +10,42 @@ import xcffib.xproto mod = "mod4" # thanks to rogerduran for the implementation of my idea (borrowed # from stumpwm) class PrevFocus(object): """Store last focus per group and go back when called""" def __init__(self): self.focus = None self.old_focus = None self.groups_focus = {} hook.subscribe.client_focus(self.on_focus) def on_focus(self, window): group = window.group # only store focus if the group is set if not group: return group_focus = self.groups_focus.setdefault(group.name, { "current": None, "prev": None }) # don't change prev if the current focus is the same as before if group_focus["current"] == window: return group_focus["prev"] = group_focus["current"] group_focus["current"] = window def __call__(self, qtile): group = qtile.currentGroup group_focus = self.groups_focus.get(group.name, {"prev": None}) prev = group_focus["prev"] if prev and group.name == prev.group.name: group.focus(prev, False) # taken from # https://github.com/qtile/qtile-examples/blob/master/roger/config.py#L34 # and adapted def switch_to(**kwargs): def callback(qtile): windows = windows_matching_shuffle(qtile, **kwargs) @@ -77,8 +83,10 @@ def window_match_re(window, wmname=None, wmclass=None, role=None): ret = ret or re.match(wmname, window.name) try: if wmclass: cls = window.window.get_wm_class() if cls: for v in cls: ret = ret or re.match(wmclass, v) if role: rol = window.window.get_wm_window_role() if rol: @@ -214,7 +222,7 @@ keys = [ lazy.spawn( "/usr/bin/env bash -c 'aumix -v +||amixer sset Master 1%+'")), Key([mod], "y", lazy.function(PrevFocus())), ] groups = [Group(i, persist=(int(i) < 3), init=(int(i) < 3)) for i in "12345678"] -
TauPan created this gist
Feb 10, 2015 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,310 @@ import re from libqtile.config import Key, Screen, Group, Drag, Click from libqtile.command import lazy from libqtile import layout, bar, widget, hook import xcffib.xproto # copied from libqtile/resources/default_config.py and adapted by me mod = "mod4" # store current and previous focus, for switch_to_previous @hook.subscribe.client_focus def store_focus(window): old_current_focus = None last_focus = None if hasattr(window.group, 'current_focus'): old_current_focus = window.group.current_focus window.group.current_focus = window if hasattr(window.group, 'last_focus'): last_focus = window.group.last_focus if (last_focus and old_current_focus and last_focus.window.wid == old_current_focus.window.wid): return window.group.last_focus = old_current_focus @lazy.function def switch_to_previous(qtile): if hasattr(qtile.currentWindow.group, 'last_focus'): qtile.log.info('hasattr') window = qtile.currentWindow.group.last_focus qtile.log.info('window %s', window) qtile.log.info('current window %s', qtile.currentWindow.group.current_focus) if window: qtile.currentScreen.setGroup(window.group) window.group.focus(window, False) # taken from https://github.com/qtile/qtile-examples/blob/master/roger/config.py#L34 def switch_to(**kwargs): def callback(qtile): windows = windows_matching_shuffle(qtile, **kwargs) if windows: window = windows[0] qtile.currentScreen.setGroup(window.group) window.group.focus(window, False) return lazy.function(callback) def windows_matching_shuffle(qtile, **kwargs): windows = [w for w in qtile.windowMap.values() if w.group and window_match_re(w, **kwargs)] idx = 0 if qtile.currentWindow is not None: try: idx = windows.index(qtile.currentWindow) except ValueError: pass idx += 1 if idx >= len(windows): idx = 0 return windows[idx:] + windows[:idx] def window_match_re(window, wmname=None, wmclass=None, role=None): if not (wmname or wmclass or role): raise TypeError( "Either a name, a wmclass or a role must be specified" ) ret = False if wmname: ret = ret or re.match(wmname, window.name) try: if wmclass: for v in window.window.get_wm_class(): ret = ret or re.match(wmclass, v) if role: rol = window.window.get_wm_window_role() if rol: ret = ret or re.match(role, rol) except (xcffib.xproto.WindowError, xcffib.xproto.AccessError): return False return ret keys = [ # Use above switch_to Key( [mod], "1", switch_to(wmclass="URxvt")), Key( [mod], "a", switch_to(wmclass="URxvt")), Key( [mod, "shift"], "a", lazy.spawn("urxvtc -e screen -xORR -S delgado-main")), Key( [mod], "2", switch_to(wmclass="Emacs")), Key( [mod], "e", switch_to(wmclass="Emacs")), Key( [mod, "shift"], "e", lazy.spawn("em")), Key( [mod], "3", switch_to(role="browser")), Key( [mod], "g", switch_to(role="browser")), Key( [mod, "shift"], "g", lazy.spawn("chromium")), Key( [mod, "control", "shift"], "Return", lazy.spawn("xscreensaver-command -lock")), Key( [mod], "d", switch_to(wmname=".*pdf$", wmclass="(Evince|Acroread|Xpdf|Okular)")), # Switch between windows in current stack pane Key( [mod], "Down", lazy.layout.down() ), Key( [mod], "Up", lazy.layout.up() ), Key( [mod], "Left", lazy.layout.left() ), Key( [mod], "Right", lazy.layout.right() ), # Move windows in current stack pane -> I'd like to have this, but move_* commands do not exist Key( [mod, "shift"], "Down", lazy.layout.move_down() ), Key( [mod, "shift"], "Up", lazy.layout.move_up() ), Key( [mod, "shift"], "Left", lazy.layout.move_left() ), Key( [mod, "shift"], "Right", lazy.layout.move_right() ), # Move windows up or down in current stack Key( [mod, "control"], "k", lazy.layout.shuffle_down() ), Key( [mod, "control"], "j", lazy.layout.shuffle_up() ), # Switch window focus to other pane(s) of stack Key( [mod], "Tab", lazy.layout.next() ), Key( [mod, "shift"], "Tab", lazy.layout.previous() ), # Swap panes of split stack Key( [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( [mod, "shift"], "Return", lazy.layout.toggle_split() ), Key([mod], "Return", lazy.spawn("xterm")), # Toggle between different layouts as defined below Key([mod], "space", lazy.nextlayout()), Key([mod], "w", lazy.window.kill()), Key([mod, "control"], "r", lazy.restart()), Key([mod, "control"], "q", lazy.shutdown()), Key([mod], "r", lazy.spawncmd()), Key([mod], "minus", lazy.spawn( "/usr/bin/env bash -c 'aumix -v -||amixer sset Master 1%-'")), Key([mod], "plus", lazy.spawn( "/usr/bin/env bash -c 'aumix -v +||amixer sset Master 1%+'")), Key([mod], "y", switch_to_previous), ] groups = [Group(i, persist=(int(i) < 3), init=(int(i) < 3)) for i in "12345678"] for i in groups: # mod + F+ number of group = switch to group keys.append( Key([mod], "F%d" % int(i.name), lazy.group[i.name].toscreen()) ) # mod1 + shift + letter of group = switch to & move focused window to group keys.append( Key([mod, "shift"], "F%d" % int(i.name), lazy.window.togroup(i.name)) ) layouts = [ layout.Max(), layout.TreeTab(), layout.Stack(num_stacks=2), layout.Matrix(), ] widget_defaults = dict( font='Arial', fontsize=16, padding=3, ) mybar = lambda: bar.Bar( [ widget.GroupBox(), widget.Prompt(), # widget.WindowName(), # either this widget.TaskList(max_title_width=1920), # or this, not both! widget.CurrentLayout(), widget.Sep(), # widget.TextBox("Friedel's config", name="config"), widget.TextBox("C", name="cpu_label"), widget.CPUGraph(), widget.TextBox("M", name="memory_label"), widget.MemoryGraph(), widget.TextBox("N", name="net_label"), widget.NetGraph(), widget.Volume(), widget.Systray(), widget.Clock(format='%Y-%m-%d %a %H:%M:%S'), ], 30, ) screens = [ Screen( bottom=mybar(), ), Screen( bottom=mybar(), ), ] # 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()) ] dgroups_key_binder = None dgroups_app_rules = [] main = None follow_mouse_focus = True bring_front_click = True cursor_warp = True floating_layout = layout.Floating() auto_fullscreen = True # 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" # see http://docs.qtile.org/en/latest/manual/faq.html#my-pointer-mouse-cursor-isn-t-the-one-i-expect-it-to-be @hook.subscribe.startup def runner(): import subprocess subprocess.Popen(['xsetroot', '-cursor_name', 'left_ptr'])