mirror of
https://github.com/libsdl-org/SDL.git
synced 2024-11-27 05:43:29 +08:00
wayland: Check the WM capabilities before sending a minimize event
Wayland gives no feedback to windows regarding whether a minimize request was successful, so we would universally send the minimize event and assume that the request succeeded. Check the window manager capabilities, if available, for whether window minimization is supported, and don't send the minimized event in the case that it is unsupported.
This commit is contained in:
parent
1abbd13414
commit
2b7dc55364
@ -165,6 +165,7 @@ extern void SDL_WAYLAND_UnloadSymbols(void);
|
||||
#define libdecor_frame_is_floating (*WAYLAND_libdecor_frame_is_floating)
|
||||
#define libdecor_frame_set_parent (*WAYLAND_libdecor_frame_set_parent)
|
||||
#define libdecor_frame_show_window_menu (*WAYLAND_libdecor_frame_show_window_menu)
|
||||
#define libdecor_frame_get_wm_capabilities (*WAYLAND_libdecor_frame_get_wm_capabilities)
|
||||
#define libdecor_frame_get_xdg_surface (*WAYLAND_libdecor_frame_get_xdg_surface)
|
||||
#define libdecor_frame_get_xdg_toplevel (*WAYLAND_libdecor_frame_get_xdg_toplevel)
|
||||
#define libdecor_frame_translate_coordinate (*WAYLAND_libdecor_frame_translate_coordinate)
|
||||
|
@ -647,8 +647,8 @@ static bool ProcessHitTest(SDL_WindowData *window_data,
|
||||
} else
|
||||
#endif
|
||||
if (window_data->shell_surface_type == WAYLAND_SURFACE_XDG_TOPLEVEL) {
|
||||
if (window_data->shell_surface.xdg.roleobj.toplevel) {
|
||||
xdg_toplevel_move(window_data->shell_surface.xdg.roleobj.toplevel,
|
||||
if (window_data->shell_surface.xdg.toplevel.xdg_toplevel) {
|
||||
xdg_toplevel_move(window_data->shell_surface.xdg.toplevel.xdg_toplevel,
|
||||
seat,
|
||||
serial);
|
||||
}
|
||||
@ -674,8 +674,8 @@ static bool ProcessHitTest(SDL_WindowData *window_data,
|
||||
} else
|
||||
#endif
|
||||
if (window_data->shell_surface_type == WAYLAND_SURFACE_XDG_TOPLEVEL) {
|
||||
if (window_data->shell_surface.xdg.roleobj.toplevel) {
|
||||
xdg_toplevel_resize(window_data->shell_surface.xdg.roleobj.toplevel,
|
||||
if (window_data->shell_surface.xdg.toplevel.xdg_toplevel) {
|
||||
xdg_toplevel_resize(window_data->shell_surface.xdg.toplevel.xdg_toplevel,
|
||||
seat,
|
||||
serial,
|
||||
directions[window_data->hit_test_result - SDL_HITTEST_RESIZE_TOPLEFT]);
|
||||
|
@ -228,6 +228,10 @@ SDL_WAYLAND_SYM_OPT(void, libdecor_frame_get_max_content_size, (const struct lib
|
||||
int *))
|
||||
#endif
|
||||
|
||||
#if defined(SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_LIBDECOR) || SDL_LIBDECOR_CHECK_VERSION(0, 3, 0)
|
||||
SDL_WAYLAND_SYM_OPT(enum libdecor_wm_capabilities, libdecor_frame_get_wm_capabilities, (struct libdecor_frame *))
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#undef SDL_WAYLAND_MODULE
|
||||
|
@ -194,13 +194,13 @@ static void SetMinMaxDimensions(SDL_Window *window)
|
||||
} else
|
||||
#endif
|
||||
if (wind->shell_surface_type == WAYLAND_SURFACE_XDG_TOPLEVEL) {
|
||||
if (wind->shell_surface.xdg.roleobj.toplevel == NULL) {
|
||||
if (wind->shell_surface.xdg.toplevel.xdg_toplevel == NULL) {
|
||||
return; // Can't do anything yet, wait for ShowWindow
|
||||
}
|
||||
xdg_toplevel_set_min_size(wind->shell_surface.xdg.roleobj.toplevel,
|
||||
xdg_toplevel_set_min_size(wind->shell_surface.xdg.toplevel.xdg_toplevel,
|
||||
min_width,
|
||||
min_height);
|
||||
xdg_toplevel_set_max_size(wind->shell_surface.xdg.roleobj.toplevel,
|
||||
xdg_toplevel_set_max_size(wind->shell_surface.xdg.toplevel.xdg_toplevel,
|
||||
max_width,
|
||||
max_height);
|
||||
}
|
||||
@ -262,8 +262,8 @@ static void RepositionPopup(SDL_Window *window, bool use_current_position)
|
||||
SDL_WindowData *wind = window->internal;
|
||||
|
||||
if (wind->shell_surface_type == WAYLAND_SURFACE_XDG_POPUP &&
|
||||
wind->shell_surface.xdg.roleobj.popup.positioner &&
|
||||
xdg_popup_get_version(wind->shell_surface.xdg.roleobj.popup.popup) >= XDG_POPUP_REPOSITION_SINCE_VERSION) {
|
||||
wind->shell_surface.xdg.popup.xdg_positioner &&
|
||||
xdg_popup_get_version(wind->shell_surface.xdg.popup.xdg_popup) >= XDG_POPUP_REPOSITION_SINCE_VERSION) {
|
||||
int x = use_current_position ? window->x : window->floating.x;
|
||||
int y = use_current_position ? window->y : window->floating.y;
|
||||
|
||||
@ -273,11 +273,11 @@ static void RepositionPopup(SDL_Window *window, bool use_current_position)
|
||||
y = PixelToPoint(window->parent, y);
|
||||
}
|
||||
AdjustPopupOffset(window, &x, &y);
|
||||
xdg_positioner_set_anchor_rect(wind->shell_surface.xdg.roleobj.popup.positioner, 0, 0, window->parent->internal->current.logical_width, window->parent->internal->current.logical_height);
|
||||
xdg_positioner_set_size(wind->shell_surface.xdg.roleobj.popup.positioner, wind->current.logical_width, wind->current.logical_height);
|
||||
xdg_positioner_set_offset(wind->shell_surface.xdg.roleobj.popup.positioner, x, y);
|
||||
xdg_popup_reposition(wind->shell_surface.xdg.roleobj.popup.popup,
|
||||
wind->shell_surface.xdg.roleobj.popup.positioner,
|
||||
xdg_positioner_set_anchor_rect(wind->shell_surface.xdg.popup.xdg_positioner, 0, 0, window->parent->internal->current.logical_width, window->parent->internal->current.logical_height);
|
||||
xdg_positioner_set_size(wind->shell_surface.xdg.popup.xdg_positioner, wind->current.logical_width, wind->current.logical_height);
|
||||
xdg_positioner_set_offset(wind->shell_surface.xdg.popup.xdg_positioner, x, y);
|
||||
xdg_popup_reposition(wind->shell_surface.xdg.popup.xdg_popup,
|
||||
wind->shell_surface.xdg.popup.xdg_positioner,
|
||||
0);
|
||||
}
|
||||
}
|
||||
@ -602,7 +602,7 @@ static void SetFullscreen(SDL_Window *window, struct wl_output *output)
|
||||
} else
|
||||
#endif
|
||||
if (wind->shell_surface_type == WAYLAND_SURFACE_XDG_TOPLEVEL) {
|
||||
if (wind->shell_surface.xdg.roleobj.toplevel == NULL) {
|
||||
if (wind->shell_surface.xdg.toplevel.xdg_toplevel == NULL) {
|
||||
return; // Can't do anything yet, wait for ShowWindow
|
||||
}
|
||||
|
||||
@ -612,9 +612,9 @@ static void SetFullscreen(SDL_Window *window, struct wl_output *output)
|
||||
Wayland_SetWindowResizable(SDL_GetVideoDevice(), window, true);
|
||||
wl_surface_commit(wind->surface);
|
||||
|
||||
xdg_toplevel_set_fullscreen(wind->shell_surface.xdg.roleobj.toplevel, output);
|
||||
xdg_toplevel_set_fullscreen(wind->shell_surface.xdg.toplevel.xdg_toplevel, output);
|
||||
} else {
|
||||
xdg_toplevel_unset_fullscreen(wind->shell_surface.xdg.roleobj.toplevel);
|
||||
xdg_toplevel_unset_fullscreen(wind->shell_surface.xdg.toplevel.xdg_toplevel);
|
||||
}
|
||||
}
|
||||
|
||||
@ -971,11 +971,33 @@ static void handle_xdg_configure_toplevel_bounds(void *data,
|
||||
// NOP
|
||||
}
|
||||
|
||||
void handle_xdg_toplevel_wm_capabilities(void *data,
|
||||
struct xdg_toplevel *xdg_toplevel,
|
||||
struct wl_array *capabilities)
|
||||
static void handle_xdg_toplevel_wm_capabilities(void *data,
|
||||
struct xdg_toplevel *xdg_toplevel,
|
||||
struct wl_array *capabilities)
|
||||
{
|
||||
// NOP
|
||||
SDL_WindowData *wind = (SDL_WindowData *)data;
|
||||
enum xdg_toplevel_wm_capabilities *wm_cap;
|
||||
|
||||
wind->wm_caps = 0;
|
||||
|
||||
wl_array_for_each (wm_cap, capabilities) {
|
||||
switch (*wm_cap) {
|
||||
case XDG_TOPLEVEL_WM_CAPABILITIES_WINDOW_MENU:
|
||||
wind->wm_caps |= WAYLAND_WM_CAPS_WINDOW_MENU;
|
||||
break;
|
||||
case XDG_TOPLEVEL_WM_CAPABILITIES_MAXIMIZE:
|
||||
wind->wm_caps |= WAYLAND_WM_CAPS_MAXIMIZE;
|
||||
break;
|
||||
case XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN:
|
||||
wind->wm_caps |= WAYLAND_WM_CAPS_FULLSCREEN;
|
||||
break;
|
||||
case XDG_TOPLEVEL_WM_CAPABILITIES_MINIMIZE:
|
||||
wind->wm_caps |= WAYLAND_WM_CAPS_MINIMIZE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const struct xdg_toplevel_listener toplevel_listener_xdg = {
|
||||
@ -1131,7 +1153,6 @@ static void decoration_frame_configure(struct libdecor_frame *frame,
|
||||
bool tiled = false;
|
||||
bool suspended = false;
|
||||
bool resizing = false;
|
||||
bool floating;
|
||||
|
||||
static const enum libdecor_window_state tiled_states = (LIBDECOR_WINDOW_STATE_TILED_LEFT | LIBDECOR_WINDOW_STATE_TILED_RIGHT |
|
||||
LIBDECOR_WINDOW_STATE_TILED_TOP | LIBDECOR_WINDOW_STATE_TILED_BOTTOM);
|
||||
@ -1149,7 +1170,7 @@ static void decoration_frame_configure(struct libdecor_frame *frame,
|
||||
resizing = (window_state & LIBDECOR_WINDOW_STATE_RESIZING) != 0;
|
||||
#endif
|
||||
}
|
||||
floating = !(fullscreen || maximized || tiled);
|
||||
const bool floating = !(fullscreen || maximized || tiled);
|
||||
|
||||
UpdateWindowFullscreen(window, fullscreen);
|
||||
|
||||
@ -1321,6 +1342,24 @@ static void decoration_frame_configure(struct libdecor_frame *frame,
|
||||
window->tiled = tiled;
|
||||
wind->resizing = resizing;
|
||||
|
||||
// Update the window manager capabilities.
|
||||
#if SDL_LIBDECOR_CHECK_VERSION(0, 3, 0)
|
||||
enum libdecor_wm_capabilities caps;
|
||||
#ifdef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_LIBDECOR
|
||||
if (libdecor_frame_get_wm_capabilities) {
|
||||
caps = libdecor_frame_get_wm_capabilities(wind->shell_surface.libdecor.frame);
|
||||
#else
|
||||
caps = libdecor_frame_get_wm_capabilities(wind->shell_surface.libdecor.frame);
|
||||
{
|
||||
#endif
|
||||
wind->wm_caps = 0;
|
||||
wind->wm_caps |= caps & LIBDECOR_WM_CAPABILITIES_WINDOW_MENU ? WAYLAND_WM_CAPS_WINDOW_MENU : 0;
|
||||
wind->wm_caps |= caps & LIBDECOR_WM_CAPABILITIES_MAXIMIZE ? WAYLAND_WM_CAPS_MAXIMIZE : 0;
|
||||
wind->wm_caps |= caps & LIBDECOR_WM_CAPABILITIES_FULLSCREEN ? WAYLAND_WM_CAPS_FULLSCREEN : 0;
|
||||
wind->wm_caps |= caps & LIBDECOR_WM_CAPABILITIES_MINIMIZE ? WAYLAND_WM_CAPS_MINIMIZE : 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Calculate the new window geometry
|
||||
if (ConfigureWindowGeometry(window)) {
|
||||
// ... then commit the changes on the libdecor side.
|
||||
@ -1602,8 +1641,8 @@ static struct xdg_toplevel *GetToplevelForWindow(SDL_WindowData *wind)
|
||||
return libdecor_frame_get_xdg_toplevel(wind->shell_surface.libdecor.frame);
|
||||
} else
|
||||
#endif
|
||||
if (wind->shell_surface_type == WAYLAND_SURFACE_XDG_TOPLEVEL && wind->shell_surface.xdg.roleobj.toplevel) {
|
||||
return wind->shell_surface.xdg.roleobj.toplevel;
|
||||
if (wind->shell_surface_type == WAYLAND_SURFACE_XDG_TOPLEVEL && wind->shell_surface.xdg.toplevel.xdg_toplevel) {
|
||||
return wind->shell_surface.xdg.toplevel.xdg_toplevel;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1801,13 +1840,13 @@ void Wayland_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
}
|
||||
|
||||
// Set up the positioner for the popup and configure the constraints
|
||||
data->shell_surface.xdg.roleobj.popup.positioner = xdg_wm_base_create_positioner(c->shell.xdg);
|
||||
xdg_positioner_set_anchor(data->shell_surface.xdg.roleobj.popup.positioner, XDG_POSITIONER_ANCHOR_TOP_LEFT);
|
||||
xdg_positioner_set_anchor_rect(data->shell_surface.xdg.roleobj.popup.positioner, 0, 0, parent->internal->current.logical_width, parent->internal->current.logical_width);
|
||||
xdg_positioner_set_constraint_adjustment(data->shell_surface.xdg.roleobj.popup.positioner,
|
||||
data->shell_surface.xdg.popup.xdg_positioner = xdg_wm_base_create_positioner(c->shell.xdg);
|
||||
xdg_positioner_set_anchor(data->shell_surface.xdg.popup.xdg_positioner, XDG_POSITIONER_ANCHOR_TOP_LEFT);
|
||||
xdg_positioner_set_anchor_rect(data->shell_surface.xdg.popup.xdg_positioner, 0, 0, parent->internal->current.logical_width, parent->internal->current.logical_width);
|
||||
xdg_positioner_set_constraint_adjustment(data->shell_surface.xdg.popup.xdg_positioner,
|
||||
XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_X | XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_Y);
|
||||
xdg_positioner_set_gravity(data->shell_surface.xdg.roleobj.popup.positioner, XDG_POSITIONER_GRAVITY_BOTTOM_RIGHT);
|
||||
xdg_positioner_set_size(data->shell_surface.xdg.roleobj.popup.positioner, data->current.logical_width, data->current.logical_height);
|
||||
xdg_positioner_set_gravity(data->shell_surface.xdg.popup.xdg_positioner, XDG_POSITIONER_GRAVITY_BOTTOM_RIGHT);
|
||||
xdg_positioner_set_size(data->shell_surface.xdg.popup.xdg_positioner, data->current.logical_width, data->current.logical_height);
|
||||
|
||||
// Set the popup initial position
|
||||
position_x = window->x;
|
||||
@ -1818,13 +1857,13 @@ void Wayland_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
position_y = PixelToPoint(window->parent, position_y);
|
||||
}
|
||||
AdjustPopupOffset(window, &position_x, &position_y);
|
||||
xdg_positioner_set_offset(data->shell_surface.xdg.roleobj.popup.positioner, position_x, position_y);
|
||||
xdg_positioner_set_offset(data->shell_surface.xdg.popup.xdg_positioner, position_x, position_y);
|
||||
|
||||
// Assign the popup role
|
||||
data->shell_surface.xdg.roleobj.popup.popup = xdg_surface_get_popup(data->shell_surface.xdg.surface,
|
||||
data->shell_surface.xdg.popup.xdg_popup = xdg_surface_get_popup(data->shell_surface.xdg.surface,
|
||||
parent_xdg_surface,
|
||||
data->shell_surface.xdg.roleobj.popup.positioner);
|
||||
xdg_popup_add_listener(data->shell_surface.xdg.roleobj.popup.popup, &popup_listener_xdg, data);
|
||||
data->shell_surface.xdg.popup.xdg_positioner);
|
||||
xdg_popup_add_listener(data->shell_surface.xdg.popup.xdg_popup, &popup_listener_xdg, data);
|
||||
|
||||
if (window->flags & SDL_WINDOW_TOOLTIP) {
|
||||
struct wl_region *region;
|
||||
@ -1840,12 +1879,12 @@ void Wayland_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
}
|
||||
}
|
||||
|
||||
SDL_SetPointerProperty(props, SDL_PROP_WINDOW_WAYLAND_XDG_POPUP_POINTER, data->shell_surface.xdg.roleobj.popup.popup);
|
||||
SDL_SetPointerProperty(props, SDL_PROP_WINDOW_WAYLAND_XDG_POSITIONER_POINTER, data->shell_surface.xdg.roleobj.popup.positioner);
|
||||
SDL_SetPointerProperty(props, SDL_PROP_WINDOW_WAYLAND_XDG_POPUP_POINTER, data->shell_surface.xdg.popup.xdg_popup);
|
||||
SDL_SetPointerProperty(props, SDL_PROP_WINDOW_WAYLAND_XDG_POSITIONER_POINTER, data->shell_surface.xdg.popup.xdg_positioner);
|
||||
} else {
|
||||
data->shell_surface.xdg.roleobj.toplevel = xdg_surface_get_toplevel(data->shell_surface.xdg.surface);
|
||||
xdg_toplevel_set_app_id(data->shell_surface.xdg.roleobj.toplevel, data->app_id);
|
||||
xdg_toplevel_add_listener(data->shell_surface.xdg.roleobj.toplevel, &toplevel_listener_xdg, data);
|
||||
data->shell_surface.xdg.toplevel.xdg_toplevel = xdg_surface_get_toplevel(data->shell_surface.xdg.surface);
|
||||
xdg_toplevel_set_app_id(data->shell_surface.xdg.toplevel.xdg_toplevel, data->app_id);
|
||||
xdg_toplevel_add_listener(data->shell_surface.xdg.toplevel.xdg_toplevel, &toplevel_listener_xdg, data);
|
||||
|
||||
if (c->zxdg_exporter_v2) {
|
||||
data->exported = zxdg_exporter_v2_export_toplevel(c->zxdg_exporter_v2, data->surface);
|
||||
@ -1854,11 +1893,11 @@ void Wayland_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
|
||||
if (c->xdg_toplevel_icon_manager_v1 && data->xdg_toplevel_icon_v1) {
|
||||
xdg_toplevel_icon_manager_v1_set_icon(_this->internal->xdg_toplevel_icon_manager_v1,
|
||||
data->shell_surface.xdg.roleobj.toplevel,
|
||||
data->shell_surface.xdg.toplevel.xdg_toplevel,
|
||||
data->xdg_toplevel_icon_v1);
|
||||
}
|
||||
|
||||
SDL_SetPointerProperty(props, SDL_PROP_WINDOW_WAYLAND_XDG_TOPLEVEL_POINTER, data->shell_surface.xdg.roleobj.toplevel);
|
||||
SDL_SetPointerProperty(props, SDL_PROP_WINDOW_WAYLAND_XDG_TOPLEVEL_POINTER, data->shell_surface.xdg.toplevel.xdg_toplevel);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1898,8 +1937,8 @@ void Wayland_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
}
|
||||
|
||||
// Create the window decorations
|
||||
if (data->shell_surface_type != WAYLAND_SURFACE_XDG_POPUP && data->shell_surface.xdg.roleobj.toplevel && c->decoration_manager) {
|
||||
data->server_decoration = zxdg_decoration_manager_v1_get_toplevel_decoration(c->decoration_manager, data->shell_surface.xdg.roleobj.toplevel);
|
||||
if (data->shell_surface_type != WAYLAND_SURFACE_XDG_POPUP && data->shell_surface.xdg.toplevel.xdg_toplevel && c->decoration_manager) {
|
||||
data->server_decoration = zxdg_decoration_manager_v1_get_toplevel_decoration(c->decoration_manager, data->shell_surface.xdg.toplevel.xdg_toplevel);
|
||||
zxdg_toplevel_decoration_v1_add_listener(data->server_decoration,
|
||||
&decoration_listener,
|
||||
window);
|
||||
@ -1977,7 +2016,7 @@ static void Wayland_ReleasePopup(SDL_VideoDevice *_this, SDL_Window *popup)
|
||||
}
|
||||
|
||||
// This may already be freed by a parent popup!
|
||||
if (popupdata->shell_surface.xdg.roleobj.popup.popup == NULL) {
|
||||
if (popupdata->shell_surface.xdg.popup.xdg_popup == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1994,10 +2033,10 @@ static void Wayland_ReleasePopup(SDL_VideoDevice *_this, SDL_Window *popup)
|
||||
}
|
||||
}
|
||||
|
||||
xdg_popup_destroy(popupdata->shell_surface.xdg.roleobj.popup.popup);
|
||||
xdg_positioner_destroy(popupdata->shell_surface.xdg.roleobj.popup.positioner);
|
||||
popupdata->shell_surface.xdg.roleobj.popup.popup = NULL;
|
||||
popupdata->shell_surface.xdg.roleobj.popup.positioner = NULL;
|
||||
xdg_popup_destroy(popupdata->shell_surface.xdg.popup.xdg_popup);
|
||||
xdg_positioner_destroy(popupdata->shell_surface.xdg.popup.xdg_positioner);
|
||||
popupdata->shell_surface.xdg.popup.xdg_popup = NULL;
|
||||
popupdata->shell_surface.xdg.popup.xdg_positioner = NULL;
|
||||
|
||||
SDL_PropertiesID props = SDL_GetWindowProperties(popup);
|
||||
SDL_SetPointerProperty(props, SDL_PROP_WINDOW_WAYLAND_XDG_POPUP_POINTER, NULL);
|
||||
@ -2061,9 +2100,9 @@ void Wayland_HideWindow(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
#endif
|
||||
if (wind->shell_surface_type == WAYLAND_SURFACE_XDG_POPUP) {
|
||||
Wayland_ReleasePopup(_this, window);
|
||||
} else if (wind->shell_surface.xdg.roleobj.toplevel) {
|
||||
xdg_toplevel_destroy(wind->shell_surface.xdg.roleobj.toplevel);
|
||||
wind->shell_surface.xdg.roleobj.toplevel = NULL;
|
||||
} else if (wind->shell_surface.xdg.toplevel.xdg_toplevel) {
|
||||
xdg_toplevel_destroy(wind->shell_surface.xdg.toplevel.xdg_toplevel);
|
||||
wind->shell_surface.xdg.toplevel.xdg_toplevel = NULL;
|
||||
SDL_SetPointerProperty(props, SDL_PROP_WINDOW_WAYLAND_XDG_TOPLEVEL_POINTER, NULL);
|
||||
}
|
||||
if (wind->shell_surface.xdg.surface) {
|
||||
@ -2239,10 +2278,10 @@ void Wayland_RestoreWindow(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
#endif
|
||||
// Note that xdg-shell does NOT provide a way to unset minimize!
|
||||
if (wind->shell_surface_type == WAYLAND_SURFACE_XDG_TOPLEVEL) {
|
||||
if (wind->shell_surface.xdg.roleobj.toplevel == NULL) {
|
||||
if (wind->shell_surface.xdg.toplevel.xdg_toplevel == NULL) {
|
||||
return; // Can't do anything yet, wait for ShowWindow
|
||||
}
|
||||
xdg_toplevel_unset_maximized(wind->shell_surface.xdg.roleobj.toplevel);
|
||||
xdg_toplevel_unset_maximized(wind->shell_surface.xdg.toplevel.xdg_toplevel);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2313,13 +2352,13 @@ void Wayland_MaximizeWindow(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
} else
|
||||
#endif
|
||||
if (wind->shell_surface_type == WAYLAND_SURFACE_XDG_TOPLEVEL) {
|
||||
if (wind->shell_surface.xdg.roleobj.toplevel == NULL) {
|
||||
if (wind->shell_surface.xdg.toplevel.xdg_toplevel == NULL) {
|
||||
return; // Can't do anything yet, wait for ShowWindow
|
||||
}
|
||||
|
||||
// Commit to preserve any pending size data.
|
||||
wl_surface_commit(wind->surface);
|
||||
xdg_toplevel_set_maximized(wind->shell_surface.xdg.roleobj.toplevel);
|
||||
xdg_toplevel_set_maximized(wind->shell_surface.xdg.toplevel.xdg_toplevel);
|
||||
}
|
||||
|
||||
++wind->maximized_deadline_count;
|
||||
@ -2331,7 +2370,10 @@ void Wayland_MinimizeWindow(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
{
|
||||
SDL_WindowData *wind = window->internal;
|
||||
|
||||
// TODO: Check compositor capabilities to see if minimizing is supported
|
||||
if (!(wind->wm_caps & WAYLAND_WM_CAPS_MINIMIZE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBDECOR_H
|
||||
if (wind->shell_surface_type == WAYLAND_SURFACE_LIBDECOR) {
|
||||
if (!wind->shell_surface.libdecor.frame) {
|
||||
@ -2342,10 +2384,10 @@ void Wayland_MinimizeWindow(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
} else
|
||||
#endif
|
||||
if (wind->shell_surface_type == WAYLAND_SURFACE_XDG_TOPLEVEL) {
|
||||
if (wind->shell_surface.xdg.roleobj.toplevel == NULL) {
|
||||
if (wind->shell_surface.xdg.toplevel.xdg_toplevel == NULL) {
|
||||
return; // Can't do anything yet, wait for ShowWindow
|
||||
}
|
||||
xdg_toplevel_set_minimized(wind->shell_surface.xdg.roleobj.toplevel);
|
||||
xdg_toplevel_set_minimized(wind->shell_surface.xdg.toplevel.xdg_toplevel);
|
||||
SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_MINIMIZED, 0, 0);
|
||||
}
|
||||
}
|
||||
@ -2420,6 +2462,9 @@ bool Wayland_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_Proper
|
||||
data->waylandData = c;
|
||||
data->sdlwindow = window;
|
||||
|
||||
// Default to all capabilities
|
||||
data->wm_caps = WAYLAND_WM_CAPS_ALL;
|
||||
|
||||
data->scale_factor = 1.0;
|
||||
|
||||
if (SDL_WINDOW_IS_POPUP(window)) {
|
||||
@ -2597,8 +2642,8 @@ bool Wayland_SetWindowPosition(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
|
||||
// Only popup windows can be positioned relative to the parent.
|
||||
if (wind->shell_surface_type == WAYLAND_SURFACE_XDG_POPUP) {
|
||||
if (wind->shell_surface.xdg.roleobj.popup.popup &&
|
||||
xdg_popup_get_version(wind->shell_surface.xdg.roleobj.popup.popup) < XDG_POPUP_REPOSITION_SINCE_VERSION) {
|
||||
if (wind->shell_surface.xdg.popup.xdg_popup &&
|
||||
xdg_popup_get_version(wind->shell_surface.xdg.popup.xdg_popup) < XDG_POPUP_REPOSITION_SINCE_VERSION) {
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
@ -2729,8 +2774,8 @@ void Wayland_SetWindowTitle(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
libdecor_frame_set_title(wind->shell_surface.libdecor.frame, title);
|
||||
} else
|
||||
#endif
|
||||
if (wind->shell_surface_type == WAYLAND_SURFACE_XDG_TOPLEVEL && wind->shell_surface.xdg.roleobj.toplevel) {
|
||||
xdg_toplevel_set_title(wind->shell_surface.xdg.roleobj.toplevel, title);
|
||||
if (wind->shell_surface_type == WAYLAND_SURFACE_XDG_TOPLEVEL && wind->shell_surface.xdg.toplevel.xdg_toplevel) {
|
||||
xdg_toplevel_set_title(wind->shell_surface.xdg.toplevel.xdg_toplevel, title);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2768,8 +2813,8 @@ bool Wayland_SetWindowIcon(SDL_VideoDevice *_this, SDL_Window *window, SDL_Surfa
|
||||
toplevel = libdecor_frame_get_xdg_toplevel(wind->shell_surface.libdecor.frame);
|
||||
} else
|
||||
#endif
|
||||
if (wind->shell_surface_type == WAYLAND_SURFACE_XDG_TOPLEVEL && wind->shell_surface.xdg.roleobj.toplevel) {
|
||||
toplevel = wind->shell_surface.xdg.roleobj.toplevel;
|
||||
if (wind->shell_surface_type == WAYLAND_SURFACE_XDG_TOPLEVEL && wind->shell_surface.xdg.toplevel.xdg_toplevel) {
|
||||
toplevel = wind->shell_surface.xdg.toplevel.xdg_toplevel;
|
||||
}
|
||||
|
||||
if (toplevel) {
|
||||
@ -2806,9 +2851,9 @@ void Wayland_ShowWindowSystemMenu(SDL_Window *window, int x, int y)
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
if (wind->shell_surface_type == WAYLAND_SURFACE_XDG_TOPLEVEL) {
|
||||
if (wind->shell_surface.xdg.roleobj.toplevel) {
|
||||
xdg_toplevel_show_window_menu(wind->shell_surface.xdg.roleobj.toplevel, wind->waylandData->input->seat, wind->waylandData->input->last_implicit_grab_serial, x, y);
|
||||
if (wind->shell_surface_type == WAYLAND_SURFACE_XDG_TOPLEVEL) {
|
||||
if (wind->shell_surface.xdg.toplevel.xdg_toplevel) {
|
||||
xdg_toplevel_show_window_menu(wind->shell_surface.xdg.toplevel.xdg_toplevel, wind->waylandData->input->seat, wind->waylandData->input->last_implicit_grab_serial, x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -56,13 +56,16 @@ struct SDL_WindowData
|
||||
struct xdg_surface *surface;
|
||||
union
|
||||
{
|
||||
struct xdg_toplevel *toplevel;
|
||||
struct
|
||||
{
|
||||
struct xdg_popup *popup;
|
||||
struct xdg_positioner *positioner;
|
||||
struct xdg_toplevel *xdg_toplevel;
|
||||
} toplevel;
|
||||
struct
|
||||
{
|
||||
struct xdg_popup *xdg_popup;
|
||||
struct xdg_positioner *xdg_positioner;
|
||||
} popup;
|
||||
} roleobj;
|
||||
};
|
||||
bool initial_configure_seen;
|
||||
} xdg;
|
||||
} shell_surface;
|
||||
@ -82,6 +85,18 @@ struct SDL_WindowData
|
||||
WAYLAND_SURFACE_STATUS_SHOW_PENDING,
|
||||
WAYLAND_SURFACE_STATUS_SHOWN
|
||||
} surface_status;
|
||||
enum
|
||||
{
|
||||
WAYLAND_WM_CAPS_WINDOW_MENU = 0x01,
|
||||
WAYLAND_WM_CAPS_MAXIMIZE = 0x02,
|
||||
WAYLAND_WM_CAPS_FULLSCREEN = 0x04,
|
||||
WAYLAND_WM_CAPS_MINIMIZE = 0x08,
|
||||
|
||||
WAYLAND_WM_CAPS_ALL = WAYLAND_WM_CAPS_WINDOW_MENU |
|
||||
WAYLAND_WM_CAPS_MAXIMIZE |
|
||||
WAYLAND_WM_CAPS_FULLSCREEN |
|
||||
WAYLAND_WM_CAPS_MINIMIZE
|
||||
} wm_caps;
|
||||
|
||||
struct wl_egl_window *egl_window;
|
||||
struct SDL_WaylandInput *keyboard_device;
|
||||
|
Loading…
Reference in New Issue
Block a user