diff --git a/glfw/glfw3.h b/glfw/glfw3.h index 1976ea8c7..f1a30cbcb 100644 --- a/glfw/glfw3.h +++ b/glfw/glfw3.h @@ -1317,6 +1317,8 @@ typedef struct GLFWLayerShellConfig { unsigned requested_left_margin; unsigned requested_bottom_margin; unsigned requested_right_margin; + int requested_exclusive_zone; + unsigned override_exclusive_zone; void (*size_callback)(GLFWwindow *window, const struct GLFWLayerShellConfig *config, unsigned monitor_width, unsigned monitor_height, uint32_t *width, uint32_t *height); } GLFWLayerShellConfig; diff --git a/glfw/wl_window.c b/glfw/wl_window.c index ac32e91a3..210e365a7 100644 --- a/glfw/wl_window.c +++ b/glfw/wl_window.c @@ -964,7 +964,7 @@ find_output_by_name(const char* name) { static void layer_set_properties(_GLFWwindow *window) { enum zwlr_layer_surface_v1_anchor which_anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT; - int exclusive_zone = -1; + int exclusive_zone = window->wl.layer_shell.config.requested_exclusive_zone; enum zwlr_layer_surface_v1_keyboard_interactivity focus_policy = ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE; switch(window->wl.layer_shell.config.focus_policy) { case GLFW_FOCUS_NOT_ALLOWED: focus_policy = ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE; break; @@ -973,7 +973,8 @@ layer_set_properties(_GLFWwindow *window) { } int panel_width = 0, panel_height = 0; switch (window->wl.layer_shell.config.type) { - case GLFW_LAYER_SHELL_BACKGROUND: break; case GLFW_LAYER_SHELL_NONE: break; + case GLFW_LAYER_SHELL_NONE: break; + case GLFW_LAYER_SHELL_BACKGROUND: exclusive_zone = -1; break; case GLFW_LAYER_SHELL_TOP: case GLFW_LAYER_SHELL_OVERLAY: case GLFW_LAYER_SHELL_PANEL: @@ -981,27 +982,27 @@ layer_set_properties(_GLFWwindow *window) { case GLFW_EDGE_TOP: which_anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT; panel_height = window->wl.height; - exclusive_zone = window->wl.height; + if (!window->wl.layer_shell.config.override_exclusive_zone) exclusive_zone = window->wl.height; break; case GLFW_EDGE_BOTTOM: which_anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT; panel_height = window->wl.height; - exclusive_zone = window->wl.height; + if (!window->wl.layer_shell.config.override_exclusive_zone) exclusive_zone = window->wl.height; break; case GLFW_EDGE_LEFT: which_anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM; panel_width = window->wl.width; - exclusive_zone = window->wl.width; + if (!window->wl.layer_shell.config.override_exclusive_zone) exclusive_zone = window->wl.width; break; case GLFW_EDGE_RIGHT: which_anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT | ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM; panel_width = window->wl.width; - exclusive_zone = window->wl.width; + if (!window->wl.layer_shell.config.override_exclusive_zone) exclusive_zone = window->wl.width; break; case GLFW_EDGE_NONE: which_anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM; // None is anchored to "top left" panel_width = window->wl.width; - panel_width = window->wl.height; + panel_height = window->wl.height; break; } } diff --git a/kittens/panel/main.py b/kittens/panel/main.py index 33c0743bb..7ff512c64 100644 --- a/kittens/panel/main.py +++ b/kittens/panel/main.py @@ -44,24 +44,28 @@ The number of columns shown in the panel. Ignored for background and horizontal type=int default=0 Request a given top margin to the compositor. +Only works on a Wayland compositor that supports the wlr layer shell protocol. --margin-left type=int default=0 Request a given left margin to the compositor. +Only works on a Wayland compositor that supports the wlr layer shell protocol. --margin-bottom type=int default=0 Request a given bottom margin to the compositor. +Only works on a Wayland compositor that supports the wlr layer shell protocol. --margin-right type=int default=0 Request a given right margin to the compositor. +Only works on a Wayland compositor that supports the wlr layer shell protocol. --edge @@ -72,14 +76,15 @@ Which edge of the screen to place the panel on. Note that some window managers The value :code:`background` means make the panel the "desktop wallpaper". This is only supported on Wayland, not X11 and note that when using sway if you set a background in your sway config it will cover the background drawn using this -kitten. The value :code:`none` allow free placement of the window -when combined with explicit margin parameters. +kitten. +The value :code:`none` anchors the panel to the top left corner by default +and the panel should be placed using margins parameters. --layer choices=background,bottom,top,overlay default=bottom -On a compositor that supports the wlr layer shell protocol, specifies the layer +On a Wayland compositor that supports the wlr layer shell protocol, specifies the layer on which the panel should be drawn. This parameter is ignored and set to :code:`background` if :option:`--edge` is set to :code:`background`. @@ -120,6 +125,22 @@ On a Wayland compositor that supports the wlr layer shell protocol, specify the interactivity with the panel. Please refer to the wlr layer shell protocol documentation for more details. +--exclusive-zone +type=int +default=-1 +On a Wayland compositor that supports the wlr layer shell protocol, request a given exclusive zone for the panel. +Please refer to the wlr layer shell documentation for more details on the meaning of exclusive and its value. +If :option:`--edge` is set to anything else than :code:`none`, this flag will not have any effect unless +the flag :option:`--override-exclusive-zone` is also set. +If :option:`--edge` is set to :code:`background`, this option has no effect. + + +--override-exclusive-zone +type=bool-set +On a Wayland compositor that supports the wlr layer shell protocol, override the default exclusive zone. +This has effect only if :option:`--edge` is set to :code:`top`, :code:`left`, :code:`bottom` or :code:`right`. + + --debug-rendering type=bool-set For internal debugging use. @@ -218,6 +239,8 @@ def layer_shell_config(opts: PanelCLIOptions) -> LayerShellConfig: requested_bottom_margin=max(0, opts.margin_bottom), requested_right_margin=max(0, opts.margin_right), focus_policy=focus_policy, + requested_exclusive_zone=opts.exclusive_zone, + override_exclusive_zone=opts.override_exclusive_zone, output_name=opts.output_name or '') diff --git a/kitty/glfw-wrapper.h b/kitty/glfw-wrapper.h index 8f97338cd..8b2a0a991 100644 --- a/kitty/glfw-wrapper.h +++ b/kitty/glfw-wrapper.h @@ -1055,6 +1055,8 @@ typedef struct GLFWLayerShellConfig { unsigned requested_left_margin; unsigned requested_bottom_margin; unsigned requested_right_margin; + int requested_exclusive_zone; + unsigned override_exclusive_zone; void (*size_callback)(GLFWwindow *window, const struct GLFWLayerShellConfig *config, unsigned monitor_width, unsigned monitor_height, uint32_t *width, uint32_t *height); } GLFWLayerShellConfig; diff --git a/kitty/glfw.c b/kitty/glfw.c index dccaa4934..6882a70ad 100644 --- a/kitty/glfw.c +++ b/kitty/glfw.c @@ -1094,6 +1094,8 @@ translate_layer_shell_config(PyObject *p, GLFWLayerShellConfig *ans) { A(requested_left_margin, PyLong_Check, PyLong_AsLong); A(requested_bottom_margin, PyLong_Check, PyLong_AsLong); A(requested_right_margin, PyLong_Check, PyLong_AsLong); + A(requested_exclusive_zone, PyLong_Check, PyLong_AsLong); + A(override_exclusive_zone, PyBool_Check, PyLong_AsLong); #undef A #define A(attr) { \ RAII_PyObject(attr, PyObject_GetAttrString(p, #attr)); if (attr == NULL) return false; \ diff --git a/kitty/types.py b/kitty/types.py index 4f306c5f6..16f908f8b 100644 --- a/kitty/types.py +++ b/kitty/types.py @@ -78,6 +78,8 @@ class LayerShellConfig(NamedTuple): requested_left_margin: int = 0 requested_bottom_margin: int = 0 requested_right_margin: int = 0 + requested_exclusive_zone: int = -1 + override_exclusive_zone: bool = False def mod_to_names(mods: int, has_kitty_mod: bool = False, kitty_mod: int = 0) -> Iterator[str]: