wayland: handle XWayland fullscreen requests
The XWayland backend was not listening for request_fullscreen events from wlr_xwayland_surface. Wine/Proton games that request fullscreen via _NET_WM_STATE_FULLSCREEN had the signal silently ignored, leaving them in a tiny window. Add handle_xwayland_request_fullscreen listener that calls wFullscreenWindow/wUnfullscreenWindow, matching the XDG toplevel path.
This commit is contained in:
parent
53d8d82e3a
commit
5b5617844a
|
|
@ -503,7 +503,7 @@ AUTOMAKE = ${SHELL} '/home/lkn/src/wmaker/missing' automake-1.18
|
|||
AWK = gawk
|
||||
CC = gcc
|
||||
CCDEPMODE = depmode=gcc3
|
||||
CFLAGS = -g -O2 -Wall -Wextra -Wno-sign-compare -Werror=trampolines -Wno-deprecated -Wno-deprecated-declarations
|
||||
CFLAGS = -O0 -g -fsanitize=address -fno-omit-frame-pointer -Wall -Wextra -Wno-sign-compare -Werror=trampolines -Wno-deprecated -Wno-deprecated-declarations
|
||||
CPP = gcc -E
|
||||
CPPFLAGS = -DNDEBUG -D_XOPEN_SOURCE=700 -D_GNU_SOURCE
|
||||
CSCOPE = cscope
|
||||
|
|
@ -535,7 +535,7 @@ INSTALL_SCRIPT = ${INSTALL}
|
|||
INSTALL_STRIP_PROGRAM = $(install_sh) -c -s
|
||||
INTLIBS =
|
||||
LD = /usr/x86_64-pc-linux-gnu/bin/ld -m elf_x86_64
|
||||
LDFLAGS =
|
||||
LDFLAGS = -fsanitize=address
|
||||
LIBBSD =
|
||||
LIBEXIF =
|
||||
LIBM = -lm
|
||||
|
|
|
|||
|
|
@ -243,7 +243,8 @@ void paint_app_icon(WApplication *wapp)
|
|||
wapp->app_icon->next == NULL && wapp->app_icon->prev == NULL)
|
||||
add_to_appicon_list(scr, wapp->app_icon);
|
||||
|
||||
if (!attracting_dock || !wapp->app_icon->attracted || !attracting_dock->collapsed)
|
||||
if (!WFLAGP(wapp->main_window_desc, no_appicon) &&
|
||||
(!attracting_dock || !wapp->app_icon->attracted || !attracting_dock->collapsed))
|
||||
wm_backend->window_map((WNativeWindow)icon->core->window);
|
||||
|
||||
if (wPreferences.auto_arrange_icons && !wapp->app_icon->attracted)
|
||||
|
|
|
|||
|
|
@ -149,6 +149,13 @@ WApplication *wApplicationCreate(WWindow * wwin)
|
|||
/* application descriptor */
|
||||
wm_backend->context_save(main_window, WM_CTX_APP_WIN, wapp);
|
||||
|
||||
/* add to the per-screen application list */
|
||||
wapp->next = scr->wapp_list;
|
||||
wapp->prev = NULL;
|
||||
if (scr->wapp_list)
|
||||
scr->wapp_list->prev = wapp;
|
||||
scr->wapp_list = wapp;
|
||||
|
||||
create_appicon_for_application(wapp, wwin);
|
||||
|
||||
return wapp;
|
||||
|
|
|
|||
|
|
@ -16,8 +16,6 @@ void wl_event_flush(void)
|
|||
(!wl_state.session || wl_state.session->active)) {
|
||||
wlr_scene_output_commit(wl_state.scene_output, NULL);
|
||||
wl_display_flush_clients(wl_state.display);
|
||||
struct wl_event_loop *loop = wl_display_get_event_loop(wl_state.display);
|
||||
wl_event_loop_dispatch(loop, 0);
|
||||
}
|
||||
}
|
||||
void wl_event_flush_expose(void) {}
|
||||
|
|
|
|||
|
|
@ -291,6 +291,7 @@ handle_toplevel_map(struct wl_listener *listener, void *data)
|
|||
wwin->client_flags.no_close_button = 1;
|
||||
wwin->client_flags.no_miniaturize_button = 1;
|
||||
wwin->client_flags.no_resizebar = 1;
|
||||
wwin->client_flags.no_appicon = 1;
|
||||
wwin->client_flags.skip_window_list = 1;
|
||||
wwin->client_flags.skip_switchpanel = 1;
|
||||
wwin->user_flags = wwin->client_flags;
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@ void wm_dock_app_remove(WNativeWindow id);
|
|||
void wl_pointer_warp_to(int x, int y);
|
||||
extern void W_UnregisterBacking(unsigned long id);
|
||||
struct wl_frame_buf *frame_buf_find(WNativeWindow id);
|
||||
void wFullscreenWindow(WWindow *wwin);
|
||||
void wUnfullscreenWindow(WWindow *wwin);
|
||||
|
||||
#define VIEW_FROM_LISTENER(ptr, field) \
|
||||
((struct wl_toplevel_view *)((char *)(ptr) - offsetof(struct wl_toplevel_view, field)))
|
||||
|
|
@ -96,6 +98,24 @@ handle_or_set_geometry(struct wl_listener *listener, void *data)
|
|||
|
||||
/* --- Managed XWayland surface handlers --- */
|
||||
|
||||
static void
|
||||
handle_xwayland_request_fullscreen(struct wl_listener *listener, void *data)
|
||||
{
|
||||
struct wl_toplevel_view *view = VIEW_FROM_LISTENER(listener, request_fullscreen_listener);
|
||||
(void)data;
|
||||
WObjDescriptor *desc = wm_backend->context_find(view->id, WM_CTX_CLIENT_WIN);
|
||||
if (!desc || desc->parent_type != WCLASS_WINDOW)
|
||||
return;
|
||||
WWindow *wwin = (WWindow *)desc->parent;
|
||||
if (view->xw_surface->fullscreen) {
|
||||
if (!wwin->flags.fullscreen)
|
||||
wFullscreenWindow(wwin);
|
||||
} else {
|
||||
if (wwin->flags.fullscreen)
|
||||
wUnfullscreenWindow(wwin);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
handle_xwayland_set_geometry(struct wl_listener *listener, void *data)
|
||||
{
|
||||
|
|
@ -152,6 +172,9 @@ handle_xwayland_surface_map(struct wl_listener *listener, void *data)
|
|||
int cy = view->y + wwin->client.height / 2;
|
||||
wl_pointer_warp_to(cx, cy);
|
||||
wm_dock_app_add(view);
|
||||
|
||||
if (xw->fullscreen && !wwin->flags.fullscreen)
|
||||
wFullscreenWindow(wwin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -221,6 +244,7 @@ handle_xwayland_destroy(struct wl_listener *listener, void *data)
|
|||
wl_list_remove(&view->unmap_listener.link);
|
||||
wl_list_remove(&view->destroy_listener.link);
|
||||
wl_list_remove(&view->title_listener.link);
|
||||
wl_list_remove(&view->request_fullscreen_listener.link);
|
||||
if (view->xw_surface_map_listener.link.next &&
|
||||
view->xw_surface_map_listener.link.next != &view->xw_surface_map_listener.link)
|
||||
wl_list_remove(&view->xw_surface_map_listener.link);
|
||||
|
|
@ -384,12 +408,14 @@ handle_xwayland_new_surface(struct wl_listener *listener, void *data)
|
|||
view->destroy_listener.notify = handle_xwayland_destroy;
|
||||
view->title_listener.notify = handle_xwayland_set_class;
|
||||
view->xw_geometry_listener.notify = handle_xwayland_set_geometry;
|
||||
view->request_fullscreen_listener.notify = handle_xwayland_request_fullscreen;
|
||||
|
||||
wl_signal_add(&xw->events.associate, &view->map_listener);
|
||||
wl_signal_add(&xw->events.dissociate, &view->unmap_listener);
|
||||
wl_signal_add(&xw->events.destroy, &view->destroy_listener);
|
||||
wl_signal_add(&xw->events.set_class, &view->title_listener);
|
||||
wl_signal_add(&xw->events.set_geometry, &view->xw_geometry_listener);
|
||||
wl_signal_add(&xw->events.request_fullscreen, &view->request_fullscreen_listener);
|
||||
|
||||
wl_list_insert(&wl_state.toplevel_list, &view->link);
|
||||
wl_state.managed_surface_count++;
|
||||
|
|
|
|||
|
|
@ -1587,6 +1587,8 @@ int wKeyboardMoveResizeWindow(WWindow * wwin)
|
|||
}
|
||||
}
|
||||
|
||||
wm_backend->server_ungrab();
|
||||
|
||||
if (ctrlmode) {
|
||||
showGeometry(wwin, src_x + off_x, src_y + off_y, src_x + off_x + ww, src_y + off_y + wh,
|
||||
0);
|
||||
|
|
@ -1594,12 +1596,12 @@ int wKeyboardMoveResizeWindow(WWindow * wwin)
|
|||
showPosition(wwin, src_x + off_x, src_y + off_y);
|
||||
|
||||
if (opaqueMoveResize) {
|
||||
wm_backend->server_ungrab();
|
||||
wWindowConfigure(wwin, src_x + off_x, src_y + off_y, ww, wh - vert_border);
|
||||
};
|
||||
|
||||
if (done) {
|
||||
if (!opaqueMoveResize) { /* ctrlmode => resize */
|
||||
wm_backend->server_grab();
|
||||
if (wwin->flags.shaded || scr->selected_windows) {
|
||||
if (scr->selected_windows)
|
||||
drawFrames(wwin, scr->selected_windows, off_x, off_y);
|
||||
|
|
@ -1608,6 +1610,7 @@ int wKeyboardMoveResizeWindow(WWindow * wwin)
|
|||
} else {
|
||||
drawTransparentFrame(wwin, src_x + off_x, src_y + off_y, ww, wh);
|
||||
}
|
||||
wm_backend->server_ungrab();
|
||||
}
|
||||
|
||||
if (ctrlmode) {
|
||||
|
|
@ -1619,7 +1622,6 @@ int wKeyboardMoveResizeWindow(WWindow * wwin)
|
|||
|
||||
wm_backend->keyboard_ungrab();
|
||||
wm_backend->pointer_ungrab(0);
|
||||
wm_backend->server_ungrab();
|
||||
|
||||
if (done == 2) {
|
||||
if (wwin->flags.shaded || scr->selected_windows) {
|
||||
|
|
@ -1754,8 +1756,8 @@ int wMouseMoveWindow(WWindow * wwin, WMEvent * ev)
|
|||
moveData.winWidth, moveData.winHeight);
|
||||
|
||||
if (wPreferences.move_display == WDIS_NEW && !scr->selected_windows) {
|
||||
wm_backend->server_grab();
|
||||
showPosition(wwin, moveData.realX, moveData.realY);
|
||||
wm_backend->server_grab();
|
||||
}
|
||||
|
||||
if (!opaqueMove) {
|
||||
|
|
@ -1871,11 +1873,12 @@ int wMouseMoveWindow(WWindow * wwin, WMEvent * ev)
|
|||
if (started && !opaqueMove)
|
||||
drawFrames(wwin, scr->selected_windows, 0, 0);
|
||||
|
||||
if (wPreferences.move_display == WDIS_NEW
|
||||
&& !scr->selected_windows)
|
||||
showPosition(wwin, moveData.realX, moveData.realY);
|
||||
if (!opaqueMove || (wPreferences.move_display == WDIS_NEW
|
||||
&& !scr->selected_windows)) {
|
||||
wm_backend->server_grab();
|
||||
if (wPreferences.move_display == WDIS_NEW)
|
||||
showPosition(wwin, moveData.realX, moveData.realY);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
16
src/window.c
16
src/window.c
|
|
@ -767,6 +767,19 @@ WWindow *wManageWindow(WScreen *scr, WNativeWindow window)
|
|||
break;
|
||||
}
|
||||
}
|
||||
/* Also search existing WApplications: catches peers that mapped
|
||||
* before this window is in focused_window (startup ordering). */
|
||||
if (wwin->main_window == wwin->client_win) {
|
||||
WApplication *wapp;
|
||||
for (wapp = scr->wapp_list; wapp; wapp = wapp->next) {
|
||||
WWindow *leader = wWindowFor(wapp->main_window);
|
||||
if (leader && leader->wm_class
|
||||
&& strcmp(leader->wm_class, wwin->wm_class) == 0) {
|
||||
wwin->main_window = wapp->main_window;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1200,6 +1213,9 @@ WWindow *wManageWindow(WScreen *scr, WNativeWindow window)
|
|||
wWindowSynthConfigureNotify(wwin);
|
||||
}
|
||||
|
||||
/* Wayland popup windows must not get an appicon. */
|
||||
if (wwin->wm_class && strcmp(wwin->wm_class, "wings-popup") == 0)
|
||||
wwin->client_flags.no_appicon = 1;
|
||||
/* Setup descriptors and save window to internal lists */
|
||||
if (wwin->main_window != WM_NATIVE_NONE) {
|
||||
WApplication *app;
|
||||
|
|
|
|||
Loading…
Reference in New Issue