Start work on full panel support in X11
This commit is contained in:
parent
04fbf63eab
commit
f04fc251bf
16 changed files with 261 additions and 309 deletions
|
|
@ -3252,6 +3252,7 @@ GLFWAPI GLFWColorScheme glfwGetCurrentSystemColorTheme(bool query_if_unintialize
|
|||
return _glfwPlatformGetNativeKeyForKey(glfw_key);
|
||||
}
|
||||
|
||||
GLFWAPI bool glfwIsLayerShellSupported(void) { return true; }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW internal API //////
|
||||
|
|
|
|||
|
|
@ -323,7 +323,6 @@ def generate_wrappers(glfw_header: str) -> None:
|
|||
void glfwWaylandRunWithActivationToken(GLFWwindow *handle, GLFWactivationcallback cb, void *cb_data)
|
||||
bool glfwWaylandSetTitlebarColor(GLFWwindow *handle, uint32_t color, bool use_system_color)
|
||||
void glfwWaylandRedrawCSDWindowTitle(GLFWwindow *handle)
|
||||
bool glfwWaylandIsLayerShellSupported(void)
|
||||
bool glfwWaylandIsWindowFullyCreated(GLFWwindow *handle)
|
||||
bool glfwWaylandBeep(GLFWwindow *handle)
|
||||
GLFWLayerShellConfig* glfwWaylandLayerShellConfig(GLFWwindow *handle)
|
||||
|
|
@ -331,8 +330,6 @@ def generate_wrappers(glfw_header: str) -> None:
|
|||
unsigned long long glfwDBusUserNotify(const GLFWDBUSNotificationData *n, GLFWDBusnotificationcreatedfun callback, void *data)
|
||||
void glfwDBusSetUserNotificationHandler(GLFWDBusnotificationactivatedfun handler)
|
||||
int glfwSetX11LaunchCommand(GLFWwindow *handle, char **argv, int argc)
|
||||
void glfwSetX11WindowAsDock(int32_t x11_window_id)
|
||||
void glfwSetX11WindowStrut(int32_t x11_window_id, uint32_t dimensions[12])
|
||||
'''.splitlines():
|
||||
if line:
|
||||
functions.append(Function(line.strip(), check_fail=False))
|
||||
|
|
|
|||
1
glfw/glfw3.h
vendored
1
glfw/glfw3.h
vendored
|
|
@ -1977,6 +1977,7 @@ GLFWAPI GLFWdrawtextfun glfwSetDrawTextFunction(GLFWdrawtextfun function);
|
|||
GLFWAPI GLFWcurrentselectionfun glfwSetCurrentSelectionCallback(GLFWcurrentselectionfun callback);
|
||||
GLFWAPI GLFWhascurrentselectionfun glfwSetHasCurrentSelectionCallback(GLFWhascurrentselectionfun callback);
|
||||
GLFWAPI GLFWimecursorpositionfun glfwSetIMECursorPositionCallback(GLFWimecursorpositionfun callback);
|
||||
GLFWAPI bool glfwIsLayerShellSupported(void);
|
||||
|
||||
/*! @brief Terminates the GLFW library.
|
||||
*
|
||||
|
|
|
|||
5
glfw/internal.h
vendored
5
glfw/internal.h
vendored
|
|
@ -668,6 +668,10 @@ struct _GLFWlibrary
|
|||
//
|
||||
extern _GLFWlibrary _glfw;
|
||||
|
||||
typedef struct GeometryRect { int x, y, width, height; } GeometryRect;
|
||||
typedef struct MonitorGeometry {
|
||||
GeometryRect full, workarea;
|
||||
} MonitorGeometry;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW platform API //////
|
||||
|
|
@ -878,6 +882,7 @@ unsigned long long _glfwPlatformAddTimer(monotonic_t interval, bool repeats, GLF
|
|||
void _glfwPlatformUpdateTimer(unsigned long long timer_id, monotonic_t interval, bool enabled);
|
||||
void _glfwPlatformRemoveTimer(unsigned long long timer_id);
|
||||
int _glfwPlatformSetWindowBlur(_GLFWwindow* handle, int value);
|
||||
MonitorGeometry _glfwPlatformGetMonitorGeometry(_GLFWmonitor* monitor);
|
||||
|
||||
char* _glfw_strdup(const char* source);
|
||||
|
||||
|
|
|
|||
9
glfw/wl_window.c
vendored
9
glfw/wl_window.c
vendored
|
|
@ -1054,8 +1054,10 @@ calculate_layer_size(_GLFWwindow *window, uint32_t *width, uint32_t *height) {
|
|||
const GLFWLayerShellConfig *config = &window->wl.layer_shell.config;
|
||||
GLFWvidmode m = {0};
|
||||
if (window->wl.monitorsCount) _glfwPlatformGetVideoMode(window->wl.monitors[0], &m);
|
||||
int monitor_width = m.width, monitor_height = m.height;
|
||||
const int y_margin = config->requested_bottom_margin + config->requested_top_margin, x_margin = config->requested_left_margin + config->requested_right_margin;
|
||||
const int monitor_width = MAX(0, m.width - x_margin), monitor_height = MAX(0, m.height - y_margin);
|
||||
monitor_width = monitor_width > x_margin ? monitor_width - x_margin : 0;
|
||||
monitor_height = monitor_height > y_margin ? monitor_height - y_margin : 0;
|
||||
float xscale = (float)config->expected.xscale, yscale = (float)config->expected.yscale;
|
||||
if (window->wl.window_fully_created) _glfwPlatformGetWindowContentScale(window, &xscale, &yscale);
|
||||
unsigned cell_width, cell_height; double left_edge_spacing, top_edge_spacing, right_edge_spacing, bottom_edge_spacing;
|
||||
|
|
@ -1089,6 +1091,7 @@ calculate_layer_size(_GLFWwindow *window, uint32_t *width, uint32_t *height) {
|
|||
*width = (uint32_t)(1. + spacing_x);
|
||||
*height = (uint32_t)(1. + spacing_y);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -1101,8 +1104,6 @@ layer_surface_handle_configure(void* data, struct zwlr_layer_surface_v1* surface
|
|||
window->wl.once.surface_configured = true;
|
||||
update_fully_created_on_configure(window);
|
||||
}
|
||||
GLFWvidmode m = {0};
|
||||
if (window->wl.monitorsCount) _glfwPlatformGetVideoMode(window->wl.monitors[0], &m);
|
||||
calculate_layer_size(window, &width, &height);
|
||||
zwlr_layer_surface_v1_ack_configure(surface, serial);
|
||||
if ((int)width != window->wl.width || (int)height != window->wl.height) {
|
||||
|
|
@ -2895,7 +2896,7 @@ GLFWAPI GLFWLayerShellConfig* glfwWaylandLayerShellConfig(GLFWwindow *handle) {
|
|||
return &((_GLFWwindow*)handle)->wl.layer_shell.config;
|
||||
}
|
||||
|
||||
GLFWAPI bool glfwWaylandIsLayerShellSupported(void) { return _glfw.wl.zwlr_layer_shell_v1 != NULL; }
|
||||
GLFWAPI bool glfwIsLayerShellSupported(void) { return _glfw.wl.zwlr_layer_shell_v1 != NULL; }
|
||||
|
||||
GLFWAPI bool glfwWaylandIsWindowFullyCreated(GLFWwindow *handle) { return handle != NULL && ((_GLFWwindow*)handle)->wl.window_fully_created; }
|
||||
|
||||
|
|
|
|||
10
glfw/x11_init.c
vendored
10
glfw/x11_init.c
vendored
|
|
@ -124,6 +124,8 @@ static void detectEWMH(void)
|
|||
getAtomIfSupported(supportedAtoms, atomCount, "_NET_WM_STATE");
|
||||
_glfw.x11.NET_WM_STATE_ABOVE =
|
||||
getAtomIfSupported(supportedAtoms, atomCount, "_NET_WM_STATE_ABOVE");
|
||||
_glfw.x11.NET_WM_STATE_BELOW =
|
||||
getAtomIfSupported(supportedAtoms, atomCount, "_NET_WM_STATE_BELOW");
|
||||
_glfw.x11.NET_WM_STATE_FULLSCREEN =
|
||||
getAtomIfSupported(supportedAtoms, atomCount, "_NET_WM_STATE_FULLSCREEN");
|
||||
_glfw.x11.NET_WM_STATE_MAXIMIZED_VERT =
|
||||
|
|
@ -132,6 +134,12 @@ static void detectEWMH(void)
|
|||
getAtomIfSupported(supportedAtoms, atomCount, "_NET_WM_STATE_MAXIMIZED_HORZ");
|
||||
_glfw.x11.NET_WM_STATE_DEMANDS_ATTENTION =
|
||||
getAtomIfSupported(supportedAtoms, atomCount, "_NET_WM_STATE_DEMANDS_ATTENTION");
|
||||
_glfw.x11.NET_WM_STATE_SKIP_TASKBAR =
|
||||
getAtomIfSupported(supportedAtoms, atomCount, "_NET_WM_STATE_SKIP_TASKBAR");
|
||||
_glfw.x11.NET_WM_STATE_SKIP_PAGER =
|
||||
getAtomIfSupported(supportedAtoms, atomCount, "_NET_WM_STATE_SKIP_PAGER");
|
||||
_glfw.x11.NET_WM_STATE_STICKY =
|
||||
getAtomIfSupported(supportedAtoms, atomCount, "_NET_WM_STATE_STICKY");
|
||||
_glfw.x11.NET_WM_FULLSCREEN_MONITORS =
|
||||
getAtomIfSupported(supportedAtoms, atomCount, "_NET_WM_FULLSCREEN_MONITORS");
|
||||
_glfw.x11.NET_WM_WINDOW_TYPE =
|
||||
|
|
@ -140,6 +148,8 @@ static void detectEWMH(void)
|
|||
getAtomIfSupported(supportedAtoms, atomCount, "_NET_WM_WINDOW_TYPE_NORMAL");
|
||||
_glfw.x11.NET_WM_WINDOW_TYPE_DOCK =
|
||||
getAtomIfSupported(supportedAtoms, atomCount, "_NET_WM_WINDOW_TYPE_DOCK");
|
||||
_glfw.x11.NET_WM_WINDOW_TYPE_DESKTOP =
|
||||
getAtomIfSupported(supportedAtoms, atomCount, "_NET_WM_WINDOW_TYPE_DESKTOP");
|
||||
_glfw.x11.NET_WORKAREA =
|
||||
getAtomIfSupported(supportedAtoms, atomCount, "_NET_WORKAREA");
|
||||
_glfw.x11.NET_CURRENT_DESKTOP =
|
||||
|
|
|
|||
101
glfw/x11_monitor.c
vendored
101
glfw/x11_monitor.c
vendored
|
|
@ -350,96 +350,79 @@ void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor UNUSED,
|
|||
*yscale = _glfw.x11.contentScaleY;
|
||||
}
|
||||
|
||||
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, int* xpos, int* ypos, int* width, int* height)
|
||||
{
|
||||
int areaX = 0, areaY = 0, areaWidth = 0, areaHeight = 0;
|
||||
|
||||
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
|
||||
{
|
||||
MonitorGeometry
|
||||
_glfwPlatformGetMonitorGeometry(_GLFWmonitor *monitor) {
|
||||
MonitorGeometry ans = {0};
|
||||
if (!monitor) return ans;
|
||||
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken) {
|
||||
XRRScreenResources* sr =
|
||||
XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
|
||||
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
|
||||
|
||||
areaX = ci->x;
|
||||
areaY = ci->y;
|
||||
ans.full.x = ci->x;
|
||||
ans.full.y = ci->y;
|
||||
|
||||
const XRRModeInfo* mi = getModeInfo(sr, ci->mode);
|
||||
|
||||
if (ci->rotation == RR_Rotate_90 || ci->rotation == RR_Rotate_270)
|
||||
{
|
||||
areaWidth = mi->height;
|
||||
areaHeight = mi->width;
|
||||
}
|
||||
else
|
||||
{
|
||||
areaWidth = mi->width;
|
||||
areaHeight = mi->height;
|
||||
if (ci->rotation == RR_Rotate_90 || ci->rotation == RR_Rotate_270) {
|
||||
ans.full.width = mi->height;
|
||||
ans.full.height = mi->width;
|
||||
} else {
|
||||
ans.full.width = mi->width;
|
||||
ans.full.height = mi->height;
|
||||
}
|
||||
|
||||
XRRFreeCrtcInfo(ci);
|
||||
XRRFreeScreenResources(sr);
|
||||
} else {
|
||||
ans.full.width = DisplayWidth(_glfw.x11.display, _glfw.x11.screen);
|
||||
ans.full.height = DisplayHeight(_glfw.x11.display, _glfw.x11.screen);
|
||||
}
|
||||
else
|
||||
{
|
||||
areaWidth = DisplayWidth(_glfw.x11.display, _glfw.x11.screen);
|
||||
areaHeight = DisplayHeight(_glfw.x11.display, _glfw.x11.screen);
|
||||
}
|
||||
ans.workarea = *(&ans.full);
|
||||
|
||||
if (_glfw.x11.NET_WORKAREA && _glfw.x11.NET_CURRENT_DESKTOP)
|
||||
{
|
||||
if (_glfw.x11.NET_WORKAREA && _glfw.x11.NET_CURRENT_DESKTOP) {
|
||||
Atom* extents = NULL;
|
||||
Atom* desktop = NULL;
|
||||
const unsigned long extentCount =
|
||||
_glfwGetWindowPropertyX11(_glfw.x11.root,
|
||||
_glfw.x11.NET_WORKAREA,
|
||||
XA_CARDINAL,
|
||||
(unsigned char**) &extents);
|
||||
const unsigned long extentCount = _glfwGetWindowPropertyX11(
|
||||
_glfw.x11.root, _glfw.x11.NET_WORKAREA, XA_CARDINAL, (unsigned char**) &extents);
|
||||
|
||||
if (_glfwGetWindowPropertyX11(_glfw.x11.root,
|
||||
_glfw.x11.NET_CURRENT_DESKTOP,
|
||||
XA_CARDINAL,
|
||||
(unsigned char**) &desktop) > 0)
|
||||
{
|
||||
if (extentCount >= 4 && *desktop < extentCount / 4)
|
||||
{
|
||||
if (_glfwGetWindowPropertyX11(_glfw.x11.root, _glfw.x11.NET_CURRENT_DESKTOP, XA_CARDINAL, (unsigned char**) &desktop) > 0) {
|
||||
if (extentCount >= 4 && *desktop < extentCount / 4) {
|
||||
const int globalX = extents[*desktop * 4 + 0];
|
||||
const int globalY = extents[*desktop * 4 + 1];
|
||||
const int globalWidth = extents[*desktop * 4 + 2];
|
||||
const int globalHeight = extents[*desktop * 4 + 3];
|
||||
|
||||
if (areaX < globalX)
|
||||
{
|
||||
areaWidth -= globalX - areaX;
|
||||
areaX = globalX;
|
||||
if (ans.workarea.x < globalX) {
|
||||
ans.workarea.width -= globalX - ans.workarea.x;
|
||||
ans.workarea.x = globalX;
|
||||
}
|
||||
|
||||
if (areaY < globalY)
|
||||
{
|
||||
areaHeight -= globalY - areaY;
|
||||
areaY = globalY;
|
||||
if (ans.workarea.y < globalY) {
|
||||
ans.workarea.height -= globalY - ans.workarea.y;
|
||||
ans.workarea.y = globalY;
|
||||
}
|
||||
|
||||
if (areaX + areaWidth > globalX + globalWidth)
|
||||
areaWidth = globalX - areaX + globalWidth;
|
||||
if (areaY + areaHeight > globalY + globalHeight)
|
||||
areaHeight = globalY - areaY + globalHeight;
|
||||
if (ans.workarea.x + ans.workarea.width > globalX + globalWidth)
|
||||
ans.workarea.width = globalX - ans.workarea.x + globalWidth;
|
||||
if (ans.workarea.y + ans.workarea.height > globalY + globalHeight)
|
||||
ans.workarea.height = globalY - ans.workarea.y + globalHeight;
|
||||
}
|
||||
}
|
||||
|
||||
if (extents)
|
||||
XFree(extents);
|
||||
if (desktop)
|
||||
XFree(desktop);
|
||||
if (extents) XFree(extents);
|
||||
if (desktop) XFree(desktop);
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, int* xpos, int* ypos, int* width, int* height) {
|
||||
MonitorGeometry ans = _glfwPlatformGetMonitorGeometry(monitor);
|
||||
if (xpos)
|
||||
*xpos = areaX;
|
||||
*xpos = ans.workarea.x;
|
||||
if (ypos)
|
||||
*ypos = areaY;
|
||||
*ypos = ans.workarea.y;
|
||||
if (width)
|
||||
*width = areaWidth;
|
||||
*width = ans.workarea.width;
|
||||
if (height)
|
||||
*height = areaHeight;
|
||||
*height = ans.workarea.height;
|
||||
}
|
||||
|
||||
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
|
||||
|
|
|
|||
9
glfw/x11_platform.h
vendored
9
glfw/x11_platform.h
vendored
|
|
@ -205,6 +205,10 @@ typedef struct _GLFWwindowX11
|
|||
// The last position the cursor was warped to by GLFW
|
||||
int warpCursorPosX, warpCursorPosY;
|
||||
|
||||
struct {
|
||||
bool is_active;
|
||||
GLFWLayerShellConfig config;
|
||||
} layer_shell;
|
||||
} _GLFWwindowX11;
|
||||
|
||||
typedef struct MimeAtom {
|
||||
|
|
@ -254,12 +258,17 @@ typedef struct _GLFWlibraryX11
|
|||
Atom NET_WM_WINDOW_TYPE;
|
||||
Atom NET_WM_WINDOW_TYPE_NORMAL;
|
||||
Atom NET_WM_WINDOW_TYPE_DOCK;
|
||||
Atom NET_WM_WINDOW_TYPE_DESKTOP;
|
||||
Atom NET_WM_STATE;
|
||||
Atom NET_WM_STATE_ABOVE;
|
||||
Atom NET_WM_STATE_BELOW;
|
||||
Atom NET_WM_STATE_FULLSCREEN;
|
||||
Atom NET_WM_STATE_MAXIMIZED_VERT;
|
||||
Atom NET_WM_STATE_MAXIMIZED_HORZ;
|
||||
Atom NET_WM_STATE_DEMANDS_ATTENTION;
|
||||
Atom NET_WM_STATE_SKIP_TASKBAR;
|
||||
Atom NET_WM_STATE_SKIP_PAGER;
|
||||
Atom NET_WM_STATE_STICKY;
|
||||
Atom NET_WM_BYPASS_COMPOSITOR;
|
||||
Atom NET_WM_FULLSCREEN_MONITORS;
|
||||
Atom NET_WM_WINDOW_OPACITY;
|
||||
|
|
|
|||
266
glfw/x11_window.c
vendored
266
glfw/x11_window.c
vendored
|
|
@ -530,19 +530,172 @@ static void enableCursor(_GLFWwindow* window)
|
|||
updateCursorImage(window);
|
||||
}
|
||||
|
||||
typedef struct WindowGeometry {
|
||||
int x, y, width, height;
|
||||
bool needs_strut;
|
||||
uint32_t struts[12];
|
||||
} WindowGeometry;
|
||||
|
||||
static WindowGeometry
|
||||
calculate_layer_geometry(_GLFWwindow *window) {
|
||||
MonitorGeometry mg = _glfwPlatformGetMonitorGeometry((_GLFWmonitor*)glfwGetPrimaryMonitor());
|
||||
WindowGeometry ans = {0};
|
||||
ans.width = mg.full.width; ans.height = mg.full.height;
|
||||
ans.x = mg.full.x; ans.y = mg.full.y;
|
||||
#define config (window->x11.layer_shell.config)
|
||||
ans.needs_strut = config.type == GLFW_LAYER_SHELL_PANEL;
|
||||
if (config.type == GLFW_LAYER_SHELL_BACKGROUND) return ans;
|
||||
float xscale = (float)config.expected.xscale, yscale = (float)config.expected.yscale;
|
||||
_glfwPlatformGetWindowContentScale(window, &xscale, &yscale);
|
||||
unsigned cell_width, cell_height; double left_edge_spacing, top_edge_spacing, right_edge_spacing, bottom_edge_spacing;
|
||||
config.size_callback((GLFWwindow*)window, xscale, yscale, &cell_width, &cell_height, &left_edge_spacing, &top_edge_spacing, &right_edge_spacing, &bottom_edge_spacing);
|
||||
double spacing_x = left_edge_spacing + right_edge_spacing;
|
||||
double spacing_y = top_edge_spacing + bottom_edge_spacing;
|
||||
double xsz = config.x_size_in_pixels ? (unsigned)(config.x_size_in_pixels * xscale) : (cell_width * config.x_size_in_cells);
|
||||
double ysz = config.y_size_in_pixels ? (unsigned)(config.y_size_in_pixels * yscale) : (cell_height * config.y_size_in_cells);
|
||||
xsz /= xscale; ysz /= yscale;
|
||||
ans.width = (int)(1. + spacing_x + xsz); ans.height = (int)(1. + spacing_y + ysz);
|
||||
GeometryRect m = config.type == GLFW_LAYER_SHELL_TOP || config.type == GLFW_LAYER_SHELL_OVERLAY ? mg.workarea : mg.full;
|
||||
static const struct {
|
||||
uint32_t left, right, top, bottom, left_start_y, left_end_y, right_start_y, right_end_y, top_start_x, top_end_x, bottom_start_x, bottom_end_x;
|
||||
} s = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
|
||||
|
||||
switch (config.edge) {
|
||||
case GLFW_EDGE_LEFT:
|
||||
ans.x = m.x + config.requested_left_margin;
|
||||
ans.y = m.y + config.requested_top_margin;
|
||||
ans.height = m.height - config.requested_bottom_margin - config.requested_top_margin;
|
||||
ans.struts[s.left] = ans.width; ans.struts[s.left_end_y] = ans.height;
|
||||
break;
|
||||
case GLFW_EDGE_RIGHT:
|
||||
ans.x = m.x + m.width - config.requested_right_margin - ans.width;
|
||||
ans.y = m.y + config.requested_top_margin;
|
||||
ans.height = m.height - config.requested_bottom_margin - config.requested_top_margin;
|
||||
ans.struts[s.right] = ans.width; ans.struts[s.right_end_y] = ans.height;
|
||||
break;
|
||||
case GLFW_EDGE_TOP:
|
||||
ans.x = m.x + config.requested_left_margin;
|
||||
ans.y = m.y + config.requested_top_margin;
|
||||
ans.width = m.width - config.requested_right_margin - config.requested_left_margin;
|
||||
ans.struts[s.top] = ans.height; ans.struts[s.top_end_x] = ans.width;
|
||||
break;
|
||||
case GLFW_EDGE_BOTTOM:
|
||||
ans.x = m.x + config.requested_left_margin;
|
||||
ans.y = m.height - config.requested_bottom_margin - ans.height;
|
||||
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;
|
||||
default:
|
||||
ans.needs_strut = false;
|
||||
ans.x = m.x + config.requested_left_margin;
|
||||
ans.y = m.y + config.requested_top_margin;
|
||||
ans.height = m.height - config.requested_bottom_margin - config.requested_top_margin;
|
||||
ans.width = m.width - config.requested_right_margin - config.requested_left_margin;
|
||||
break;
|
||||
}
|
||||
#undef config
|
||||
return ans;
|
||||
}
|
||||
|
||||
GLFWAPI bool glfwIsLayerShellSupported(void) { return _glfw.x11.NET_WM_WINDOW_TYPE != 0 && _glfw.x11.NET_WM_STATE != 0; }
|
||||
|
||||
static void
|
||||
glfwSetX11WindowStrut(_GLFWwindow *window, const uint32_t dimensions[12]) {
|
||||
XChangeProperty(
|
||||
_glfw.x11.display, window->x11.handle, _glfw.x11.NET_WM_STRUT_PARTIAL, XA_CARDINAL, 32, PropModeReplace, (unsigned char*) dimensions, 12);
|
||||
}
|
||||
|
||||
static bool
|
||||
update_wm_hints(_GLFWwindow *window, const WindowGeometry *wg, const _GLFWwndconfig *wndconfig) {
|
||||
XWMHints* hints = XAllocWMHints();
|
||||
bool is_layer_shell = window->x11.layer_shell.is_active;
|
||||
bool ok = false;
|
||||
if (hints) {
|
||||
ok = true;
|
||||
hints->flags = StateHint | InputHint;
|
||||
hints->initial_state = NormalState;
|
||||
hints->input = true;
|
||||
if (is_layer_shell && window->x11.layer_shell.config.type == GLFW_LAYER_SHELL_BACKGROUND) hints->input = false;
|
||||
XSetWMHints(_glfw.x11.display, window->x11.handle, hints);
|
||||
XFree(hints);
|
||||
} else _glfwInputError(GLFW_OUT_OF_MEMORY, "X11: Failed to allocate WM hints");
|
||||
if (_glfw.x11.NET_WM_WINDOW_TYPE) {
|
||||
Atom type = 0;
|
||||
if (window->x11.layer_shell.is_active) {
|
||||
const char *name = NULL;
|
||||
#define S(which) type = _glfw.x11.NET_WM_WINDOW_TYPE_DESKTOP; name = #which
|
||||
switch (window->x11.layer_shell.config.type) {
|
||||
case GLFW_LAYER_SHELL_BACKGROUND: S(NET_WM_WINDOW_TYPE_DESKTOP); break;
|
||||
case GLFW_LAYER_SHELL_PANEL: S(NET_WM_WINDOW_TYPE_DOCK); break;
|
||||
default: S(NET_WM_WINDOW_TYPE_NORMAL); break;
|
||||
}
|
||||
#undef S
|
||||
if (!type) {
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "X11: Window manager does not support _%s", name);
|
||||
ok = false;
|
||||
}
|
||||
} else if (_glfw.x11.NET_WM_WINDOW_TYPE_NORMAL) type = _glfw.x11.NET_WM_WINDOW_TYPE_NORMAL;
|
||||
if (type) XChangeProperty(
|
||||
_glfw.x11.display, window->x11.handle, _glfw.x11.NET_WM_WINDOW_TYPE, XA_ATOM, 32, PropModeReplace, (unsigned char*) &type, 1);
|
||||
} else if (is_layer_shell) {
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "X11: Window manager does not support _NET_WM_WINDOW_TYPE");
|
||||
ok = false;
|
||||
}
|
||||
if (is_layer_shell) {
|
||||
if (_glfw.x11.NET_WM_STRUT_PARTIAL) {
|
||||
glfwSetX11WindowStrut(window, wg->needs_strut ? wg->struts : (uint32_t[12]){0});
|
||||
} else if (wg->needs_strut) {
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "X11: Window manager does not support _NET_WM_STRUT_PARTIAL");
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
if (ok) {
|
||||
updateNormalHints(window, wg->width, wg->height);
|
||||
Atom states[8]; unsigned count = 0;
|
||||
if (is_layer_shell) {
|
||||
_glfwPlatformSetWindowDecorated(window, false);
|
||||
if (_glfw.x11.NET_WM_STATE_STICKY) states[count++] = _glfw.x11.NET_WM_STATE_STICKY;
|
||||
if (_glfw.x11.NET_WM_STATE_SKIP_PAGER) states[count++] = _glfw.x11.NET_WM_STATE_SKIP_PAGER;
|
||||
if (_glfw.x11.NET_WM_STATE_SKIP_TASKBAR) states[count++] = _glfw.x11.NET_WM_STATE_SKIP_TASKBAR;
|
||||
#define S(x) if (_glfw.x11.x) { states[count++] = _glfw.x11.x; } else { _glfwInputError(GLFW_PLATFORM_ERROR, "X11: Window manager does not support _%s", #x); ok = false; }
|
||||
switch (window->x11.layer_shell.config.type) {
|
||||
case GLFW_LAYER_SHELL_NONE: break;
|
||||
case GLFW_LAYER_SHELL_BACKGROUND: case GLFW_LAYER_SHELL_PANEL: S(NET_WM_STATE_BELOW); break;
|
||||
case GLFW_LAYER_SHELL_TOP: case GLFW_LAYER_SHELL_OVERLAY: S(NET_WM_STATE_ABOVE); break;
|
||||
}
|
||||
#undef S
|
||||
} else if (wndconfig) {
|
||||
if (!wndconfig->decorated) _glfwPlatformSetWindowDecorated(window, false);
|
||||
if (_glfw.x11.NET_WM_STATE && !window->monitor) {
|
||||
if (wndconfig->floating) {
|
||||
if (_glfw.x11.NET_WM_STATE_ABOVE) states[count++] = _glfw.x11.NET_WM_STATE_ABOVE;
|
||||
}
|
||||
if (wndconfig->maximized) {
|
||||
if (_glfw.x11.NET_WM_STATE_MAXIMIZED_VERT && _glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ) {
|
||||
states[count++] = _glfw.x11.NET_WM_STATE_MAXIMIZED_VERT;
|
||||
states[count++] = _glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ;
|
||||
window->x11.maximized = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (count && _glfw.x11.NET_WM_STATE) XChangeProperty(_glfw.x11.display, window->x11.handle, _glfw.x11.NET_WM_STATE,
|
||||
XA_ATOM, 32, PropModeReplace, (unsigned char*) states, count);
|
||||
}
|
||||
if (!wndconfig && ok) _glfwPlatformSetWindowPos(window, wg->x, wg->y);
|
||||
return ok;
|
||||
}
|
||||
|
||||
// Create the X11 window (and its colormap)
|
||||
//
|
||||
static bool createNativeWindow(_GLFWwindow* window,
|
||||
const _GLFWwndconfig* wndconfig,
|
||||
Visual* visual, int depth)
|
||||
{
|
||||
int width = wndconfig->width;
|
||||
int height = wndconfig->height;
|
||||
|
||||
if (wndconfig->scaleToMonitor)
|
||||
{
|
||||
width *= (int)_glfw.x11.contentScaleX;
|
||||
height *= (int)_glfw.x11.contentScaleY;
|
||||
WindowGeometry wg = {.width=wndconfig->width, .height=wndconfig->height};
|
||||
if (window->x11.layer_shell.is_active) {
|
||||
wg = calculate_layer_geometry(window);
|
||||
window->resizable = false;
|
||||
}
|
||||
|
||||
// Create a colormap based on the visual used by the current context
|
||||
|
|
@ -565,8 +718,8 @@ static bool createNativeWindow(_GLFWwindow* window,
|
|||
window->x11.parent = _glfw.x11.root;
|
||||
window->x11.handle = XCreateWindow(_glfw.x11.display,
|
||||
_glfw.x11.root,
|
||||
0, 0, // Position
|
||||
width, height,
|
||||
wg.x, wg.y, // Position
|
||||
wg.width, wg.height,
|
||||
0, // Border width
|
||||
depth, // Color depth
|
||||
InputOutput,
|
||||
|
|
@ -588,39 +741,6 @@ static bool createNativeWindow(_GLFWwindow* window,
|
|||
_glfw.x11.context,
|
||||
(XPointer) window);
|
||||
|
||||
if (!wndconfig->decorated)
|
||||
_glfwPlatformSetWindowDecorated(window, false);
|
||||
|
||||
if (_glfw.x11.NET_WM_STATE && !window->monitor)
|
||||
{
|
||||
Atom states[3];
|
||||
int count = 0;
|
||||
|
||||
if (wndconfig->floating)
|
||||
{
|
||||
if (_glfw.x11.NET_WM_STATE_ABOVE)
|
||||
states[count++] = _glfw.x11.NET_WM_STATE_ABOVE;
|
||||
}
|
||||
|
||||
if (wndconfig->maximized)
|
||||
{
|
||||
if (_glfw.x11.NET_WM_STATE_MAXIMIZED_VERT &&
|
||||
_glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ)
|
||||
{
|
||||
states[count++] = _glfw.x11.NET_WM_STATE_MAXIMIZED_VERT;
|
||||
states[count++] = _glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ;
|
||||
window->x11.maximized = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (count)
|
||||
{
|
||||
XChangeProperty(_glfw.x11.display, window->x11.handle,
|
||||
_glfw.x11.NET_WM_STATE, XA_ATOM, 32,
|
||||
PropModeReplace, (unsigned char*) states, count);
|
||||
}
|
||||
}
|
||||
|
||||
// Declare the WM protocols supported by GLFW
|
||||
{
|
||||
Atom protocols[] =
|
||||
|
|
@ -643,32 +763,7 @@ static bool createNativeWindow(_GLFWwindow* window,
|
|||
(unsigned char*) &pid, 1);
|
||||
}
|
||||
|
||||
if (_glfw.x11.NET_WM_WINDOW_TYPE && _glfw.x11.NET_WM_WINDOW_TYPE_NORMAL)
|
||||
{
|
||||
Atom type = _glfw.x11.NET_WM_WINDOW_TYPE_NORMAL;
|
||||
XChangeProperty(_glfw.x11.display, window->x11.handle,
|
||||
_glfw.x11.NET_WM_WINDOW_TYPE, XA_ATOM, 32,
|
||||
PropModeReplace, (unsigned char*) &type, 1);
|
||||
}
|
||||
|
||||
// Set ICCCM WM_HINTS property
|
||||
{
|
||||
XWMHints* hints = XAllocWMHints();
|
||||
if (!hints)
|
||||
{
|
||||
_glfwInputError(GLFW_OUT_OF_MEMORY,
|
||||
"X11: Failed to allocate WM hints");
|
||||
return false;
|
||||
}
|
||||
|
||||
hints->flags = StateHint;
|
||||
hints->initial_state = NormalState;
|
||||
|
||||
XSetWMHints(_glfw.x11.display, window->x11.handle, hints);
|
||||
XFree(hints);
|
||||
}
|
||||
|
||||
updateNormalHints(window, width, height);
|
||||
if (!update_wm_hints(window, &wg, wndconfig)) return false;
|
||||
|
||||
// Set ICCCM WM_CLASS property
|
||||
{
|
||||
|
|
@ -1869,9 +1964,12 @@ void _glfwPushSelectionToManagerX11(void)
|
|||
|
||||
int _glfwPlatformCreateWindow(_GLFWwindow* window, const _GLFWwndconfig* wndconfig, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig, const GLFWLayerShellConfig *lsc)
|
||||
{
|
||||
(void)lsc;
|
||||
Visual* visual = NULL;
|
||||
int depth;
|
||||
if (lsc) {
|
||||
window->x11.layer_shell.is_active = true;
|
||||
window->x11.layer_shell.config = *lsc;
|
||||
} else window->x11.layer_shell.is_active = false;
|
||||
|
||||
if (ctxconfig->client != GLFW_NO_API)
|
||||
{
|
||||
|
|
@ -1964,7 +2062,9 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
|
|||
}
|
||||
|
||||
bool _glfwPlatformSetLayerShellConfig(_GLFWwindow* window, const GLFWLayerShellConfig *value) {
|
||||
(void)window; (void)value;
|
||||
if (value) window->x11.layer_shell.config = *value;
|
||||
WindowGeometry wg = calculate_layer_geometry(window);
|
||||
update_wm_hints(window, &wg, NULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -3273,30 +3373,4 @@ GLFWAPI int glfwSetX11LaunchCommand(GLFWwindow *handle, char **argv, int argc)
|
|||
return XSetCommand(_glfw.x11.display, window->x11.handle, argv, argc);
|
||||
}
|
||||
|
||||
GLFWAPI void glfwSetX11WindowAsDock(int32_t x11_window_id) {
|
||||
_GLFW_REQUIRE_INIT();
|
||||
Atom type = _glfw.x11.NET_WM_WINDOW_TYPE_DOCK;
|
||||
if (!type) {
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "The X11 window manager does not support the NET_WM_WINDOW_TYPE_DOCK Atom, cannot make panels into docks\n");
|
||||
return ;
|
||||
}
|
||||
if (!_glfw.x11.NET_WM_WINDOW_TYPE) {
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "The X11 window manager does not support the NET_WM_WINDOW_TYPE Atom, cannot make panels into docks\n");
|
||||
return ;
|
||||
}
|
||||
XChangeProperty(_glfw.x11.display, x11_window_id,
|
||||
_glfw.x11.NET_WM_WINDOW_TYPE, XA_ATOM, 32,
|
||||
PropModeReplace, (unsigned char*) &type, 1);
|
||||
}
|
||||
|
||||
|
||||
GLFWAPI void glfwSetX11WindowStrut(int32_t x11_window_id, uint32_t dimensions[12]) {
|
||||
_GLFW_REQUIRE_INIT();
|
||||
if (!_glfw.x11.NET_WM_STRUT_PARTIAL) {
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "The X11 window manager does not support the NET_WM_STRUT_PARTIAL Atom, cannot make panels into docks\n");
|
||||
return ;
|
||||
}
|
||||
XChangeProperty(_glfw.x11.display, x11_window_id,
|
||||
_glfw.x11.NET_WM_STRUT_PARTIAL, XA_CARDINAL, 32,
|
||||
PropModeReplace, (unsigned char*) dimensions, 12);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,14 +3,13 @@
|
|||
|
||||
import os
|
||||
import sys
|
||||
from collections.abc import Callable
|
||||
from contextlib import suppress
|
||||
from functools import partial
|
||||
from typing import Any, Iterable, Mapping, Sequence
|
||||
from typing import Iterable, Mapping, Sequence
|
||||
|
||||
from kitty.cli import parse_args
|
||||
from kitty.cli_stub import PanelCLIOptions
|
||||
from kitty.constants import is_macos, is_wayland, kitten_exe
|
||||
from kitty.constants import is_macos, kitten_exe
|
||||
from kitty.fast_data_types import (
|
||||
GLFW_EDGE_BOTTOM,
|
||||
GLFW_EDGE_CENTER,
|
||||
|
|
@ -25,15 +24,12 @@
|
|||
GLFW_LAYER_SHELL_OVERLAY,
|
||||
GLFW_LAYER_SHELL_PANEL,
|
||||
GLFW_LAYER_SHELL_TOP,
|
||||
glfw_primary_monitor_size,
|
||||
make_x11_window_a_dock_window,
|
||||
set_layer_shell_config,
|
||||
toggle_os_window_visibility,
|
||||
)
|
||||
from kitty.os_window_size import WindowSizeData, edge_spacing
|
||||
from kitty.simple_cli_definitions import build_panel_cli_spec
|
||||
from kitty.types import LayerShellConfig
|
||||
from kitty.typing_compat import BossType, EdgeLiteral
|
||||
from kitty.typing_compat import BossType
|
||||
from kitty.utils import log_error
|
||||
|
||||
args = PanelCLIOptions()
|
||||
|
|
@ -51,84 +47,6 @@ def parse_panel_args(args: list[str]) -> tuple[PanelCLIOptions, list[str]]:
|
|||
return parse_args(args, panel_kitten_options_spec, usage, help_text, 'kitty +kitten panel', result_class=PanelCLIOptions)
|
||||
|
||||
|
||||
Strut = tuple[int, int, int, int, int, int, int, int, int, int, int, int]
|
||||
|
||||
|
||||
def create_strut(
|
||||
win_id: int,
|
||||
left: int = 0, right: int = 0, top: int = 0, bottom: int = 0, left_start_y: int = 0, left_end_y: int = 0,
|
||||
right_start_y: int = 0, right_end_y: int = 0, top_start_x: int = 0, top_end_x: int = 0,
|
||||
bottom_start_x: int = 0, bottom_end_x: int = 0
|
||||
) -> Strut:
|
||||
return left, right, top, bottom, left_start_y, left_end_y, right_start_y, right_end_y, top_start_x, top_end_x, bottom_start_x, bottom_end_x
|
||||
|
||||
|
||||
def create_top_strut(win_id: int, width: int, height: int) -> Strut:
|
||||
return create_strut(win_id, top=height, top_end_x=width)
|
||||
|
||||
|
||||
def create_bottom_strut(win_id: int, width: int, height: int) -> Strut:
|
||||
return create_strut(win_id, bottom=height, bottom_end_x=width)
|
||||
|
||||
|
||||
def create_left_strut(win_id: int, width: int, height: int) -> Strut:
|
||||
return create_strut(win_id, left=width, left_end_y=height)
|
||||
|
||||
|
||||
def create_right_strut(win_id: int, width: int, height: int) -> Strut:
|
||||
return create_strut(win_id, right=width, right_end_y=height)
|
||||
|
||||
|
||||
window_width = window_height = 0
|
||||
|
||||
|
||||
def setup_x11_window(win_id: int) -> None:
|
||||
if is_wayland():
|
||||
return
|
||||
try:
|
||||
func = globals()[f'create_{args.edge}_strut']
|
||||
except KeyError:
|
||||
raise SystemExit(f'The value {args.edge} is not supported for --edge on X11')
|
||||
strut = func(win_id, window_width, window_height)
|
||||
make_x11_window_a_dock_window(win_id, strut)
|
||||
|
||||
|
||||
def initial_window_size_func(opts: WindowSizeData, cached_values: dict[str, Any]) -> Callable[[int, int, float, float, float, float], tuple[int, int]]:
|
||||
|
||||
def es(which: EdgeLiteral) -> float:
|
||||
return edge_spacing(which, opts)
|
||||
|
||||
def initial_window_size(cell_width: int, cell_height: int, dpi_x: float, dpi_y: float, xscale: float, yscale: float) -> tuple[int, int]:
|
||||
if not is_macos and not is_wayland():
|
||||
# Not sure what the deal with scaling on X11 is
|
||||
xscale = yscale = 1
|
||||
global window_width, window_height
|
||||
monitor_width, monitor_height = glfw_primary_monitor_size()
|
||||
x = dual_distance(args.columns, min_cell_value_if_no_pixels=1)
|
||||
rwidth = x[1] if x[1] else (x[0] * cell_width / xscale)
|
||||
x = dual_distance(args.lines, min_cell_value_if_no_pixels=1)
|
||||
rheight = x[1] if x[1] else (x[0] * cell_width / yscale)
|
||||
|
||||
if args.edge in {'left', 'right'}:
|
||||
spacing = es('left') + es('right')
|
||||
window_width = int(rwidth + (dpi_x / 72) * spacing + 1)
|
||||
window_height = monitor_height
|
||||
elif args.edge in {'top', 'bottom'}:
|
||||
spacing = es('top') + es('bottom')
|
||||
window_height = int(rheight + (dpi_y / 72) * spacing + 1)
|
||||
window_width = monitor_width
|
||||
elif args.edge in {'background', 'center'}:
|
||||
window_width, window_height = monitor_width, monitor_height
|
||||
else:
|
||||
x_spacing = es('left') + es('right')
|
||||
window_width = int(rwidth + (dpi_x / 72) * x_spacing + 1)
|
||||
y_spacing = es('top') + es('bottom')
|
||||
window_height = int(rheight + (dpi_y / 72) * y_spacing + 1)
|
||||
return window_width, window_height
|
||||
|
||||
return initial_window_size
|
||||
|
||||
|
||||
def dual_distance(spec: str, min_cell_value_if_no_pixels: int = 0) -> tuple[int, int]:
|
||||
with suppress(Exception):
|
||||
return int(spec), 0
|
||||
|
|
@ -259,9 +177,6 @@ def actual_main(sys_args: list[str]) -> None:
|
|||
from kitty.main import run_app
|
||||
run_app.cached_values_name = 'panel'
|
||||
run_app.layer_shell_config = layer_shell_config(args)
|
||||
if not is_macos:
|
||||
run_app.first_window_callback = setup_x11_window
|
||||
run_app.initial_window_size_func = initial_window_size_func
|
||||
real_main(called_from_panel=True)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -458,7 +458,7 @@ def add_os_window(
|
|||
return os_window_id
|
||||
|
||||
def add_os_panel(self, cfg: LayerShellConfig, wclass: str | None = appname, wname: str | None = appname) -> int:
|
||||
if is_macos or not is_wayland() or not is_layer_shell_supported():
|
||||
if not is_layer_shell_supported():
|
||||
raise RuntimeError('Creating desktop panels is not supported on this platform')
|
||||
wclass = wclass or appname
|
||||
wname = wname or appname
|
||||
|
|
|
|||
|
|
@ -1703,7 +1703,6 @@ def get_docs_ref_map() -> bytes: ...
|
|||
def set_clipboard_data_types(ct: int, mime_types: Tuple[str, ...]) -> None: ...
|
||||
def get_clipboard_mime(ct: int, mime: Optional[str], callback: Callable[[bytes], None]) -> None: ...
|
||||
def run_with_activation_token(func: Callable[[str], None]) -> bool: ...
|
||||
def make_x11_window_a_dock_window(x11_window_id: int, strut: Tuple[int, int, int, int, int, int, int, int, int, int, int, int]) -> None: ...
|
||||
def toggle_os_window_visibility(os_window_id: int, visible: Literal[True, False] = ...) -> bool: ...
|
||||
def parse_cli_from_spec(args: list[str], names_map: dict[str, OptionDict], defval_map: dict[str, Any]) -> tuple[dict[str, tuple[Any, bool]], list[str]]: ...
|
||||
def layer_shell_config_for_os_window(os_window_id: int) -> dict[str, Any] | None: ...
|
||||
|
|
|
|||
12
kitty/glfw-wrapper.c
generated
12
kitty/glfw-wrapper.c
generated
|
|
@ -47,6 +47,9 @@ load_glfw(const char* path) {
|
|||
*(void **) (&glfwSetIMECursorPositionCallback_impl) = dlsym(handle, "glfwSetIMECursorPositionCallback");
|
||||
if (glfwSetIMECursorPositionCallback_impl == NULL) fail("Failed to load glfw function glfwSetIMECursorPositionCallback with error: %s", dlerror());
|
||||
|
||||
*(void **) (&glfwIsLayerShellSupported_impl) = dlsym(handle, "glfwIsLayerShellSupported");
|
||||
if (glfwIsLayerShellSupported_impl == NULL) fail("Failed to load glfw function glfwIsLayerShellSupported with error: %s", dlerror());
|
||||
|
||||
*(void **) (&glfwTerminate_impl) = dlsym(handle, "glfwTerminate");
|
||||
if (glfwTerminate_impl == NULL) fail("Failed to load glfw function glfwTerminate with error: %s", dlerror());
|
||||
|
||||
|
|
@ -488,9 +491,6 @@ load_glfw(const char* path) {
|
|||
*(void **) (&glfwWaylandRedrawCSDWindowTitle_impl) = dlsym(handle, "glfwWaylandRedrawCSDWindowTitle");
|
||||
if (glfwWaylandRedrawCSDWindowTitle_impl == NULL) dlerror(); // clear error indicator
|
||||
|
||||
*(void **) (&glfwWaylandIsLayerShellSupported_impl) = dlsym(handle, "glfwWaylandIsLayerShellSupported");
|
||||
if (glfwWaylandIsLayerShellSupported_impl == NULL) dlerror(); // clear error indicator
|
||||
|
||||
*(void **) (&glfwWaylandIsWindowFullyCreated_impl) = dlsym(handle, "glfwWaylandIsWindowFullyCreated");
|
||||
if (glfwWaylandIsWindowFullyCreated_impl == NULL) dlerror(); // clear error indicator
|
||||
|
||||
|
|
@ -512,12 +512,6 @@ load_glfw(const char* path) {
|
|||
*(void **) (&glfwSetX11LaunchCommand_impl) = dlsym(handle, "glfwSetX11LaunchCommand");
|
||||
if (glfwSetX11LaunchCommand_impl == NULL) dlerror(); // clear error indicator
|
||||
|
||||
*(void **) (&glfwSetX11WindowAsDock_impl) = dlsym(handle, "glfwSetX11WindowAsDock");
|
||||
if (glfwSetX11WindowAsDock_impl == NULL) dlerror(); // clear error indicator
|
||||
|
||||
*(void **) (&glfwSetX11WindowStrut_impl) = dlsym(handle, "glfwSetX11WindowStrut");
|
||||
if (glfwSetX11WindowStrut_impl == NULL) dlerror(); // clear error indicator
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
|||
16
kitty/glfw-wrapper.h
generated
16
kitty/glfw-wrapper.h
generated
|
|
@ -1756,6 +1756,10 @@ typedef GLFWimecursorpositionfun (*glfwSetIMECursorPositionCallback_func)(GLFWim
|
|||
GFW_EXTERN glfwSetIMECursorPositionCallback_func glfwSetIMECursorPositionCallback_impl;
|
||||
#define glfwSetIMECursorPositionCallback glfwSetIMECursorPositionCallback_impl
|
||||
|
||||
typedef bool (*glfwIsLayerShellSupported_func)(void);
|
||||
GFW_EXTERN glfwIsLayerShellSupported_func glfwIsLayerShellSupported_impl;
|
||||
#define glfwIsLayerShellSupported glfwIsLayerShellSupported_impl
|
||||
|
||||
typedef void (*glfwTerminate_func)(void);
|
||||
GFW_EXTERN glfwTerminate_func glfwTerminate_impl;
|
||||
#define glfwTerminate glfwTerminate_impl
|
||||
|
|
@ -2344,10 +2348,6 @@ typedef void (*glfwWaylandRedrawCSDWindowTitle_func)(GLFWwindow*);
|
|||
GFW_EXTERN glfwWaylandRedrawCSDWindowTitle_func glfwWaylandRedrawCSDWindowTitle_impl;
|
||||
#define glfwWaylandRedrawCSDWindowTitle glfwWaylandRedrawCSDWindowTitle_impl
|
||||
|
||||
typedef bool (*glfwWaylandIsLayerShellSupported_func)(void);
|
||||
GFW_EXTERN glfwWaylandIsLayerShellSupported_func glfwWaylandIsLayerShellSupported_impl;
|
||||
#define glfwWaylandIsLayerShellSupported glfwWaylandIsLayerShellSupported_impl
|
||||
|
||||
typedef bool (*glfwWaylandIsWindowFullyCreated_func)(GLFWwindow*);
|
||||
GFW_EXTERN glfwWaylandIsWindowFullyCreated_func glfwWaylandIsWindowFullyCreated_impl;
|
||||
#define glfwWaylandIsWindowFullyCreated glfwWaylandIsWindowFullyCreated_impl
|
||||
|
|
@ -2376,12 +2376,4 @@ typedef int (*glfwSetX11LaunchCommand_func)(GLFWwindow*, char**, int);
|
|||
GFW_EXTERN glfwSetX11LaunchCommand_func glfwSetX11LaunchCommand_impl;
|
||||
#define glfwSetX11LaunchCommand glfwSetX11LaunchCommand_impl
|
||||
|
||||
typedef void (*glfwSetX11WindowAsDock_func)(int32_t);
|
||||
GFW_EXTERN glfwSetX11WindowAsDock_func glfwSetX11WindowAsDock_impl;
|
||||
#define glfwSetX11WindowAsDock glfwSetX11WindowAsDock_impl
|
||||
|
||||
typedef void (*glfwSetX11WindowStrut_func)(int32_t, uint32_t[12]);
|
||||
GFW_EXTERN glfwSetX11WindowStrut_func glfwSetX11WindowStrut_impl;
|
||||
#define glfwSetX11WindowStrut glfwSetX11WindowStrut_impl
|
||||
|
||||
const char* load_glfw(const char* path);
|
||||
|
|
|
|||
37
kitty/glfw.c
37
kitty/glfw.c
|
|
@ -1264,17 +1264,11 @@ create_os_window(PyObject UNUSED *self, PyObject *args, PyObject *kw) {
|
|||
window_state = (int) PyLong_AsLong(optional_window_state);
|
||||
}
|
||||
if (layer_shell_config && layer_shell_config != Py_None ) {
|
||||
#ifdef __APPLE__
|
||||
lsc = &lsc_stack;
|
||||
#else
|
||||
if (global_state.is_wayland) {
|
||||
if (!glfwWaylandIsLayerShellSupported()) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "The Wayland compositor does not support the layer shell protocol.");
|
||||
return NULL;
|
||||
}
|
||||
lsc = &lsc_stack;
|
||||
if (!glfwIsLayerShellSupported()) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "The window manager/compositor does not support the primitives needed to make panels.");
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
lsc = &lsc_stack;
|
||||
} else {
|
||||
if (optional_x && optional_x != Py_None) { if (!PyLong_Check(optional_x)) { PyErr_SetString(PyExc_TypeError, "x must be an int"); return NULL;} x = (int)PyLong_AsLong(optional_x); }
|
||||
if (optional_y && optional_y != Py_None) { if (!PyLong_Check(optional_y)) { PyErr_SetString(PyExc_TypeError, "y must be an int"); return NULL;} y = (int)PyLong_AsLong(optional_y); }
|
||||
|
|
@ -2458,29 +2452,9 @@ get_clipboard_mime(PyObject *self UNUSED, PyObject *args) {
|
|||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
make_x11_window_a_dock_window(PyObject *self UNUSED, PyObject *args UNUSED) {
|
||||
int x11_window_id;
|
||||
PyObject *dims;
|
||||
if (!PyArg_ParseTuple(args, "iO!", &x11_window_id, &PyTuple_Type, &dims)) return NULL;
|
||||
if (PyTuple_GET_SIZE(dims) != 12 ) { PyErr_SetString(PyExc_TypeError, "dimensions must be a tuple of length 12"); return NULL; }
|
||||
if (!glfwSetX11WindowAsDock) { PyErr_SetString(PyExc_RuntimeError, "Failed to load glfwGetX11Window"); return NULL; }
|
||||
uint32_t dimensions[12];
|
||||
for (Py_ssize_t i = 0; i < 12; i++) dimensions[i] = PyLong_AsUnsignedLong(PyTuple_GET_ITEM(dims, i));
|
||||
if (PyErr_Occurred()) return NULL;
|
||||
glfwSetX11WindowAsDock(x11_window_id);
|
||||
glfwSetX11WindowStrut(x11_window_id, dimensions);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
is_layer_shell_supported(PyObject *self UNUSED, PyObject *args UNUSED) {
|
||||
#ifdef __APPLE__
|
||||
Py_RETURN_FALSE;
|
||||
#else
|
||||
if (!global_state.is_wayland) Py_RETURN_FALSE;
|
||||
return Py_NewRef(glfwWaylandIsLayerShellSupported() ? Py_True : Py_False);
|
||||
#endif
|
||||
return Py_NewRef(glfwIsLayerShellSupported() ? Py_True : Py_False);
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
|
|
@ -2552,7 +2526,6 @@ static PyMethodDef module_methods[] = {
|
|||
METHODB(get_click_interval, METH_NOARGS),
|
||||
METHODB(is_layer_shell_supported, METH_NOARGS),
|
||||
METHODB(x11_window_id, METH_O),
|
||||
METHODB(make_x11_window_a_dock_window, METH_VARARGS),
|
||||
METHODB(strip_csi, METH_O),
|
||||
#ifndef __APPLE__
|
||||
METHODB(dbus_close_notification, METH_VARARGS),
|
||||
|
|
|
|||
|
|
@ -230,10 +230,8 @@ def _run_app(opts: Options, args: CLIOptions, bad_lines: Sequence[BadLine] = (),
|
|||
else:
|
||||
global_shortcuts = {}
|
||||
set_window_icon()
|
||||
if _is_panel_kitten and is_wayland() and not is_layer_shell_supported():
|
||||
from .debug_config import compositor_name
|
||||
raise SystemExit(
|
||||
f'Cannot create panels as the layer shell protocol is not supported by the compositor: {compositor_name()}')
|
||||
if _is_panel_kitten and not is_layer_shell_supported():
|
||||
raise SystemExit('Cannot create panels as the window manager/compositor does not support the neccessary protocols')
|
||||
|
||||
with cached_values_for(run_app.cached_values_name) as cached_values:
|
||||
startup_sessions = tuple(create_sessions(opts, args, default_session=opts.startup_session))
|
||||
|
|
|
|||
Loading…
Reference in a new issue