diff --git a/qtile/.config/qtile/config.py b/qtile/.config/qtile/config.py index c8a5188a7..a48ab60ca 100644 --- a/qtile/.config/qtile/config.py +++ b/qtile/.config/qtile/config.py @@ -21,8 +21,10 @@ # SOFTWARE. import re +import json import locale import subprocess +from os.path import expanduser from widgets import Widgets from groups import Groups @@ -51,14 +53,13 @@ class Commands(object): menu = 'repomenu_run -i -l 10 -w 600 -c -p "Launcher" -q "Launch a app"' browser = 'firefox' terminal = 'alacritty' - btop = 'alacritty --class=btop -e btop' - powermenu = 'repomenue_powermenu' + btop = 'kitty --class=btop -e btop' + powermenu = 'kitty --class=powermenu -o initial_window_height=220 -e fzf_powermenu' vbox = 'virt-manager' files = 'nemo' mail = 'thunderbird' killmenu = 'repomenue_kill' - passmenu = 'repomenue_pass' - smartmenu = 'repomenue_smartrun' + passmenu = 'kitty --class=passmenu -o initial_window_height=650 -e fzf_pass' autostart = [files, terminal, browser] configure = ['autorandr --load qtile', 'autostart'] @@ -119,7 +120,6 @@ keys = [ Key([MOD], "Return", lazy.spawn(Commands.terminal), desc="Launch terminal", group="Launch"), Key([MOD], "m", lazy.spawn(Commands.menu), desc="Launch menu", group="Launch"), Key([MOD], "p", lazy.spawn(Commands.passmenu), desc="Launch password menu", group="Launch"), - Key([MOD], "s", lazy.spawn(Commands.smartmenu), desc="Launch smart menu", group="Launch"), Key([MOD, CTRL], "f", lazy.spawn(Commands.browser), desc="Launch browser", group="Launch"), Key([MOD, CTRL], "c", lazy.spawn(Commands.editor), desc="Launch editor", group="Launch"), Key([MOD, SHIFT], "e", lazy.spawn(Commands.powermenu), desc="Launch power menu", group="Launch"), @@ -140,7 +140,87 @@ keys = [ # xBacklight Key([], "XF86MonBrightnessUp", lazy.spawn("xbacklight +10")), Key([], "XF86MonBrightnessDown", lazy.spawn("xbacklight -10")), +] +dgroups_key_binder = simple_key_binder(MOD) +dgroups_app_rules = [] # type: list + +def show_keys(keys): + """ + print current keybindings in a pretty way for a rofi/dmenu window. + """ + key_help = "{:<20} {:<30} {}\n".format('Group', 'Keybinds', 'Description') + keys_ignored = ( + "XF86AudioMute", # + "XF86AudioLowerVolume", # + "XF86AudioRaiseVolume", # + "XF86AudioPlay", # + "XF86AudioNext", # + "XF86AudioPrev", # + "XF86AudioStop", + "XF86MonBrightnessUp", + "XF86MonBrightnessDown", + ) + text_replaced = { + "mod4": "[MOD]", # + "control": "[CTRL]", # + "mod1": "[ALT]", # + "shift": "[SHIFT]", # + "Escape": "ESC", # + } + + data = {} + category={} + file_path = expanduser("~/.config/qtile/keybinds.json") + for k in keys: + if k.key in keys_ignored: + continue + + mods = "" + key = "" + desc = k.desc.title() + group = k.group.title() + allargs = ", ".join([value.__name__ if callable(value) else repr(value) for value in k.commands[0].args] + + ["%s = %s" % (keyword, repr(value)) for keyword, value in k.commands[0].kwargs.items()]) + command = k.commands[0].name + " " + allargs + for m in k.modifiers: + if m in text_replaced.keys(): + mods += text_replaced[m] + " + " + else: + mods += m.capitalize() + " + " + + if len(k.key) > 1: + if k.key in text_replaced.keys(): + key = text_replaced[k.key] + else: + key = k.key.title() + else: + key = k.key + + key_line = "{:<20} {:<30} {}\n".format(group, mods + key, desc) + key_help += key_line + + if group not in data: + data[group] = {} + + category = data[group] + category[desc] = {} + category[desc]['keybind'] = mods + key + category[desc]['command'] = command + + with open(file_path, "w") as json_data: + json.dump(data, json_data, indent=4) + + return expanduser("~/.config/qtile/scripts/qtile-cheat") + + +# this must be done AFTER all the keys have been defined +cheater = show_keys(keys) +keys.extend([ + Key([MOD], "F1", lazy.spawn(cheater), desc="Print keyboard bindings"), +]) + +keys.extend([ ################ ## Key Chords ## ################ @@ -186,71 +266,6 @@ keys = [ desc="Take a Screenshot", group="KeyChord", ), -] - -dgroups_key_binder = simple_key_binder(MOD) -dgroups_app_rules = [] # type: list - -def show_keys(keys): - """ - print current keybindings in a pretty way for a rofi/dmenu window. - """ - key_help = "{:<20} {:<30} {}\n".format('Group', 'Keybinds', 'Description') - keys_ignored = ( - "XF86AudioMute", # - "XF86AudioLowerVolume", # - "XF86AudioRaiseVolume", # - "XF86AudioPlay", # - "XF86AudioNext", # - "XF86AudioPrev", # - "XF86AudioStop", - "XF86MonBrightnessUp", - "XF86MonBrightnessDown", - ) - text_replaced = { - "mod4": "[MOD]", # - "control": "[CTRL]", # - "mod1": "[ALT]", # - "shift": "[SHIFT]", # - "Escape": "ESC", # - } - for k in keys: - if k.key in keys_ignored: - continue - - mods = "" - key = "" - desc = k.desc.title() - group = k.group.title() - for m in k.modifiers: - if m in text_replaced.keys(): - mods += text_replaced[m] + " + " - else: - mods += m.capitalize() + " + " - - if len(k.key) > 1: - if k.key in text_replaced.keys(): - key = text_replaced[k.key] - else: - key = k.key.title() - else: - key = k.key - - key_line = "{:<20} {:<30} {}\n".format(group, mods + key, desc) - key_help += key_line - - with open('/home/repo/.config/qtile/packages.txt', 'w') as outfile: - outfile.write(key_help) - - return key_help - - -# this must be done AFTER all the keys have been defined -cheater = Commands.terminal + " --class='Cheater' -e sh -c 'echo \"" + show_keys( - keys -) + "\" | fzf --prompt=\"Search for a keybind: \" --border=rounded --margin=1% --color=dark --height 100% --reverse --header=\" QTILE CHEAT SHEET \" --info=hidden --header-first'" -keys.extend([ - Key([MOD], "F1", lazy.spawn(cheater), desc="Print keyboard bindings"), ]) ############ @@ -319,7 +334,8 @@ 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=re.compile('^Cheater.*', re.IGNORECASE)), # gitk + Match(wm_class=re.compile('^Cheater.*', re.IGNORECASE)), # Cheater + Match(wm_class=re.compile('^PassMenu.*|^PowerMenu.*', re.IGNORECASE)), # Menus Match(wm_class="confirmreset"), # gitk Match(wm_class="makebranch"), # gitk Match(wm_class="maketag"), # gitk diff --git a/qtile/.config/qtile/groups.py b/qtile/.config/qtile/groups.py index 5f70d1442..d942463a1 100644 --- a/qtile/.config/qtile/groups.py +++ b/qtile/.config/qtile/groups.py @@ -6,7 +6,7 @@ class Groups(object): groups = [ # first group that hold the terminals Group( - # label='', + label='一', init=True, exclusive=False, persist=True, @@ -17,7 +17,7 @@ class Groups(object): name='1', ), Group( - # label='', + label='二', init=True, exclusive=False, persist=True, @@ -27,7 +27,7 @@ class Groups(object): name='2', ), Group( - # label='', + label='三', init=True, exclusive=False, persist=True, @@ -37,7 +37,7 @@ class Groups(object): name='3', ), Group( - # label='', + label='四', init=True, exclusive=False, persist=True, @@ -47,7 +47,7 @@ class Groups(object): name='4', ), Group( - # label='ﱘ', + label='五', init=True, exclusive=False, persist=True, @@ -57,7 +57,7 @@ class Groups(object): name='5', ), Group( - # label='', + label='六', init=True, persist=True, exclusive=False, @@ -67,7 +67,7 @@ class Groups(object): name='6', ), Group( - # label='', + label='七', init=True, persist=True, exclusive=False, @@ -77,7 +77,7 @@ class Groups(object): name='7', ), Group( - # label='調', + label='八', init=True, persist=True, exclusive=False, @@ -87,7 +87,7 @@ class Groups(object): name='8', ), Group( - # label='', + label='九', init=True, persist=True, exclusive=False, @@ -97,7 +97,7 @@ class Groups(object): name='9', ), Group( - # label='', + label='零', init=True, persist=True, exclusive=False, diff --git a/qtile/.config/qtile/keybinds.json b/qtile/.config/qtile/keybinds.json new file mode 100644 index 000000000..768537381 --- /dev/null +++ b/qtile/.config/qtile/keybinds.json @@ -0,0 +1,92 @@ +{ + "Qtile": { + "Reload The Config": { + "keybind": "[MOD] + [SHIFT] + r", + "command": "reload_config " + }, + "Restart Qtile": { + "keybind": "[MOD] + [CTRL] + r", + "command": "restart " + } + }, + "Moving": { + "Move Focus To Left": { + "keybind": "[MOD] + h", + "command": "left " + }, + "Move Focus To Right": { + "keybind": "[MOD] + l", + "command": "right " + }, + "Move Focus Down": { + "keybind": "[MOD] + j", + "command": "down " + }, + "Move Focus Up": { + "keybind": "[MOD] + k", + "command": "up " + } + }, + "Reset": { + "Reset All Window Sizes": { + "keybind": "[MOD] + n", + "command": "normalize " + } + }, + "Toggle": { + "Toggle Between Layouts": { + "keybind": "[MOD] + Tab", + "command": "next_layout " + }, + "Toggle Floating": { + "keybind": "[MOD] + t", + "command": "toggle_floating " + } + }, + "Kill": { + "Kill Focused Window": { + "keybind": "[MOD] + q", + "command": "kill " + }, + "Launch Kill Menu": { + "keybind": "[MOD] + [SHIFT] + q", + "command": "spawn 'repomenue_kill'" + } + }, + "Launch": { + "Launch Terminal": { + "keybind": "[MOD] + Return", + "command": "spawn 'alacritty'" + }, + "Launch Menu": { + "keybind": "[MOD] + m", + "command": "spawn 'repomenu_run -i -l 10 -w 600 -c -p \"Launcher\" -q \"Launch a app\"'" + }, + "Launch Password Menu": { + "keybind": "[MOD] + p", + "command": "spawn 'kitty --class=passmenu -o initial_window_height=650 -e fzf_pass'" + }, + "Launch Browser": { + "keybind": "[MOD] + [CTRL] + f", + "command": "spawn 'firefox'" + }, + "Launch Editor": { + "keybind": "[MOD] + [CTRL] + c", + "command": "spawn 'code'" + }, + "Launch Power Menu": { + "keybind": "[MOD] + [SHIFT] + e", + "command": "spawn 'kitty --class=powermenu -o initial_window_height=220 -e fzf_powermenu'" + }, + "Launch Files": { + "keybind": "[MOD] + [SHIFT] + Return", + "command": "spawn 'nemo'" + } + }, + "Utils": { + "Launch Btop": { + "keybind": "[MOD] + b", + "command": "spawn 'kitty --class=btop -e btop'" + } + } +} \ No newline at end of file diff --git a/qtile/.config/qtile/scripts/qtile-cheat b/qtile/.config/qtile/scripts/qtile-cheat new file mode 100755 index 000000000..fc158a035 --- /dev/null +++ b/qtile/.config/qtile/scripts/qtile-cheat @@ -0,0 +1,165 @@ +#!/usr/bin/env python3 + +import json +from os.path import expanduser + +import gi + +gi.require_version('Gtk', '3.0') +gi.require_version('Gdk', '3.0') +from gi.repository import Gdk, Gio, GLib, Gtk + +configFile = expanduser("~/.config/qtile/keybinds.json") +with open(f'{configFile}', mode='r') as inputfile: + data = json.load(inputfile) + +def mode_label(mode): + 'Create a GTK label for mode' '' + label = Gtk.Label() + label.set_text(str(mode)) + return label + +class WMCheatWindow(Gtk.ApplicationWindow): + + + + def __init__(self, **kwargs): + super().__init__(**kwargs) + self._tab_lookup = dict() + self.set_default_size(-1, 740) + self.set_border_width(3) + + accel_group = Gtk.AccelGroup() + accel_group.connect(Gdk.keyval_from_name('Left'), + Gdk.ModifierType.SUPER_MASK, 0, self.prev_mode) + accel_group.connect(Gdk.keyval_from_name('Right'), + Gdk.ModifierType.SUPER_MASK, 0, self.next_mode) + accel_group.connect(Gdk.keyval_from_name('Escape'), 0, 0, self._quit) + self.add_accel_group(accel_group) + + self.set_type_hint(Gdk.WindowTypeHint.DIALOG) + + self.notebook = Gtk.Notebook(scrollable=True) + for (category, array) in data.items(): + self.category = Gtk.Box() + self.category.set_border_width(10) + + store = Gtk.ListStore(str, str, str, str) + + for description in array: + keybind = array[description]['keybind'] + command = array[description]['command'] + store.append( + [category, + str(description), + str(keybind), + str(command)]) + + tree = Gtk.TreeView(model=store, + headers_visible=True, + enable_search=False, + search_column=1) + tree.get_selection().set_mode(Gtk.SelectionMode.BROWSE) + tree.set_cursor(Gtk.TreePath(0), None, False) + + description_column = Gtk.TreeViewColumn("Description", + Gtk.CellRendererText(), + text=1) + description_column.set_min_width(300) + tree.append_column(description_column) + + keybind_column = Gtk.TreeViewColumn("Keybind", + Gtk.CellRendererText(), + text=2) + keybind_column.set_min_width(300) + tree.append_column(keybind_column) + + command_column = Gtk.TreeViewColumn("Command", + Gtk.CellRendererText(), + text=3) + command_column.set_min_width(300) + tree.append_column(command_column) + + scrolled = Gtk.ScrolledWindow() + scrolled.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) + scrolled.add(tree) + + self._tab_lookup[category] = self.notebook.get_n_pages() + self.notebook.append_page(scrolled, mode_label(category)) + + self.add(self.notebook) + self.current_page().grab_focus() + + style = Gtk.CssProvider() + style.load_from_data(WMCheat.CSS) + Gtk.StyleContext.add_provider_for_screen( + Gdk.Screen.get_default(), style, + Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION) + + def current_page(self): + return self.notebook.get_nth_page(self.notebook.get_current_page()) + + def _init_mode(self, mode): + store = Gtk.ListStore(str, str, str) + + def focus_mode(self, mode): + 'Focus on a mode by its name' + idx = self._tab_lookup.get(mode, 0) + self.notebook.set_current_page(idx) + + def next_mode(self, *args): + self.notebook.next_page() + + def prev_mode(self, *args): + self.notebook.prev_page() + + def _quit(self, *args): + self.close() + + +class WMCheat(Gtk.Application): + CSS = b""" + * { + font-size: 16px; + } + @binding-set i3-binds { + bind "slash" { "start-interactive-search" () }; + bind "j" { "move-cursor" (display-lines, 1) }; + bind "k" { "move-cursor" (display-lines, -1) }; + } + GtkTreeView, treeview { + -gtk-key-bindings: i3-binds; + } + """ + + def __init__(self): + super().__init__(application_id="com.github.The-Repo-Club.keybinds", + flags=Gio.ApplicationFlags.HANDLES_COMMAND_LINE) + self.add_main_option('mode', ord('m'), 0, GLib.OptionArg.STRING, + "Mode tab to open", "MODE") + self._window = None + + def do_command_line(self, cl): + if not self._window: + self._window = WMCheatWindow(application=self, + title="Window Manager Cheatsheet") + self._window.show_all() + + mode = cl.get_options_dict().lookup_value('mode') + if mode: + mode = mode.get_string() + self._window.focus_mode(mode) + self._window.present() + return 0 + + def do_startup(self): + Gtk.Application.do_startup(self) + + +if __name__ == '__main__': + import sys + import signal + app = WMCheat() + # so ctrl+c still works + GLib.unix_signal_add(GLib.PRIORITY_DEFAULT, signal.SIGINT, app.quit) + app.run(sys.argv) diff --git a/qtile/.config/qtile/widgets.py b/qtile/.config/qtile/widgets.py index ba96a00ce..314d8c8f4 100644 --- a/qtile/.config/qtile/widgets.py +++ b/qtile/.config/qtile/widgets.py @@ -27,7 +27,7 @@ class Widgets(object): text_only=True, foreground=colorScheme[1], progs=[ - ('⏻ ', 'repomenue_powermenu', 'launch repomenu powermenu'), + ('⏻ ', 'kitty --class=powermenu -o initial_window_height=220 -e fzf_powermenu', 'launch fzf powermenu'), ], ) @@ -35,7 +35,7 @@ class Widgets(object): text_only=True, foreground=colorScheme[1], progs=[ - ('⏻ ', 'repomenue_powermenu', 'launch repomenu powermenu'), + ('⏻ ', 'kitty --class=powermenu -o initial_window_height=220 -e fzf_powermenu', 'launch fzf powermenu'), ], )