From e36f3889d8c8766ec9b9c61f95c6af0b1bcff06c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Av=C3=A9?= Date: Wed, 24 May 2023 15:57:03 +0200 Subject: [PATCH] Qtile experiments --- qtile/main.py | 25 +++++++----- qtile/traverse.py | 100 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 115 insertions(+), 10 deletions(-) create mode 100644 qtile/traverse.py diff --git a/qtile/main.py b/qtile/main.py index 114ee58..f853475 100644 --- a/qtile/main.py +++ b/qtile/main.py @@ -6,6 +6,8 @@ from libqtile.utils import guess_terminal from qtile_extras.widget.decorations import PowerLineDecoration from widgets.volume import Volume +import traverse + class Colors: background = "#1f2430" accent = "#002F5F" @@ -35,6 +37,9 @@ screens = [ highlight_method="block", highlight_color=Colors.accent, this_current_screen_border=Colors.accent, + other_current_screen_border=Colors.accent, + this_screen_border="#00000000", + other_screen_border="#00000000", font="Ubuntu bold", padding=9, hide_unused=True @@ -76,10 +81,10 @@ keys = [ # A list of available commands that can be bound to keys can be found # at https://docs.qtile.org/en/latest/manual/config/lazy.html # Switch between windows - Key([mod], "h", lazy.layout.left(), desc="Move focus to left"), - Key([mod], "l", lazy.layout.right(), desc="Move focus to right"), - Key([mod], "j", lazy.layout.down(), desc="Move focus down"), - Key([mod], "k", lazy.layout.up(), desc="Move focus up"), + Key([mod], 'k', lazy.function(traverse.up)), + Key([mod], 'j', lazy.function(traverse.down)), + Key([mod], 'h', lazy.function(traverse.left)), + Key([mod], 'l', lazy.function(traverse.right)), Key([mod], "f", lazy.window.toggle_floating(), desc="Move focus up"), Key([mod], "m", lazy.window.toggle_fullscreen(), desc="Move focus up"), Key([mod], "space", lazy.layout.next(), desc="Move window focus to other window"), @@ -117,9 +122,8 @@ keys = [ ] groups = [] -for s in screens: - for i in list(range(1, 10)) + [0]: - groups.append(Group(str(i), screen_affinity=s)) +for i in list(range(1, 10)) + [0]: + groups.append(Group(str(i))) for i in groups[:10]: keys.extend( @@ -128,7 +132,7 @@ for i in groups[:10]: Key( [mod], i.name, - lazy.group[i.name].toscreen(0), + lazy.group[i.name].toscreen(), desc="Switch to group {}".format(i.name), ), # mod1 + shift + letter of group = switch to & move focused window to group @@ -155,13 +159,14 @@ layout_settings = { } mouse = [ - Drag([mod], "Button1", lazy.window.set_position(), start=lazy.window.get_position()), + Drag([mod], "Button1", lazy.window.set_position(), + start=lazy.window.get_position()), Drag([mod], "Button3", lazy.window.set_position(), start=lazy.window.get_size()) ] layouts = [ - layout.Tile(**layout_settings), layout.Columns(**layout_settings), + layout.Tile(**layout_settings), layout.Max(), # Try more layouts by unleashing below layouts. # layout.Stack(num_stacks=2), diff --git a/qtile/traverse.py b/qtile/traverse.py new file mode 100644 index 0000000..f7df516 --- /dev/null +++ b/qtile/traverse.py @@ -0,0 +1,100 @@ +""" +This plugin exports four functions - up, down, left and right - that when called will +move window focus to the first window in that general direction. Focussing is based +entirely on position and geometry, so is independent of screens, layouts and whether +windows are floating or tiled. It can also move focus to and from empty screens. + +Example usage: + + import traverse + + keys.extend([ + Key([mod], 'k', lazy.function(traverse.up)), + Key([mod], 'j', lazy.function(traverse.down)), + Key([mod], 'h', lazy.function(traverse.left)), + Key([mod], 'l', lazy.function(traverse.right)), + ]) + +Qtile versions known to work: 0.16 - 0.18 +""" + +from libqtile.config import Screen + + +def up(qtile): + _focus_window(qtile, -1, 'y') + + +def down(qtile): + _focus_window(qtile, 1, 'y') + + +def left(qtile): + _focus_window(qtile, -1, 'x') + + +def right(qtile): + _focus_window(qtile, 1, 'x') + + + +def get_window_in_direction(qtile, dir, axis): + win = None + win_wide = None + dist = 10000 + dist_wide = 10000 + cur = qtile.current_window + if not cur: + cur = qtile.current_screen + + if axis == 'x': + dim = 'width' + band_axis = 'y' + band_dim = 'height' + cur_pos = cur.x + band_min = cur.y + band_max = cur.y + cur.height + else: + dim = 'height' + band_axis = 'x' + band_dim = 'width' + band_min = cur.x + cur_pos = cur.y + band_max = cur.x + cur.width + + cur_pos += getattr(cur, dim) / 2 + + windows = [w for g in qtile.groups if g.screen for w in g.windows] + windows.extend([s for s in qtile.screens if not s.group.windows]) + + if cur in windows: + windows.remove(cur) + + for w in windows: + if isinstance(w, Screen) or not w.minimized: + pos = getattr(w, axis) + getattr(w, dim) / 2 + gap = dir * (pos - cur_pos) + if gap > 5: + band_pos = getattr(w, band_axis) + getattr(w, band_dim) / 2 + if band_min < band_pos < band_max: + if gap < dist: + dist = gap + win = w + else: + if gap < dist_wide: + dist_wide = gap + win_wide = w + + if not win: + win = win_wide + + return win + + +def _focus_window(qtile, dir, axis): + win = get_window_in_direction(qtile, dir, axis) + if win: + qtile.focus_screen(win.group.screen.index) + win.group.focus(win, True) + if not isinstance(win, Screen): + win.focus(False)