@@ 16,6 16,7 @@ from qtile_extras.widget.decorations import BorderDecoration, PowerLineDecoratio
from tasklist import TaskList
from mpris2widget import Mpris2
from bluetooth import Bluetooth
+import xmonad
from nixenvironment import setupLocation, configLocation
colors = {
@@ 109,9 110,9 @@ layout_theme = {
}
layouts = [
- layout.MonadTall(**layout_theme),
+ xmonad.MonadTall(**layout_theme),
layout.Max(**layout_theme),
- layout.MonadWide(**layout_theme),
+ xmonad.MonadWide(**layout_theme),
]
widget_defaults = dict(
@@ 332,8 333,8 @@ def init_screen(top_bar, wallpaper):
return Screen(top=top_bar, bottom=create_bottom_bar(), wallpaper=wallpaper, width=1920, height=1080)
screens = [
- init_screen(create_top_bar(systray = True), f'{setupLocation}/wall.png'),
init_screen(create_top_bar(), f'{setupLocation}/wall.png'),
+ init_screen(create_top_bar(systray = True), f'{setupLocation}/wall.png'),
init_screen(create_top_bar(), f'{setupLocation}/wall.png'),
]
@@ 359,6 360,8 @@ keys.extend([
EzKey('M-<Return>', lazy.layout.swap_main()),
EzKey('M-<Space>', lazy.next_layout()),
EzKey('M-S-<Space>', lazy.to_layout_index(0), desc = 'Default layout'),
+ EzKey('M-<comma>', lazy.layout.increase_nmaster()),
+ EzKey('M-<period>', lazy.layout.decrease_nmaster()),
])
# Spwning programs
@@ 426,12 429,14 @@ keys.extend([
EzKey('M-S-c', lazy.window.kill()),
EzKey('M-C-r', lazy.reload_config()),
EzKey('M-C-q', lazy.shutdown()),
+
+ #EzKey(f'M-r', lazy.to_screen(0), desc = f'Move focus to screen {i}'),
])
# Monitor navigation
monitor_navigation_keys = ['w', 'e', 'r']
-monitor_index_map = [ 1, 2, 0 ]
for i, key in enumerate(monitor_navigation_keys):
+ monitor_index_map = [ 2, 1, 0 ]
keys.extend([
EzKey(f'M-{key}', lazy.to_screen(monitor_index_map[i]), desc = f'Move focus to screen {i}'),
EzKey(f'M-S-{key}', lazy.window.toscreen(monitor_index_map[i]), desc = f'Move focus to screen {i}'),
@@ 576,7 581,7 @@ def startup_applications(client: Window):
if client.match(Match(wm_class = 'firefox')) and firefoxInstance <= 1:
client.togroup(groups[firefoxInstance].name)
firefoxInstance += 1
- elif client.match(Match(wm_class = 'discord')) or client.match(Match(wm_class = 'cinny')):
+ elif client.match(Match(wm_class = 'discord')) or client.match(Match(wm_class = 'telegram-desktop')) or client.match(Match(wm_class = 'cinny')):
client.togroup(groups[8].name)
# Turn off fullscreen on unfocus
@@ 0,0 1,695 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2011-2012 Dustin Lacewell
+# Copyright (c) 2011 Mounier Florian
+# Copyright (c) 2012 Craig Barnes
+# Copyright (c) 2012 Maximilian Köhl
+# Copyright (c) 2012, 2014-2015 Tycho Andersen
+# Copyright (c) 2013 jpic
+# Copyright (c) 2013 babadoo
+# Copyright (c) 2013 Jure Ham
+# Copyright (c) 2013 Tao Sauvage
+# Copyright (c) 2014 ramnes
+# Copyright (c) 2014 Sean Vig
+# Copyright (c) 2014 dmpayton
+# Copyright (c) 2014 dequis
+# Copyright (c) 2014 Florian Scherf
+# Copyright (c) 2017 Dirk Hartmann
+# Copyright (c) 2021 Jakob Helmecke
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+from libqtile.layout.base import _SimpleLayoutBase
+
+
+class MonadTall(_SimpleLayoutBase):
+ """Emulate the behavior of XMonad's default tiling scheme.
+
+ Master-Pane:
+
+ A master pane that contains a set number of windows takes up a vertical portion of
+ the screen_rect based on the ratio setting. This ratio can be adjusted with
+ the ``cmd_grow_master`` and ``cmd_shrink_master``.
+
+ ::
+
+ ---------------------
+ | | |
+ | | |
+ | | |
+ | | |
+ | | |
+ | | |
+ ---------------------
+
+ Using the ``cmd_flip`` method will switch which horizontal side the master
+ pane will occupy. The master pane is considered the "top" of the stack.
+
+ ::
+
+ ---------------------
+ | | |
+ | | |
+ | | |
+ | | |
+ | | |
+ | | |
+ ---------------------
+
+ Slave-panes:
+
+ Occupying the rest of the screen_rect are one or more slave panes. The
+ slave panes will share the vertical space of the screen_rect.
+
+ ::
+
+ ---------------------
+ | | |
+ | |______|
+ | | |
+ | |______|
+ | | |
+ | | |
+ ---------------------
+
+ Panes can be moved with the ``cmd_shuffle_up`` and ``cmd_shuffle_down``
+ methods. As mentioned the master pane is considered the top of the stack;
+ moving up is counter-clockwise and moving down is clockwise.
+
+ The opposite is true if the layout is "flipped".
+
+ ::
+
+ --------------------- ---------------------
+ | | 2 | | 2 | |
+ | |______| |_______| |
+ | | 3 | | 3 | |
+ | 1 |______| |_______| 1 |
+ | | 4 | | 4 | |
+ | | | | | |
+ --------------------- ---------------------
+
+
+ Normalizing/Resetting:
+
+ To restore master slave ratio use the ``cmd_normalize`` method.
+
+ To reset the layout to its default state, including the master
+ windows, master slave ratio and flip, use the ``cmd_reset`` method.
+
+ Maximizing:
+
+ To toggle a maximized layout, showing a single window, simply use the
+ ``cmd_maximize`` on a focused client.
+
+ Suggested Bindings::
+ # these mirror the xmonad default config
+
+ Key([modkey], "j", lazy.layout.down()),
+ Key([modkey], "k", lazy.layout.up()),
+ Key([modkey, "shift"], "j", lazy.layout.shuffle_down()),
+ Key([modkey, "shift"], "k", lazy.layout.shuffle_up()),
+ Key([modkey], "h", lazy.layout.shink_master()),
+ Key([modkey], "l", lazy.layout.grow_master()),
+ Key([modkey], "n", lazy.layout.normalize()),
+ Key([modkey], "m", lazy.layout.master()),
+ Key([modkey], "comma", lazy.layout.decrease_nmaster()),
+ Key([modkey], "period", lazy.layout.increase_nmaster()),
+ Key([modkey], "Return", lazy.layout.swap_master())
+
+ # keybindings not in xmonad default config
+
+ Key([modkey, "shift"], "n", lazy.layout.reset()),
+ Key([modkey], "space", lazy.layout.flip()),
+ Key([modkey, "shift"], "space", lazy.layout.flip_master()),
+ Key([modkey, "shift"], "m", lazy.layout.maximize()),
+ """
+
+ _left = 0
+ _right = 1
+ _vert = 0
+ _hori = 1
+ _med_ratio = 0.5
+
+ defaults = [
+ ("border_focus", "#ff0000", "Border colour(s) for the focused window."),
+ ("border_normal", "#000000", "Border colour(s) for un-focused windows."),
+ ("border_width", 2, "Border width."),
+ ("single_border_width", None, "Border width for single window"),
+ ("single_margin", None, "Margin size for single window"),
+ ("margin", 0, "Margin of the layout"),
+ (
+ "ratio",
+ 0.5,
+ "The percent of the screen-space the master pane should occupy by default.",
+ ),
+ (
+ "min_ratio",
+ 0.25,
+ "The percent of the screen-space the master pane should occupy at minimum.",
+ ),
+ (
+ "max_ratio",
+ 0.75,
+ "The percent of the screen-space the master pane should occupy at maximum.",
+ ),
+ (
+ "align",
+ _left,
+ "Which side master plane will be placed (one of ``MonadTall._left`` or "
+ "``MonadTall._right``)",
+ ),
+ ("change_ratio", 0.05, "Resize ratio"),
+ (
+ "new_client_position",
+ "before_current",
+ "Place new windows: "
+ " after_current - after the active window."
+ " before_current - before the active window,"
+ " top - at the top of the stack,"
+ " bottom - at the bottom of the stack,",
+ ),
+ (
+ "master_length",
+ 1,
+ "Amount of windows displayed in the master stack. Surplus windows will be moved to "
+ "the slave stack.",
+ ),
+ (
+ "orientation",
+ _vert,
+ "Orientation in which master windows will be "
+ "placed (one of ``MonadTall._vert`` or ``MonadTall._hori``)",
+ ),
+ ("maximized", False, "Start maximized"),
+ ]
+
+ def __init__(self, **config):
+ _SimpleLayoutBase.__init__(self, **config)
+ self.add_defaults(MonadTall.defaults)
+ if self.single_border_width is None:
+ self.single_border_width = self.border_width
+ if self.single_margin is None:
+ self.single_margin = self.margin
+ self.screen_rect = None
+
+ @property
+ def focused(self):
+ return self.clients.current_index
+
+ @property
+ def master_windows(self):
+ return self.clients[: self.master_length]
+
+ @property
+ def slave_windows(self):
+ return self.clients[self.master_length :]
+
+ def clone(self, group):
+ "Clone layout for other groups"
+ c = _SimpleLayoutBase.clone(self, group)
+ c.screen_rect = group.screen.get_rect() if group.screen else None
+ c.ratio = self.ratio
+ c.align = self.align
+ c.orientation = self.orientation
+ return c
+
+ def add(self, client):
+ "Add client to layout"
+ self.clients.add(client, client_position=self.new_client_position)
+ self.do_normalize = True
+
+ def remove(self, client):
+ "Remove client from layout"
+ self.do_normalize = True
+ return self.clients.remove(client)
+
+ def cmd_normalize(self, redraw=True):
+ "Evenly distribute screen-space between master and slave pane"
+ if redraw:
+ self.ratio = self._med_ratio
+ self.group.layout_all()
+ self.do_normalize = False
+
+ def cmd_reset(self, redraw=True):
+ "Reset Layout."
+ self.ratio = self._med_ratio
+ if self.align == self._right:
+ self.align = self._left
+ if self.orientation == self._hori:
+ self.orientation = self._vert
+ self.master_length = 1
+ self.cmd_normalize(redraw)
+
+ def cmd_maximize(self):
+ "Grow the currently focused client to the max size"
+ if self.maximized:
+ self.maximized = False
+ else:
+ self.maximized = True
+ self.group.layout_all()
+
+ def configure(self, client, screen_rect):
+ "Position client based on order and sizes"
+ self.screen_rect = screen_rect
+
+ if self.do_normalize:
+ self.cmd_normalize(False)
+
+ # if client not in this layout
+ if not self.clients or client not in self.clients:
+ client.hide()
+ return
+
+ # determine focus border-color
+ if client.has_focus:
+ px = self.border_focus
+ else:
+ px = self.border_normal
+
+ # single client - fullscreen
+ if len(self.clients) == 1 or self.maximized:
+ if self.clients and client is self.clients.current_client:
+ client.place(
+ self.screen_rect.x,
+ self.screen_rect.y,
+ self.screen_rect.width - 2 * self.single_border_width,
+ self.screen_rect.height - 2 * self.single_border_width,
+ self.single_border_width,
+ px,
+ margin=self.single_margin,
+ )
+ client.unhide()
+ else:
+ client.hide()
+ return
+
+ cidx = self.clients.index(client)
+ self._configure_specific(client, screen_rect, px, cidx)
+ client.unhide()
+
+ def _configure_specific(self, client, screen_rect, px, cidx):
+ """Specific configuration for xmonad tall."""
+ self.screen_rect = screen_rect
+
+ # calculate master/slave pane size
+ width_master = int(self.screen_rect.width * self.ratio)
+ width_slave = self.screen_rect.width - width_master
+
+ if len(self.master_windows) == 0:
+ width_master = 0
+ width_slave = self.screen_rect.width
+ if len(self.slave_windows) == 0:
+ width_master = self.screen_rect.width
+ width_slave = 0
+
+ # calculate client's x offset
+ if self.align == self._left: # left or up orientation
+ if client in self.master_windows:
+ # master client
+ xpos = self.screen_rect.x
+ else:
+ # slave client
+ xpos = self.screen_rect.x + width_master
+ else: # right or down orientation
+ if client in self.master_windows:
+ # master client
+ xpos = self.screen_rect.x + width_slave - self.margin
+ else:
+ # slave client
+ xpos = self.screen_rect.x
+
+ # calculate client height and place
+ if client in self.slave_windows:
+ pos = self.clients.index(client)
+ # slave client
+ width = width_slave - 2 * self.border_width
+ # ypos is the sum of all clients above it
+ height = self.screen_rect.height // len(self.slave_windows)
+ ypos = self.screen_rect.y + self.clients[self.master_length :].index(client) * height
+ # fix double margin
+ if cidx > 1:
+ ypos -= self.margin
+ height += self.margin
+ # place client based on calculated dimensions
+ client.place(
+ xpos,
+ ypos,
+ width,
+ height - 2 * self.border_width,
+ self.border_width,
+ px,
+ margin=self.margin,
+ )
+ else:
+ pos = self.clients.index(client)
+ if self.orientation == self._vert:
+ height = self.screen_rect.height // self.master_length
+ width = width_master
+ ypos = self.screen_rect.y + pos * height
+ else:
+ height = self.screen_rect.height
+ width = width_master // self.master_length
+ overflow = width_master % self.master_length
+ ypos = self.screen_rect.y
+ if self.align == self._left:
+ xpos = self.screen_rect.x + pos * width + overflow
+ else:
+ xpos = self.screen_rect.x + width_slave + pos * width
+
+ # master client
+ client.place(
+ xpos,
+ ypos,
+ width,
+ height,
+ self.border_width,
+ px,
+ margin=[
+ self.margin,
+ 2 * self.border_width,
+ self.margin + 2 * self.border_width,
+ self.margin,
+ ],
+ )
+
+ def info(self):
+ d = _SimpleLayoutBase.info(self)
+ d.update(
+ dict(
+ master=[c.name for c in self.master_windows],
+ slave=[c.name for c in self.slave_windows],
+ )
+ )
+ return d
+
+ def _grow_master(self, amt):
+ """Will grow the client that is currently in the master pane"""
+ self.ratio += amt
+ self.ratio = min(self.max_ratio, self.ratio)
+
+ def cmd_grow_master(self):
+ """Grow master pane
+
+ Will grow the master pane, reducing the size of clients in the slave
+ pane.
+ """
+ self._grow_master(self.change_ratio)
+ self.group.layout_all()
+
+ def cmd_shrink_master(self):
+ """Shrink master pane
+
+ Will shrink the master pane, increasing the size of clients in the
+ slave pane.
+ """
+ self._shrink_master(self.change_ratio)
+ self.group.layout_all()
+
+ def _shrink_master(self, amt):
+ """Will shrink the client that currently in the master pane"""
+ self.ratio -= amt
+ self.ratio = max(self.min_ratio, self.ratio)
+
+ cmd_next = _SimpleLayoutBase.next
+ cmd_previous = _SimpleLayoutBase.previous
+
+ cmd_up = cmd_previous
+ cmd_down = cmd_next
+
+ def cmd_shuffle_up(self):
+ """Shuffle the client up the stack"""
+ self.clients.shuffle_up()
+ self.group.layout_all()
+ self.group.focus(self.clients.current_client)
+
+ def cmd_shuffle_down(self):
+ """Shuffle the client down the stack"""
+ self.clients.shuffle_down()
+ self.group.layout_all()
+ self.group.focus(self.clients[self.focused])
+
+ def cmd_flip(self):
+ """Flip the layout horizontally"""
+ self.align = self._left if self.align == self._right else self._right
+ self.group.layout_all()
+
+ def cmd_swap(self, window1, window2):
+ """Swap two windows"""
+ self.clients.swap(window1, window2, 1)
+ self.group.layout_all()
+ self.group.focus(window1)
+
+ def cmd_swap_master(self):
+ """Swap current window to master pane"""
+ win = self.clients.current_client
+ cidx = self.clients.index(win)
+
+ if cidx < self.master_length - 1:
+ target = self.clients[cidx + 1]
+ else:
+ target = self.clients[0]
+
+ self.cmd_swap(win, target)
+
+ def cmd_decrease_nmaster(self):
+ """Decrease number of windows in master pane"""
+ self.master_length -= 1
+ if self.master_length <= 0:
+ self.master_length = 0
+ self.group.layout_all()
+
+ def cmd_increase_nmaster(self):
+ """Increase number of windows in master pane"""
+ self.master_length += 1
+ if self.master_length >= len(self.clients):
+ self.master_length = len(self.clients)
+ self.group.layout_all()
+
+ def cmd_master(self):
+ """Focus windows in master pane"""
+ win = self.clients.current_client
+ cidx = self.clients.index(win)
+ if cidx < self.master_length - 1:
+ self.group.focus(self.clients[cidx + 1])
+ else:
+ self.group.focus(self.clients[0])
+
+ def cmd_flip_master(self):
+ """Flip the layout horizontally"""
+ self.orientation = self._vert if self.orientation == self._hori else self._hori
+ self.group.layout_all()
+
+
+class MonadWide(MonadTall):
+ """Emulate the behavior of XMonad's horizontal tiling scheme.
+
+ This layout attempts to emulate the behavior of XMonad wide
+ tiling scheme.
+
+ Master-Pane:
+
+ A master pane that contains a single window takes up a horizontal
+ portion of the screen_rect based on the ratio setting. This ratio can be
+ adjusted with the ``cmd_grow_master`` and ``cmd_shrink_master`` or.
+
+ ::
+
+ ---------------------
+ | |
+ | |
+ | |
+ |___________________|
+ | |
+ | |
+ ---------------------
+
+ Using the ``cmd_flip`` method will switch which vertical side the
+ master pane will occupy. The master pane is considered the "top" of
+ the stack.
+
+ ::
+
+ ---------------------
+ | |
+ |___________________|
+ | |
+ | |
+ | |
+ | |
+ ---------------------
+
+ Slave-panes:
+
+ Occupying the rest of the screen_rect are one or more slave panes.
+ The slave panes will share the horizontal space of the screen_rect.
+
+ ::
+
+ ---------------------
+ | |
+ | |
+ | |
+ |___________________|
+ | | | |
+ | | | |
+ ---------------------
+
+ Panes can be moved with the ``cmd_shuffle_up`` and ``cmd_shuffle_down``
+ methods. As mentioned the master pane is considered the top of the
+ stack; moving up is counter-clockwise and moving down is clockwise.
+
+ The opposite is true if the layout is "flipped".
+
+ ::
+
+ --------------------- ---------------------
+ | | | 2 | 3 | 4 |
+ | 1 | |_____|_______|_____|
+ | | | |
+ |___________________| | |
+ | | | | | 1 |
+ | 2 | 3 | 4 | | |
+ --------------------- ---------------------
+
+ Normalizing/Resetting:
+
+ To restore master slave ratio use the ``cmd_normalize`` method.
+
+ To reset the layout to its default state, including the master
+ windows, master slave ratio and flip, use the ``cmd_reset`` method.
+
+ Maximizing:
+
+ To toggle a maximized layout, showing a single window, simply use the
+ ``cmd_maximize`` on a focused client.
+
+ Suggested Bindings::
+ # these mirror the xmonad default config
+
+ Key([modkey], "j", lazy.layout.down()),
+ Key([modkey], "k", lazy.layout.up()),
+ Key([modkey, "shift"], "j", lazy.layout.shuffle_down()),
+ Key([modkey, "shift"], "k", lazy.layout.shuffle_up()),
+ Key([modkey], "h", lazy.layout.shink_master()),
+ Key([modkey], "l", lazy.layout.grow_master()),
+ Key([modkey], "n", lazy.layout.normalize()),
+ Key([modkey], "m", lazy.layout.master()),
+ Key([modkey], "comma", lazy.layout.decrease_nmaster()),
+ Key([modkey], "period", lazy.layout.increase_nmaster()),
+ Key([modkey], "Return", lazy.layout.swap_master())
+
+ # keybindings not in xmonad default config
+
+ Key([modkey, "shift"], "n", lazy.layout.reset()),
+ Key([modkey], "space", lazy.layout.flip()),
+ Key([modkey, "shift"], "space", lazy.layout.flip_master()),
+ Key([modkey, "shift"], "m", lazy.layout.maximize()),
+ """
+
+ _up = 0
+ _down = 1
+ _hori = 0
+ _vert = 1
+
+ def _configure_specific(self, client, screen_rect, px, cidx):
+ """Specific configuration for xmonad wide."""
+ self.screen_rect = screen_rect
+
+ # calculate master/slave column widths
+ height_master = int(self.screen_rect.height * self.ratio)
+ height_slave = self.screen_rect.height - height_master
+
+ if len(self.master_windows) == 0:
+ height_master = 0
+ height_slave = self.screen_rect.height
+ if len(self.slave_windows) == 0:
+ height_master = self.screen_rect.height
+ height_slave = 0
+
+ # calculate client's x offset
+ if self.align == self._up: # up orientation
+ if client in self.master_windows:
+ # master client
+ ypos = self.screen_rect.y
+ else:
+ # slave client
+ ypos = self.screen_rect.y + height_master
+ else: # right or down orientation
+ if client in self.master_windows:
+ # master client
+ ypos = self.screen_rect.y + height_slave - self.margin
+ else:
+ # slave client
+ ypos = self.screen_rect.y
+
+ # calculate client height and place
+ if client in self.slave_windows:
+ # slave client
+ height = height_slave - 2 * self.border_width
+ # xpos is the sum of all clients left of it
+ width = self.screen_rect.width // len(self.slave_windows)
+ xpos = self.screen_rect.x + self.clients[self.master_length :].index(client) * width
+ # get width from precalculated width list
+ width = self.screen_rect.width // len(self.slave_windows)
+
+ # fix double margin
+ if cidx > 1:
+ xpos -= self.margin
+ width += self.margin
+ # place client based on calculated dimensions
+ client.place(
+ xpos,
+ ypos,
+ width - 2 * self.border_width,
+ height,
+ self.border_width,
+ px,
+ margin=self.margin,
+ )
+ else:
+ pos = self.clients.index(client)
+ if self.orientation == self._hori:
+ width = self.screen_rect.width // self.master_length
+ height = height_master
+ xpos = self.screen_rect.x + pos * width
+ else:
+ width = self.screen_rect.width
+ height = height_master // self.master_length
+ overflow = height_master % self.master_length
+ xpos = self.screen_rect.x
+ if self.align == self._up:
+ ypos = self.screen_rect.y + pos * height + overflow
+ else:
+ ypos = self.screen_rect.y + height_slave + pos * height
+
+ # master client
+ client.place(
+ xpos,
+ ypos,
+ width,
+ height,
+ self.border_width,
+ px,
+ margin=[
+ self.margin,
+ self.margin + 2 * self.border_width,
+ 2 * self.border_width,
+ self.margin,
+ ],
+ )