Handle all known xdg top level states
This commit is contained in:
parent
f849f383cb
commit
5a1bd93518
8
glfw/wl_client_side_decorations.c
vendored
8
glfw/wl_client_side_decorations.c
vendored
@ -393,16 +393,16 @@ change_csd_title(_GLFWwindow *window) {
|
||||
|
||||
void
|
||||
set_csd_window_geometry(_GLFWwindow *window, int32_t *width, int32_t *height) {
|
||||
bool has_csd = window->decorated && !window->wl.decorations.serverSide && window->wl.decorations.left.surface && !window->wl.fullscreened;
|
||||
bool has_csd = window->decorated && !window->wl.decorations.serverSide && window->wl.decorations.left.surface && !(window->wl.toplevel_states & TOPLEVEL_STATE_FULLSCREEN);
|
||||
bool size_specified_by_compositor = *width > 0 && *height > 0;
|
||||
if (!size_specified_by_compositor) { *width = window->wl.width; *height = window->wl.height; }
|
||||
int32_t scale = window->wl.scale >= 1 ? window->wl.scale : 1;
|
||||
struct { int32_t x, y, width, height; } geometry = {.x = 0, .y = 0, .width = scale * *width, .height = scale * *height};
|
||||
struct { int32_t x, y, width, height; } geometry = {.x = 0, .y = 0, .width = *width, .height = *height};
|
||||
if (has_csd) {
|
||||
// I dont know why GNOME wants geometry.x to be zero, but thats what works
|
||||
geometry.y = -decs.metrics.width * scale;
|
||||
int32_t visible_titlebar_height = decs.metrics.top - decs.metrics.width;
|
||||
geometry.y = -decs.metrics.width;
|
||||
*height -= visible_titlebar_height;
|
||||
}
|
||||
xdg_surface_set_window_geometry(window->wl.xdg.surface, geometry.x, geometry.y, geometry.width, geometry.height);
|
||||
xdg_surface_set_window_geometry(window->wl.xdg.surface, geometry.x * scale, geometry.y * scale, geometry.width * scale, geometry.height * scale);
|
||||
}
|
||||
|
||||
24
glfw/wl_platform.h
vendored
24
glfw/wl_platform.h
vendored
@ -111,6 +111,22 @@ typedef struct _GLFWWaylandCSDEdge {
|
||||
int x, y;
|
||||
} _GLFWWaylandCSDEdge;
|
||||
|
||||
typedef enum WaylandWindowState {
|
||||
|
||||
TOPLEVEL_STATE_NONE = 0,
|
||||
TOPLEVEL_STATE_MAXIMIZED = 1,
|
||||
TOPLEVEL_STATE_FULLSCREEN = 2,
|
||||
TOPLEVEL_STATE_RESIZING = 4,
|
||||
TOPLEVEL_STATE_ACTIVATED = 8,
|
||||
TOPLEVEL_STATE_TILED_LEFT = 16,
|
||||
TOPLEVEL_STATE_TILED_RIGHT = 32,
|
||||
TOPLEVEL_STATE_TILED_TOP = 64,
|
||||
TOPLEVEL_STATE_TILED_BOTTOM = 128,
|
||||
} WaylandWindowState;
|
||||
|
||||
|
||||
static const WaylandWindowState TOPLEVEL_STATE_DOCKED = TOPLEVEL_STATE_MAXIMIZED | TOPLEVEL_STATE_FULLSCREEN | TOPLEVEL_STATE_TILED_TOP | TOPLEVEL_STATE_TILED_LEFT | TOPLEVEL_STATE_TILED_RIGHT | TOPLEVEL_STATE_TILED_BOTTOM;
|
||||
|
||||
|
||||
// Wayland-specific per-window data
|
||||
//
|
||||
@ -118,7 +134,6 @@ typedef struct _GLFWwindowWayland
|
||||
{
|
||||
int width, height;
|
||||
bool visible;
|
||||
bool maximized;
|
||||
bool hovered;
|
||||
bool transparent;
|
||||
struct wl_surface* surface;
|
||||
@ -152,8 +167,6 @@ typedef struct _GLFWwindowWayland
|
||||
|
||||
struct zwp_idle_inhibitor_v1* idleInhibitor;
|
||||
|
||||
bool fullscreened;
|
||||
|
||||
struct {
|
||||
bool serverSide;
|
||||
_GLFWdecorationSideWayland focus;
|
||||
@ -187,7 +200,10 @@ typedef struct _GLFWwindowWayland
|
||||
|
||||
struct {
|
||||
int32_t width, height;
|
||||
} size_before_maximize;
|
||||
} size_before_docking;
|
||||
|
||||
uint32_t toplevel_states;
|
||||
bool maximize_on_first_show;
|
||||
|
||||
} _GLFWwindowWayland;
|
||||
|
||||
|
||||
76
glfw/wl_window.c
vendored
76
glfw/wl_window.c
vendored
@ -389,7 +389,7 @@ static void setFullscreen(_GLFWwindow* window, _GLFWmonitor* monitor, bool on)
|
||||
|
||||
bool
|
||||
_glfwPlatformToggleFullscreen(_GLFWwindow *window, unsigned int flags UNUSED) {
|
||||
bool already_fullscreen = window->wl.fullscreened;
|
||||
bool already_fullscreen = window->wl.toplevel_states & TOPLEVEL_STATE_FULLSCREEN;
|
||||
setFullscreen(window, NULL, !already_fullscreen);
|
||||
return !already_fullscreen;
|
||||
}
|
||||
@ -403,44 +403,41 @@ static void xdgToplevelHandleConfigure(void* data,
|
||||
_GLFWwindow* window = data;
|
||||
float aspectRatio;
|
||||
float targetRatio;
|
||||
uint32_t* state;
|
||||
bool maximized = false;
|
||||
bool fullscreen = false;
|
||||
bool activated = false;
|
||||
enum xdg_toplevel_state* state;
|
||||
uint32_t new_states = 0;
|
||||
const bool report_event = true;
|
||||
if (report_event) printf("top-level configure event: size: %dx%d states: ", width, height);
|
||||
|
||||
wl_array_for_each(state, states)
|
||||
{
|
||||
switch (*state)
|
||||
{
|
||||
case XDG_TOPLEVEL_STATE_MAXIMIZED:
|
||||
maximized = true;
|
||||
break;
|
||||
case XDG_TOPLEVEL_STATE_FULLSCREEN:
|
||||
fullscreen = true;
|
||||
break;
|
||||
case XDG_TOPLEVEL_STATE_RESIZING:
|
||||
break;
|
||||
case XDG_TOPLEVEL_STATE_ACTIVATED:
|
||||
activated = true;
|
||||
break;
|
||||
wl_array_for_each(state, states) {
|
||||
switch (*state) {
|
||||
#define C(x) case XDG_##x: new_states |= x; if (report_event) printf("%s ", #x); break
|
||||
C(TOPLEVEL_STATE_RESIZING);
|
||||
C(TOPLEVEL_STATE_MAXIMIZED);
|
||||
C(TOPLEVEL_STATE_FULLSCREEN);
|
||||
C(TOPLEVEL_STATE_ACTIVATED);
|
||||
C(TOPLEVEL_STATE_TILED_LEFT);
|
||||
C(TOPLEVEL_STATE_TILED_RIGHT);
|
||||
C(TOPLEVEL_STATE_TILED_TOP);
|
||||
C(TOPLEVEL_STATE_TILED_BOTTOM);
|
||||
#undef C
|
||||
}
|
||||
}
|
||||
bool window_maximized = !window->wl.maximized && maximized;
|
||||
bool window_unmaximized = window->wl.maximized && !maximized;
|
||||
if (window_maximized) {
|
||||
window->wl.size_before_maximize.width = window->wl.width;
|
||||
window->wl.size_before_maximize.height = window->wl.height;
|
||||
} else if (window_unmaximized && window->wl.size_before_maximize.width > 0 && window->wl.size_before_maximize.height > 0) {
|
||||
width = window->wl.size_before_maximize.width;
|
||||
height = window->wl.size_before_maximize.height;
|
||||
window->wl.size_before_maximize.width = 0;
|
||||
window->wl.size_before_maximize.height = 0;
|
||||
if (report_event) printf("\n");
|
||||
if ((window->wl.toplevel_states & TOPLEVEL_STATE_DOCKED) && !(new_states & TOPLEVEL_STATE_DOCKED)) {
|
||||
width = window->wl.size_before_docking.width;
|
||||
height = window->wl.size_before_docking.height;
|
||||
window->wl.size_before_docking.width = 0;
|
||||
window->wl.size_before_docking.height = 0;
|
||||
if (report_event) printf("Restoring size on undock to: %dx%d\n", width, height);
|
||||
} else if (!(window->wl.toplevel_states & TOPLEVEL_STATE_DOCKED) && (new_states & TOPLEVEL_STATE_DOCKED)) {
|
||||
window->wl.size_before_docking.width = window->wl.width;
|
||||
window->wl.size_before_docking.height = window->wl.height;
|
||||
if (report_event) printf("Saving size on undock to: %dx%d\n", window->wl.width, window->wl.height);
|
||||
}
|
||||
window->wl.maximized = maximized;
|
||||
|
||||
if (width != 0 && height != 0)
|
||||
{
|
||||
if (!maximized && !fullscreen)
|
||||
if (!(new_states & TOPLEVEL_STATE_DOCKED))
|
||||
{
|
||||
if (window->numer != GLFW_DONT_CARE && window->denom != GLFW_DONT_CARE)
|
||||
{
|
||||
@ -453,11 +450,12 @@ static void xdgToplevelHandleConfigure(void* data,
|
||||
}
|
||||
}
|
||||
}
|
||||
window->wl.fullscreened = fullscreen;
|
||||
bool focus_changed = (window->wl.toplevel_states & TOPLEVEL_STATE_ACTIVATED) != (new_states & TOPLEVEL_STATE_ACTIVATED);
|
||||
window->wl.toplevel_states = new_states;
|
||||
set_csd_window_geometry(window, &width, &height);
|
||||
wl_surface_commit(window->wl.surface);
|
||||
dispatchChangesAfterConfigure(window, width, height);
|
||||
_glfwInputWindowFocus(window, activated);
|
||||
if (focus_changed) _glfwInputWindowFocus(window, window->wl.toplevel_states & TOPLEVEL_STATE_ACTIVATED);
|
||||
ensure_csd_resources(window);
|
||||
}
|
||||
|
||||
@ -548,9 +546,9 @@ static bool createXdgSurface(_GLFWwindow* window)
|
||||
window->monitor->wl.output);
|
||||
setIdleInhibitor(window, true);
|
||||
}
|
||||
else if (window->wl.maximized)
|
||||
else if (window->wl.maximize_on_first_show)
|
||||
{
|
||||
window->wl.maximized = false;
|
||||
window->wl.maximize_on_first_show = false;
|
||||
xdg_toplevel_set_maximized(window->wl.xdg.toplevel);
|
||||
setIdleInhibitor(window, false);
|
||||
setXdgDecorations(window);
|
||||
@ -745,6 +743,8 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||
|
||||
if (wndconfig->title)
|
||||
window->wl.title = _glfw_strdup(wndconfig->title);
|
||||
if (wndconfig->maximized)
|
||||
window->wl.maximize_on_first_show = true;
|
||||
|
||||
if (wndconfig->visible)
|
||||
{
|
||||
@ -957,7 +957,7 @@ void _glfwPlatformRestoreWindow(_GLFWwindow* window)
|
||||
{
|
||||
if (window->monitor)
|
||||
xdg_toplevel_unset_fullscreen(window->wl.xdg.toplevel);
|
||||
if (window->wl.maximized)
|
||||
if (window->wl.toplevel_states & TOPLEVEL_STATE_MAXIMIZED)
|
||||
xdg_toplevel_unset_maximized(window->wl.xdg.toplevel);
|
||||
// There is no way to unset minimized, or even to know if we are
|
||||
// minimized, so there is nothing to do in this case.
|
||||
@ -1058,7 +1058,7 @@ int _glfwPlatformWindowVisible(_GLFWwindow* window)
|
||||
|
||||
int _glfwPlatformWindowMaximized(_GLFWwindow* window)
|
||||
{
|
||||
return window->wl.maximized;
|
||||
return window->wl.toplevel_states & TOPLEVEL_STATE_MAXIMIZED;
|
||||
}
|
||||
|
||||
int _glfwPlatformWindowHovered(_GLFWwindow* window)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user