From ce2bcbb92da6080e7fff06b13a5e9b443932b7d1 Mon Sep 17 00:00:00 2001 From: Robin Carlier <57142648+robin-carlier@users.noreply.github.com> Date: Sat, 23 Nov 2024 17:31:39 +0100 Subject: [PATCH] Panel: add a edge=none option --- glfw/glfw3.h | 5 +++-- glfw/wl_window.c | 4 ++++ kittens/panel/main.py | 17 ++++++++++++----- kitty/fast_data_types.pyi | 1 + kitty/glfw-wrapper.h | 5 +++-- kitty/glfw.c | 21 ++++++++++++++++----- kitty/types.py | 3 ++- 7 files changed, 41 insertions(+), 15 deletions(-) diff --git a/glfw/glfw3.h b/glfw/glfw3.h index f68c34cb8..2a7613f9f 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 } GLFWEdge; +typedef enum { GLFW_EDGE_TOP, GLFW_EDGE_BOTTOM, GLFW_EDGE_LEFT, GLFW_EDGE_RIGHT, GLFW_EDGE_NONE } GLFWEdge; typedef enum { GLFW_FOCUS_NOT_ALLOWED, GLFW_FOCUS_EXCLUSIVE, GLFW_FOCUS_ON_DEMAND} GLFWFocusPolicy; @@ -1311,7 +1311,8 @@ typedef struct GLFWLayerShellConfig { GLFWEdge edge; char output_name[64]; GLFWFocusPolicy focus_policy; - unsigned size_in_cells; + unsigned x_size_in_cells; + unsigned y_size_in_cells; 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 7910f3295..0eb1be6a0 100644 --- a/glfw/wl_window.c +++ b/glfw/wl_window.c @@ -998,6 +998,10 @@ layer_set_properties(_GLFWwindow *window) { panel_width = window->wl.width; exclusive_zone = window->wl.width; break; + case GLFW_EDGE_NONE: + panel_width = window->wl.width; + panel_width = window->wl.height; + break; } } #define surface window->wl.layer_shell.zwlr_layer_surface_v1 diff --git a/kittens/panel/main.py b/kittens/panel/main.py index f2a0b62af..f4a27531f 100644 --- a/kittens/panel/main.py +++ b/kittens/panel/main.py @@ -12,6 +12,7 @@ from kitty.fast_data_types import ( GLFW_EDGE_LEFT, GLFW_EDGE_RIGHT, GLFW_EDGE_TOP, + GLFW_EDGE_NONE, GLFW_LAYER_SHELL_BACKGROUND, GLFW_LAYER_SHELL_PANEL, GLFW_LAYER_SHELL_TOP, @@ -24,14 +25,20 @@ from kitty.types import LayerShellConfig from kitty.typing import EdgeLiteral OPTIONS = r''' ---lines --columns +--lines type=int default=1 -The number of lines shown in the panel if horizontal otherwise the number of columns shown in the panel. Ignored for background panels. +The number of lines shown in the panel if horizontal. Ignored for background panels. + + +--columns +type=int +default=1 +The number of columns shown in the panel if vertical. Ignored for background panels. --edge -choices=top,bottom,left,right,background +choices=top,bottom,left,right,background,none default=top 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. @@ -165,8 +172,8 @@ def layer_shell_config(opts: PanelCLIOptions) -> LayerShellConfig: 'top': GLFW_LAYER_SHELL_TOP, 'overlay': GLFW_LAYER_SHELL_OVERLAY}.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}.get(opts.edge, GLFW_EDGE_TOP) - return LayerShellConfig(type=ltype, edge=edge, size_in_cells=max(1, opts.lines), output_name=opts.output_name or '') + edge = {'top': GLFW_EDGE_TOP, 'bottom': GLFW_EDGE_BOTTOM, 'left': GLFW_EDGE_LEFT, 'right': GLFW_EDGE_RIGHT, 'none': GLFW_EDGE_NONE}.get(opts.edge, GLFW_EDGE_TOP) + return LayerShellConfig(type=ltype, edge=edge, x_size_in_cells=max(1, opts.columns), y_size_in_cells=max(1, opts.lines), output_name=opts.output_name or '') def main(sys_args: List[str]) -> None: diff --git a/kitty/fast_data_types.pyi b/kitty/fast_data_types.pyi index d41313f34..122ebb0a1 100644 --- a/kitty/fast_data_types.pyi +++ b/kitty/fast_data_types.pyi @@ -21,6 +21,7 @@ GLFW_EDGE_TOP: int GLFW_EDGE_BOTTOM: int GLFW_EDGE_LEFT: int GLFW_EDGE_RIGHT: int +GLFW_EDGE_NONE: int GLFW_FOCUS_NOT_ALLOWED: int GLFW_FOCUS_EXCLUSIVE: int GLFW_FOCUS_ON_DEMAND: int diff --git a/kitty/glfw-wrapper.h b/kitty/glfw-wrapper.h index 67f6ef698..7a71c34c7 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 } GLFWEdge; +typedef enum { GLFW_EDGE_TOP, GLFW_EDGE_BOTTOM, GLFW_EDGE_LEFT, GLFW_EDGE_RIGHT, GLFW_EDGE_NONE } GLFWEdge; typedef enum { GLFW_FOCUS_NOT_ALLOWED, GLFW_FOCUS_EXCLUSIVE, GLFW_FOCUS_ON_DEMAND} GLFWFocusPolicy; @@ -1049,7 +1049,8 @@ typedef struct GLFWLayerShellConfig { GLFWEdge edge; char output_name[64]; GLFWFocusPolicy focus_policy; - unsigned size_in_cells; + unsigned x_size_in_cells; + unsigned y_size_in_cells; 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 2a5edc591..af761bcf8 100644 --- a/kitty/glfw.c +++ b/kitty/glfw.c @@ -1029,6 +1029,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_NONE: edge = "top"; break; } if (!edge_spacing_func) { log_error("Attempt to call edge_spacing() without first setting edge_spacing_func"); @@ -1059,14 +1060,23 @@ calculate_layer_shell_window_size( if (!*height) *height = monitor_height; double spacing = edge_spacing(GLFW_EDGE_LEFT) + edge_spacing(GLFW_EDGE_RIGHT); spacing *= xdpi / 72.; - spacing += (fonts_data->cell_width * config->size_in_cells) / xscale; + spacing += (fonts_data->cell_width * config->x_size_in_cells) / xscale; *width = (uint32_t)(1. + spacing); - } else { + } else if (config->edge == GLFW_EDGE_TOP || config->edge == GLFW_EDGE_BOTTOM) { if (!*width) *width = monitor_width; double spacing = edge_spacing(GLFW_EDGE_TOP) + edge_spacing(GLFW_EDGE_BOTTOM); spacing *= ydpi / 72.; - spacing += (fonts_data->cell_height * config->size_in_cells) / yscale; + spacing += (fonts_data->cell_height * config->y_size_in_cells) / yscale; *height = (uint32_t)(1. + spacing); + } else { + double spacing_x = edge_spacing(GLFW_EDGE_LEFT) + edge_spacing(GLFW_EDGE_RIGHT); + spacing_x *= xdpi / 72.; + spacing_x += (fonts_data->cell_width * config->x_size_in_cells) / xscale; + double spacing_y = edge_spacing(GLFW_EDGE_TOP) + edge_spacing(GLFW_EDGE_BOTTOM); + spacing_y *= ydpi / 72.; + spacing_y += (fonts_data->cell_height * config->y_size_in_cells) / yscale; + *width = (uint32_t)(1. + spacing_x); + *height = (uint32_t)(1. + spacing_y); } } @@ -1078,7 +1088,8 @@ translate_layer_shell_config(PyObject *p, GLFWLayerShellConfig *ans) { A(type, PyLong_Check, PyLong_AsLong); A(edge, PyLong_Check, PyLong_AsLong); A(focus_policy, PyLong_Check, PyLong_AsLong); - A(size_in_cells, PyLong_Check, PyLong_AsLong); + A(x_size_in_cells, PyLong_Check, PyLong_AsLong); + A(y_size_in_cells, PyLong_Check, PyLong_AsLong); #undef A #define A(attr) { \ RAII_PyObject(attr, PyObject_GetAttrString(p, #attr)); if (attr == NULL) return false; \ @@ -2353,7 +2364,7 @@ init_glfw(PyObject *m) { ADDC(GLFW_PRIMARY_SELECTION); ADDC(GLFW_CLIPBOARD); 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_TOP); ADDC(GLFW_EDGE_BOTTOM); ADDC(GLFW_EDGE_LEFT); ADDC(GLFW_EDGE_RIGHT); ADDC(GLFW_EDGE_NONE) 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/types.py b/kitty/types.py index 3626f1a3d..abf1a2639 100644 --- a/kitty/types.py +++ b/kitty/types.py @@ -72,7 +72,8 @@ class LayerShellConfig(NamedTuple): edge: int = 0 focus_policy: int = 0 output_name: str = '' - size_in_cells: int = 0 + x_size_in_cells: int = 0 + y_size_in_cells: int = 0 def mod_to_names(mods: int, has_kitty_mod: bool = False, kitty_mod: int = 0) -> Iterator[str]: