From fb1803bc625af2cfc381863a27e20de9f954fb7b Mon Sep 17 00:00:00 2001 From: elParaguayo Date: Sat, 11 May 2024 19:37:46 +0100 Subject: [PATCH] Add modified Plasma layout --- docs/index.rst | 9 +++ docs/manual/how_to/layouts.rst | 19 ++++++ docs/manual/ref/layouts.rst | 11 +++ qtile_extras/layout/__init__.py | 2 + qtile_extras/layout/_mods.py | 20 ++++++ qtile_extras/layout/plasma.py | 117 ++++++++++++++++++++++++++++++++ 6 files changed, 178 insertions(+) create mode 100644 docs/manual/how_to/layouts.rst create mode 100644 docs/manual/ref/layouts.rst create mode 100644 qtile_extras/layout/_mods.py create mode 100644 qtile_extras/layout/plasma.py diff --git a/docs/index.rst b/docs/index.rst index 2b6b1e58..74f622c6 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -25,6 +25,13 @@ I've also added some "eye candy" in the form of: - :ref:`Window Border Decorations ` - :ref:`Wallpapers ` +Next up, we have modified layouts to benefit from the new window border +decorations. See :ref:`here` for more details. + +The modified layouts are: + +.. list_objects:: qtile_extras.layout._mods + Lastly, I've created a new ``ImgMask`` class which, rather than drawing the source image, uses the source as a mask for the drawing. This can be used to change the colour of icons without needing to recrate the icons themselves. You can see the class :ref:`here `. @@ -46,6 +53,7 @@ without needing to recrate the icons themselves. You can see the class :ref:`her manual/how_to/popup manual/how_to/decorations manual/how_to/borders + manual/how_to/layouts manual/how_to/img-mask manual/how_to/tooltips @@ -58,6 +66,7 @@ without needing to recrate the icons themselves. You can see the class :ref:`her manual/ref/hooks manual/ref/popup manual/ref/decorations + manual/ref/layouts manual/ref/borders manual/ref/imgmask diff --git a/docs/manual/how_to/layouts.rst b/docs/manual/how_to/layouts.rst new file mode 100644 index 00000000..53856d13 --- /dev/null +++ b/docs/manual/how_to/layouts.rst @@ -0,0 +1,19 @@ +.. _layouts: + +======= +Layouts +======= + +Modified versions of stock layouts may provide some additional functionality +which benefits from items available in qtile-extras. + +To prevent the need for multiple imports, all layouts are available via +qtile-extras. You can therefore use a single import in your config: + +.. code:: python + + # from libqtile import layout + from qtile_extras import layout + +To see details of modified layouts, please click +:ref:`here`. diff --git a/docs/manual/ref/layouts.rst b/docs/manual/ref/layouts.rst new file mode 100644 index 00000000..3c7024b4 --- /dev/null +++ b/docs/manual/ref/layouts.rst @@ -0,0 +1,11 @@ +.. _ref_layouts: + +======= +Layouts +======= + +.. qtile_module:: qtile_extras.layout._mods + :baseclass: libqtile.layout.base.Layout + :exclude-base: + :no-commands: + :show-config: \ No newline at end of file diff --git a/qtile_extras/layout/__init__.py b/qtile_extras/layout/__init__.py index 25bc2016..7af19e90 100644 --- a/qtile_extras/layout/__init__.py +++ b/qtile_extras/layout/__init__.py @@ -18,3 +18,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. from libqtile.layout import * # noqa: F401, F403 + +from qtile_extras.layout._mods import * # noqa: F401, F403 diff --git a/qtile_extras/layout/_mods.py b/qtile_extras/layout/_mods.py new file mode 100644 index 00000000..03ed1686 --- /dev/null +++ b/qtile_extras/layout/_mods.py @@ -0,0 +1,20 @@ +# Copyright (c) 2024 elParaguayo +# +# 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 qtile_extras.layout.plasma import Plasma # noqa: F401 diff --git a/qtile_extras/layout/plasma.py b/qtile_extras/layout/plasma.py new file mode 100644 index 00000000..79d03651 --- /dev/null +++ b/qtile_extras/layout/plasma.py @@ -0,0 +1,117 @@ +# Copyright (c) 2024 elParaguayo +# +# 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.command.base import expose_command +from libqtile.layout.plasma import AddMode +from libqtile.layout.plasma import Plasma as QtilePlasma + + +class Plasma(QtilePlasma): + """ + This is a modified version of the Plasma layout in the main qtile repo. + + The change is to add new ``border_highlight_...`` parameters which can be used to + highlight the add_mode for the current window. These values will benefit from + the new window border decorations in qtile-extras i.e. single edges can now be + highlighted. + + To have this behaviour enabled by default, you should set ``highlight=True``. + Alternatively, the behaviour can be toggled with ``lazy.layout.toggle_highlight()``. + """ + + defaults = [ + ("highlight", False, "Highlights the add_mode for the layout."), + ("border_highlight_vertical", None, "Border for focused window with vertical add_mode."), + ( + "border_highlight_vertical_split", + None, + "Border for focused window with vertical split add_mode.", + ), + ( + "border_highlight_horizontal", + None, + "Border for focused window with horizontal add_mode.", + ), + ( + "border_highlight_horizontal_split", + None, + "Border for focused window with horizontal add_mode.", + ), + ] + + def __init__(self, **config): + QtilePlasma.__init__(self, **config) + self.add_defaults(Plasma.defaults) + + self.highlights = { + AddMode.VERTICAL: self.border_highlight_vertical, + AddMode.VERTICAL | AddMode.SPLIT: self.border_highlight_vertical_split, + AddMode.HORIZONTAL: self.border_highlight_horizontal, + AddMode.HORIZONTAL | AddMode.SPLIT: self.border_highlight_horizontal_split, + } + + def configure(self, client, screen_rect): + self.root.x = screen_rect.x + self.root.y = screen_rect.y + self.root.width = screen_rect.width + self.root.height = screen_rect.height + node = self.root.find_payload(client) + border_width = self.border_width_single if self.root.tree == [node] else self.border_width + border_color = getattr( + self, + "border_" + + ("focus" if client.has_focus else "normal") + + ("" if node.flexible else "_fixed"), + ) + + if client is self.focused and self.highlight: + if self.horizontal: + if self.split: + add_mode = AddMode.HORIZONTAL | AddMode.SPLIT + else: + add_mode = AddMode.HORIZONTAL + else: + if self.split: + add_mode = AddMode.VERTICAL | AddMode.SPLIT + else: + add_mode = AddMode.VERTICAL + + highlight = self.highlights[add_mode] + + border_color = highlight if highlight else border_color + + x, y, width, height = node.pixel_perfect + client.place( + x, + y, + width - 2 * border_width, + height - 2 * border_width, + border_width, + border_color, + margin=self.margin, + ) + # Always keep tiles below floating windows + client.unhide() + + @expose_command + def toggle_highlight(self): + """Toggle window border highlighting.""" + if self.group is not None: + self.highlight = not self.highlight + self.group.layout_all()