from libqtile.config import Key, Screen, Group, Drag, Click, Match from libqtile.command import lazy from libqtile import layout, bar, widget, hook from os.path import expanduser import re import subprocess mod = "mod4" alt = "mod1" home = expanduser("~") terminal = "termite" drun_launcher = "rofi -show drun" run_launcher = "rofi -show run" lock = home+"/bin/i3lock" brightness_step = "5" brightness_up = "xbacklight -inc "+brightness_step brightness_down = "xbacklight -dec "+brightness_step volume_up = home+"/bin/set_volume increase" volume_down = home+"/bin/set_volume decrease" volume_toggle = home+"/bin/set_volume toggle" audio_prev = home+"/bin/notify_mpd prev" audio_next = home+"/bin/notify_mpd next" audio_toggle = home+"/bin/notify_mpd toggle" audio_stop = home+"/bin/notify_mpd stop" subprocess.call(['feh', '--randomize', '--recursive', '--bg-fill', home+'/ownCloud/photos/desktop/']) colors = { "grey": "#555555", "red": "#DD1144", "blue": "#445588", "lgrey": "#b8b6b1", "green": "#008080", } # kick a window to another screen (handy during presentations) def move_to_other_screen(qtile, direction=1): other_scr_index = (qtile.screens.index(qtile.currentScreen) + direction) % len(qtile.screens) othergroup = None for group in qtile.cmd_groups().values(): if group['screen'] == other_scr_index: othergroup = group['name'] break if othergroup: qtile.moveToGroup(othergroup) keys = [ # base commands # restart qtile Key([mod, "control"], "r", lazy.restart()), # close qtile Key([mod, "control"], "q", lazy.shutdown()), # start run launcher Key([mod], "r", lazy.spawn(run_launcher)), # start drun launcher Key([mod], "p", lazy.spawn(drun_launcher)), # lock screen Key([mod, "control"], "s", lazy.spawn(lock)), # launch terminal Key([mod], "Return", lazy.spawn(terminal)), # brightness settings Key([], "XF86MonBrightnessUp", lazy.spawn(brightness_up)), Key([], "XF86MonBrightnessDown", lazy.spawn(brightness_down)), # multimedia Key([], "XF86AudioRaiseVolume", lazy.spawn(volume_up)), Key([], "XF86AudioLowerVolume", lazy.spawn(volume_down)), Key([], "XF86AudioMute", lazy.spawn(volume_toggle)), Key([], "XF86AudioPrev", lazy.spawn(audio_prev)), Key([], "XF86AudioNext", lazy.spawn(audio_next)), Key([], "XF86AudioPlay", lazy.spawn(audio_toggle)), Key([], "XF86AudioStop", lazy.spawn(audio_stop)), # cycle to previous and next group Key(["control", alt], "Left", lazy.screen.prev_group(skip_managed=True)), Key(["control", alt], "Right", lazy.screen.next_group(skip_managed=True)), Key(["control", mod, alt], "Left", lazy.screen.prev_group()), Key(["control", mod, alt], "Right", lazy.screen.next_group()), # Switch between windows in current stack pane Key([mod], "comma", lazy.layout.up()), Key([mod], "period", lazy.layout.down()), Key([mod], "Tab", lazy.layout.previous()), Key([mod, "shift"], "Tab", lazy.layout.next()), # toggle between different layouts Key([mod], "space", lazy.next_layout()), # close window Key([mod], "q", lazy.window.kill()), # toggle fullscreen Key([mod, "control"], "f", lazy.window.toggle_fullscreen()), # toggle maximized Key([mod], "m", lazy.window.toggle_maximize()), # toggle floating Key([mod], "f", lazy.window.toggle_floating()), Key([mod, alt], "space", lazy.layout.rotate()), # flip sides # Multihead magic Key([mod, "control"], "comma", lazy.prev_screen()), Key([mod, "control"], "period", lazy.next_screen()), Key([mod], "o", lazy.function(move_to_other_screen)), # columns layout # move selection around in current group Key([mod], "j", lazy.layout.down()), Key([mod], "k", lazy.layout.up()), Key([mod], "h", lazy.layout.left()), Key([mod], "l", lazy.layout.right()), # move current window around in the current layout Key([mod, "shift"], "j", lazy.layout.shuffle_down()), Key([mod, "shift"], "k", lazy.layout.shuffle_up()), Key([mod, "shift"], "h", lazy.layout.shuffle_left()), Key([mod, "shift"], "l", lazy.layout.shuffle_right()), # grow current window into some direction Key([mod, "control"], "j", lazy.layout.grow_down()), Key([mod, "control"], "k", lazy.layout.grow_up()), Key([mod, "control"], "h", lazy.layout.grow_left()), Key([mod, "control"], "l", lazy.layout.grow_right()), # toggle current window to be splitting current group in half Key([mod], "s", lazy.layout.toggle_split()), # normalize the layout Key([mod], "n", lazy.layout.normalize()), ] matchers = { 'web': [ Match(wm_class=[ "Firefox", "chromium", re.compile('TorLauncher'), re.compile('Tor Browser'), ]), ], 'dev': [ Match(wm_class=[ re.compile('Processing'), re.compile('processing-app-Base'), re.compile('scide'), "pdwindow", "PdWindow", "PatchWindow", ]), Match(title=[ re.compile('SuperCollider'), "Pd", re.compile('Arduino'), ]), ], 'games': [ Match(wm_class=[ re.compile('Minecraft'), re.compile('Minetest'), "pyrogenesis", "spring", "angband", "scummvm", "widelands", ]), Match(title=[ re.compile('ScummVM'), re.compile('Widelands'), re.compile('Minecraft'), re.compile('Minetest'), "OpenRA", "0 A.D.", "Angband", "Alien Arena", ]), ], 'audio': [ Match(wm_class=[ "Ardour", re.compile('Audacity'), re.compile('Calfjackhost'), re.compile('Ffado-mixer'), re.compile('Guitarix'), ]) ], 'photo': [ Match(wm_class=[ re.compile('Shotwell'), re.compile('Gimp'), re.compile('Inkscape'), re.compile('Darktable'), re.compile('Converseen'), re.compile('Ufraw'), ]) ], 'office': [ Match(wm_class=[ re.compile('libreoffice'), re.compile('Scribus'), re.compile('net-sf-jabref-JabRefMain'), ]), ], 'admin': [ Match(wm_class=[ re.compile('virt-manager'), re.compile('Virt-manager'), ]), ], } workspaces = [ {"key": "1", "name": "shell"}, {"key": "2", "name": "web", "matches": matchers["web"]}, {"key": "3", "name": "dev", "matches": matchers["dev"]}, {"key": "4", "name": "games", "matches": matchers["games"]}, {"key": "5", "name": "audio", "matches": matchers["audio"]}, {"key": "6", "name": "photo", "matches": matchers["photo"]}, {"key": "7", "name": "office", "matches": matchers["office"]}, {"key": "8", "name": "admin", "matches": matchers["admin"]}, {"key": "9", "name": "9"}, {"key": "0", "name": "0"}, ] groups = [] for workspace in workspaces: matches = workspace["matches"] if "matches" in workspace else None groups.append(Group(workspace["name"], matches=matches)) keys.append( Key([mod], workspace["key"], lazy.group[workspace["name"]].toscreen()) ) keys.append(Key( [mod, alt], workspace["key"], lazy.window.togroup(workspace["name"]), )) layouts = [ layout.Columns( border_focus=colors["red"][1:], border_normal=colors["green"][1:], margin=1, ), # layout.TreeTab( # active_bg=colors["red"][1:], # #active_fg=colors["grey"][1:], # active_fg='ffffff', # inactive_bg=colors["green"][1:], # #inactive_fg=colors["lgrey"][1:], # inactive_fg='ffffff', # border_focus=colors["red"][1:], # border_normal=colors["green"][1:], # font='Monospace', # fontsize=14, # margin_left=0, # padding_left=0, # panel_width=100, # previous_on_rm=True, # ), layout.Stack( border_focus=colors["red"][1:], border_normal=colors["green"][1:], margin=1, ), layout.Max(), layout.VerticalTile( border_focus=colors["red"][1:], border_normal=colors["green"][1:], margin=1, ), layout.Matrix( border_focus=colors["red"][1:], border_normal=colors["green"][1:], margin=1, ), layout.Zoomy(), ] widget_defaults = dict( font='Monospace', fontsize=11, padding=3, ) screens = [ Screen( top=bar.Bar([ widget.CurrentScreen(), widget.Sep(), widget.GroupBox( highlight_method="block", this_current_screen_border=colors["blue"] ), widget.Sep(), widget.Notify( foreground_low=colors["red"][1:], foreground_urgent=colors["red"][1:] ), widget.Spacer(), widget.CurrentLayout(), widget.Sep(), widget.Mpd( host="127.0.0.1", port=6600, reconnect=True, fmt_playing="%a [%A] %t [%v%%]", ), widget.Sep(), widget.HDDGraph( graph_color=colors["blue"], border_width=0, samples=60, frequency=5, type="box", ), widget.MemoryGraph( graph_color=colors["green"], border_width=0, samples=60, frequency=2, type="box", ), widget.CPUGraph( graph_color=colors["red"], border_width=0, samples=60, frequency=2, type="box", ), widget.Battery(), widget.Sep(), widget.Systray(), widget.Sep(), widget.Clock( timezone="Europe/Berlin", format="%Y%m%d %a %H:%M:%S" ), ], 20 ), ), Screen( top=bar.Bar([ widget.CurrentScreen(), widget.Sep(), widget.GroupBox( highlight_method="block", this_current_screen_border=colors["blue"] ), widget.Sep(), # widget.Notify( # foreground_low=colors["red"][1:], # foreground_urgent=colors["red"][1:] # ), widget.Spacer(), widget.CurrentLayout(), widget.Sep(), widget.Clock( timezone="Europe/Berlin", format="%Y%m%d %a %H:%M:%S" ), ], 20 ), ), ] # 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 = [] follow_mouse_focus = True bring_front_click = False cursor_warp = False floating_layout = layout.Floating() auto_fullscreen = True wmname = "LG3D" def main(qtile): qtile.cmd_warning() @hook.subscribe.screen_change def restart_on_randr(qtile, ev): qtile.cmd_restart() @hook.subscribe.client_new def floating_dialogs(window): float_clients = [ 'DialogWindow', 'HelpBrowser', ] wm_class = window.window.get_wm_class() for client in float_clients: if client in wm_class: window.floating = True transient = window.window.get_wm_transient_for() if transient: window.floating = True