Improve handling of output names

Now can use panel --output-name list to list available outputs.
Also, --output-name works on macOS
This commit is contained in:
Kovid Goyal
2025-05-13 15:29:37 +05:30
parent 67c1ce7280
commit 88f4c829eb
15 changed files with 100 additions and 24 deletions

View File

@@ -1570,6 +1570,7 @@ def set_os_window_pos(os_window_id: int, x: int, y: int) -> None:
def get_all_processes() -> Tuple[int, ...]:
pass
def get_monitor_names() -> tuple[tuple[str, str], ...]: ...
def num_users() -> int:
pass

3
kitty/glfw-wrapper.c generated
View File

@@ -89,6 +89,9 @@ load_glfw(const char* path) {
*(void **) (&glfwGetMonitorName_impl) = dlsym(handle, "glfwGetMonitorName");
if (glfwGetMonitorName_impl == NULL) fail("Failed to load glfw function glfwGetMonitorName with error: %s", dlerror());
*(void **) (&glfwGetMonitorDescription_impl) = dlsym(handle, "glfwGetMonitorDescription");
if (glfwGetMonitorDescription_impl == NULL) fail("Failed to load glfw function glfwGetMonitorDescription with error: %s", dlerror());
*(void **) (&glfwSetMonitorUserPointer_impl) = dlsym(handle, "glfwSetMonitorUserPointer");
if (glfwSetMonitorUserPointer_impl == NULL) fail("Failed to load glfw function glfwSetMonitorUserPointer with error: %s", dlerror());

6
kitty/glfw-wrapper.h generated
View File

@@ -1052,7 +1052,7 @@ typedef struct GLFWLayerShellConfig {
int requested_top_margin, requested_left_margin, requested_bottom_margin, requested_right_margin;
} previous;
bool was_toggled_to_fullscreen;
char output_name[64];
char output_name[128];
GLFWFocusPolicy focus_policy;
unsigned x_size_in_cells, x_size_in_pixels;
unsigned y_size_in_cells, y_size_in_pixels;
@@ -1817,6 +1817,10 @@ typedef const char* (*glfwGetMonitorName_func)(GLFWmonitor*);
GFW_EXTERN glfwGetMonitorName_func glfwGetMonitorName_impl;
#define glfwGetMonitorName glfwGetMonitorName_impl
typedef const char* (*glfwGetMonitorDescription_func)(GLFWmonitor*);
GFW_EXTERN glfwGetMonitorDescription_func glfwGetMonitorDescription_impl;
#define glfwGetMonitorDescription glfwGetMonitorDescription_impl
typedef void (*glfwSetMonitorUserPointer_func)(GLFWmonitor*, void*);
GFW_EXTERN glfwSetMonitorUserPointer_func glfwSetMonitorUserPointer_impl;
#define glfwSetMonitorUserPointer glfwSetMonitorUserPointer_impl

View File

@@ -2143,6 +2143,23 @@ get_monitor_workarea(PYNOARG) {
return Py_NewRef(result);
}
static PyObject*
get_monitor_names(PYNOARG) {
int count = 0;
GLFWmonitor **monitors = glfwGetMonitors(&count);
if (count <= 0 || !monitors) return PyTuple_New(0);
RAII_PyObject(result, PyTuple_New(count)); if (!result) return NULL;
for (int i = 0; i < count; i++) {
const char *name = glfwGetMonitorName(monitors[i]);
const char *description = glfwGetMonitorDescription(monitors[i]);
PyObject *x = Py_BuildValue("ss", name, description);
if (!x) return NULL;
PyTuple_SET_ITEM(result, i, x);
}
return Py_NewRef(result);
}
static PyObject*
primary_monitor_content_scale(PYNOARG) {
GLFWmonitor* monitor = glfwGetPrimaryMonitor();
@@ -2643,6 +2660,7 @@ static PyMethodDef module_methods[] = {
{"glfw_get_system_color_theme", (PyCFunction)glfw_get_system_color_theme, METH_VARARGS, ""},
{"glfw_primary_monitor_size", (PyCFunction)primary_monitor_size, METH_NOARGS, ""},
{"glfw_get_monitor_workarea", (PyCFunction)get_monitor_workarea, METH_NOARGS, ""},
{"glfw_get_monitor_names", (PyCFunction)get_monitor_names, METH_NOARGS, ""},
{"glfw_primary_monitor_content_scale", (PyCFunction)primary_monitor_content_scale, METH_NOARGS, ""},
{NULL, NULL, 0, NULL} /* Sentinel */
};

View File

@@ -38,6 +38,7 @@ from .fast_data_types import (
SingleKey,
create_os_window,
free_font_data,
glfw_get_monitor_names,
glfw_get_monitor_workarea,
glfw_init,
glfw_terminate,
@@ -220,9 +221,30 @@ def is_panel_kitten() -> bool:
return _is_panel_kitten
def list_monitors() -> None:
monitor_names = glfw_get_monitor_names()
has_descriptions = False
for (name, desc) in monitor_names:
if desc:
has_descriptions = True
break
isatty = sys.stdout.isatty()
for (name, desc) in monitor_names:
if isatty:
name = f'\x1b[32m{name}\x1b[39m' # ]]
print(name)
if desc:
print(f'\t{desc}')
if has_descriptions:
print()
def _run_app(opts: Options, args: CLIOptions, bad_lines: Sequence[BadLine] = (), talk_fd: int = -1) -> None:
global _is_panel_kitten
_is_panel_kitten = run_app.cached_values_name == 'panel'
if _is_panel_kitten and run_app.layer_shell_config.output_name == 'list':
list_monitors()
return
if is_macos:
global_shortcuts = set_cocoa_global_shortcuts(opts)
if opts.macos_custom_beam_cursor:

View File

@@ -639,9 +639,10 @@ Syntax: :italic:`name=value`. For example: :option:`kitty +kitten panel -o` font
--output-name
On Wayland or X11, the panel can only be displayed on a single monitor (output) at a time. This allows
The panel can only be displayed on a single monitor (output) at a time. This allows
you to specify which output is used, by name. If not specified the compositor will choose an
output automatically, typically the last output the user interacted with or the primary monitor.
Use the special value :code:`list` to get a list of available outputs.
--class --app-id