diff --git a/docs/changelog.rst b/docs/changelog.rst index 34a215d21..75d39a35a 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -121,6 +121,8 @@ Detailed list of changes - A new setting :opt:`remember_window_position` to optionally use the position of the last closed kitty OS Window as the position of the first kitty OS Window when running a new kitty instance (:pull:`8601`) +- Panel kitten: A new ``center-sized`` value for :option:`--edge ` to allow easily creating sized and centered panels + 0.42.0 [2025-05-11] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/glfw/cocoa_window.m b/glfw/cocoa_window.m index 6d7f99dbf..d9d8f30b5 100644 --- a/glfw/cocoa_window.m +++ b/glfw/cocoa_window.m @@ -2031,6 +2031,11 @@ _glfwPlatformSetLayerShellConfig(_GLFWwindow* window, const GLFWLayerShellConfig x += width - panel_width + 1.; width = panel_width; break; + case GLFW_EDGE_CENTER_SIZED: + x += (width - panel_width) / 2; + y += (height - panel_height) / 2; + width = panel_width; height = panel_height; + break; default: // top left y += height - panel_height + 1.; height = panel_height; width = panel_width; @@ -2040,8 +2045,10 @@ _glfwPlatformSetLayerShellConfig(_GLFWwindow* window, const GLFWLayerShellConfig if (height < 1.) height = NSWidth(screen.visibleFrame); } - x += config.requested_left_margin; width -= config.requested_left_margin + config.requested_right_margin; - y += config.requested_bottom_margin; height -= config.requested_top_margin + config.requested_bottom_margin; + if (config.edge != GLFW_EDGE_CENTER_SIZED) { + x += config.requested_left_margin; width -= config.requested_left_margin + config.requested_right_margin; + y += config.requested_bottom_margin; height -= config.requested_top_margin + config.requested_bottom_margin; + } [nswindow setAnimationBehavior:animation_behavior]; [nswindow setLevel:level]; diff --git a/glfw/glfw3.h b/glfw/glfw3.h index 53ac074f2..79a14f9cc 100644 --- a/glfw/glfw3.h +++ b/glfw/glfw3.h @@ -1302,7 +1302,7 @@ typedef struct GLFWkeyevent typedef enum { GLFW_LAYER_SHELL_NONE, GLFW_LAYER_SHELL_BACKGROUND, GLFW_LAYER_SHELL_PANEL, GLFW_LAYER_SHELL_TOP, GLFW_LAYER_SHELL_OVERLAY } GLFWLayerShellType; -typedef enum { GLFW_EDGE_TOP, GLFW_EDGE_BOTTOM, GLFW_EDGE_LEFT, GLFW_EDGE_RIGHT, GLFW_EDGE_CENTER, GLFW_EDGE_NONE } GLFWEdge; +typedef enum { GLFW_EDGE_TOP, GLFW_EDGE_BOTTOM, GLFW_EDGE_LEFT, GLFW_EDGE_RIGHT, GLFW_EDGE_CENTER, GLFW_EDGE_NONE, GLFW_EDGE_CENTER_SIZED } GLFWEdge; typedef enum { GLFW_FOCUS_NOT_ALLOWED, GLFW_FOCUS_EXCLUSIVE, GLFW_FOCUS_ON_DEMAND} GLFWFocusPolicy; diff --git a/glfw/wl_window.c b/glfw/wl_window.c index 0363c1f0f..e75232545 100644 --- a/glfw/wl_window.c +++ b/glfw/wl_window.c @@ -1028,12 +1028,13 @@ layer_set_properties(const _GLFWwindow *window, bool during_creation, uint32_t w if (!config.override_exclusive_zone) exclusive_zone = width; break; case GLFW_EDGE_CENTER: - which_anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT | ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM; + break; + case GLFW_EDGE_CENTER_SIZED: + panel_width = width; panel_height = height; break; case GLFW_EDGE_NONE: which_anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP; - panel_width = width; - panel_height = height; + panel_width = width; panel_height = height; break; } } diff --git a/glfw/x11_window.c b/glfw/x11_window.c index 90bbbbfa6..6f16ee686 100644 --- a/glfw/x11_window.c +++ b/glfw/x11_window.c @@ -606,6 +606,11 @@ calculate_layer_geometry(_GLFWwindow *window) { ans.width = m.width - config.requested_right_margin - config.requested_left_margin; ans.struts[s.bottom] = ans.height; ans.struts[s.bottom_end_x] = ans.width; break; + case GLFW_EDGE_CENTER_SIZED: + ans.needs_strut = false; + ans.x = (m.width - ans.width) / 2; + ans.y = (m.height - ans.height) / 2; + break; default: ans.needs_strut = false; ans.x = m.x + config.requested_left_margin; diff --git a/kittens/panel/main.py b/kittens/panel/main.py index c491ef967..d61e17779 100644 --- a/kittens/panel/main.py +++ b/kittens/panel/main.py @@ -13,6 +13,7 @@ from kitty.constants import is_macos, kitten_exe from kitty.fast_data_types import ( GLFW_EDGE_BOTTOM, GLFW_EDGE_CENTER, + GLFW_EDGE_CENTER_SIZED, GLFW_EDGE_LEFT, GLFW_EDGE_NONE, GLFW_EDGE_RIGHT, @@ -66,7 +67,8 @@ def layer_shell_config(opts: PanelCLIOptions) -> LayerShellConfig: }.get(opts.layer, GLFW_LAYER_SHELL_PANEL) ltype = GLFW_LAYER_SHELL_BACKGROUND if opts.edge == 'background' else ltype edge = { - 'top': GLFW_EDGE_TOP, 'bottom': GLFW_EDGE_BOTTOM, 'left': GLFW_EDGE_LEFT, 'right': GLFW_EDGE_RIGHT, 'center': GLFW_EDGE_CENTER, 'none': GLFW_EDGE_NONE + 'top': GLFW_EDGE_TOP, 'bottom': GLFW_EDGE_BOTTOM, 'left': GLFW_EDGE_LEFT, 'right': GLFW_EDGE_RIGHT, + 'center': GLFW_EDGE_CENTER, 'none': GLFW_EDGE_NONE, 'center-sized': GLFW_EDGE_CENTER_SIZED, }.get(opts.edge, GLFW_EDGE_TOP) focus_policy = { 'not-allowed': GLFW_FOCUS_NOT_ALLOWED, 'exclusive': GLFW_FOCUS_EXCLUSIVE, 'on-demand': GLFW_FOCUS_ON_DEMAND diff --git a/kitty/fast_data_types.pyi b/kitty/fast_data_types.pyi index fb7779286..afd361de3 100644 --- a/kitty/fast_data_types.pyi +++ b/kitty/fast_data_types.pyi @@ -25,6 +25,7 @@ GLFW_EDGE_BOTTOM: int GLFW_EDGE_LEFT: int GLFW_EDGE_RIGHT: int GLFW_EDGE_CENTER: int +GLFW_EDGE_CENTER_SIZED: int GLFW_EDGE_NONE: int GLFW_FOCUS_NOT_ALLOWED: int GLFW_FOCUS_EXCLUSIVE: int diff --git a/kitty/glfw-wrapper.h b/kitty/glfw-wrapper.h index a485b3b04..83866e713 100644 --- a/kitty/glfw-wrapper.h +++ b/kitty/glfw-wrapper.h @@ -1040,7 +1040,7 @@ typedef struct GLFWkeyevent typedef enum { GLFW_LAYER_SHELL_NONE, GLFW_LAYER_SHELL_BACKGROUND, GLFW_LAYER_SHELL_PANEL, GLFW_LAYER_SHELL_TOP, GLFW_LAYER_SHELL_OVERLAY } GLFWLayerShellType; -typedef enum { GLFW_EDGE_TOP, GLFW_EDGE_BOTTOM, GLFW_EDGE_LEFT, GLFW_EDGE_RIGHT, GLFW_EDGE_CENTER, GLFW_EDGE_NONE } GLFWEdge; +typedef enum { GLFW_EDGE_TOP, GLFW_EDGE_BOTTOM, GLFW_EDGE_LEFT, GLFW_EDGE_RIGHT, GLFW_EDGE_CENTER, GLFW_EDGE_NONE, GLFW_EDGE_CENTER_SIZED } GLFWEdge; typedef enum { GLFW_FOCUS_NOT_ALLOWED, GLFW_FOCUS_EXCLUSIVE, GLFW_FOCUS_ON_DEMAND} GLFWFocusPolicy; diff --git a/kitty/glfw.c b/kitty/glfw.c index cf8bd2d21..60787bd11 100644 --- a/kitty/glfw.c +++ b/kitty/glfw.c @@ -1231,7 +1231,7 @@ edge_spacing(GLFWEdge which) { case GLFW_EDGE_BOTTOM: edge = "bottom"; break; case GLFW_EDGE_LEFT: edge = "left"; break; case GLFW_EDGE_RIGHT: edge = "right"; break; - case GLFW_EDGE_CENTER: case GLFW_EDGE_NONE: return 0; + case GLFW_EDGE_CENTER: case GLFW_EDGE_NONE: case GLFW_EDGE_CENTER_SIZED: return 0; } if (!edge_spacing_func) { log_error("Attempt to call edge_spacing() without first setting edge_spacing_func"); @@ -2690,6 +2690,7 @@ init_glfw(PyObject *m) { ADDC(GLFW_LAYER_SHELL_NONE); ADDC(GLFW_LAYER_SHELL_PANEL); ADDC(GLFW_LAYER_SHELL_BACKGROUND); ADDC(GLFW_LAYER_SHELL_TOP); ADDC(GLFW_LAYER_SHELL_OVERLAY); ADDC(GLFW_FOCUS_NOT_ALLOWED); ADDC(GLFW_FOCUS_EXCLUSIVE); ADDC(GLFW_FOCUS_ON_DEMAND); ADDC(GLFW_EDGE_TOP); ADDC(GLFW_EDGE_BOTTOM); ADDC(GLFW_EDGE_LEFT); ADDC(GLFW_EDGE_RIGHT); ADDC(GLFW_EDGE_CENTER); ADDC(GLFW_EDGE_NONE); + ADDC(GLFW_EDGE_CENTER_SIZED); ADDC(GLFW_COLOR_SCHEME_NO_PREFERENCE); ADDC(GLFW_COLOR_SCHEME_DARK); ADDC(GLFW_COLOR_SCHEME_LIGHT); /* start glfw functional keys (auto generated by gen-key-constants.py do not edit) */ diff --git a/kitty/simple_cli_definitions.py b/kitty/simple_cli_definitions.py index dd3f17d43..86a34651e 100644 --- a/kitty/simple_cli_definitions.py +++ b/kitty/simple_cli_definitions.py @@ -601,20 +601,21 @@ Only works on macOS and Wayland compositors that supports the wlr layer shell pr --edge -choices=top,bottom,left,right,background,center,none +choices=top,bottom,left,right,background,center,center-sized,none default={edge} Which edge of the screen to place the panel on. Note that some window managers (such as i3) do not support placing docked windows on the left and right edges. The value :code:`background` means make the panel the "desktop wallpaper". Note that when using sway if you set a background in your sway config it will cover the background drawn using this kitten. -Additionally, there are two more values: :code:`center` and :code:`none`. +Additionally, there are three more values: :code:`center`, :code:`center-sized` and :code:`none`. The value :code:`center` anchors the panel to all sides and covers the entire display (on macOS the part of the display not covered by titlebar and dock). The panel can be shrunk and placed using the margin parameters. The value :code:`none` anchors the panel to the top left corner and should be placed and using the margin parameters. Its size is set by :option:`--lines` -and :option:`--columns`. +and :option:`--columns`. The value :code:`center-sized` is just like :code:`none` except +that the panel is centered instead of in the top left corner and the margins have no effect. --layer