xwayland: add fullscreen mode for rootful

Add a new command line option "-fullscreen" to make the rootful Xwayland
window appear fullscreen.

This requires viewport support in the compositor and when used with
"-geometry" can emulate the full range of XRandR resolutions.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
This commit is contained in:
Olivier Fourdan 2022-05-12 12:04:29 +02:00
parent 5ef4ad0af2
commit d370f1e58a
7 changed files with 108 additions and 3 deletions

View File

@ -53,6 +53,11 @@ backend first, then fallback to the GBM backend if EGLStream is not supported
by the Wayland server. Without this option, \fIXwayland\fP tries the GBM
backend first, and fallback to EGLStream if GBM is not usable.
.TP 8
.B \-fullscreen
Set the Xwayland window fullscreen when running rootful.
This option is not compatible with rootless mode (\fI-rootless\fP).
.TP 8
.B \-geometry \fIWxH\fP
Sets the geometry of the \fIXwayland\fP window to \fIWxH\fP when running rootful.

View File

@ -676,6 +676,9 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
}
use_fixed_size = 1;
}
else if (strcmp(argv[i], "-fullscreen") == 0) {
xwl_screen->fullscreen = 1;
}
}
if (use_fixed_size) {
@ -732,6 +735,16 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
&registry_listener, xwl_screen);
xwl_screen_roundtrip(xwl_screen);
if (xwl_screen->fullscreen && xwl_screen->rootless) {
ErrorF("error, cannot set fullscreen when running rootless\n");
return FALSE;
}
if (xwl_screen->fullscreen && !xwl_screen_has_viewport_support(xwl_screen)) {
ErrorF("missing viewport support in the compositor, ignoring fullscreen\n");
xwl_screen->fullscreen = FALSE;
}
if (!xwl_screen->rootless && !xwl_screen->xdg_wm_base) {
ErrorF("missing XDG-WM-Base protocol\n");
return FALSE;

View File

@ -58,6 +58,7 @@ struct xwl_screen {
int glamor;
int present;
int force_xrandr_emulation;
int fullscreen;
CreateScreenResourcesProcPtr CreateScreenResources;
CloseScreenProcPtr CloseScreen;

View File

@ -267,6 +267,41 @@ window_get_client_toplevel(WindowPtr window)
return window;
}
static struct xwl_output *
xwl_window_get_output(struct xwl_window *xwl_window)
{
struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
struct xwl_output *xwl_output;
xwl_output = xwl_output_from_wl_output(xwl_screen, xwl_window->wl_output);
if (xwl_output)
return xwl_output;
return xwl_screen_get_first_output(xwl_screen);
}
static Bool
xwl_window_should_enable_viewport_fullscreen(struct xwl_window *xwl_window,
struct xwl_output **xwl_output_ret,
struct xwl_emulated_mode *emulated_mode_ret)
{
struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
struct xwl_output *xwl_output;
xwl_output = xwl_window_get_output(xwl_window);
if (!xwl_output)
return FALSE;
*xwl_output_ret = xwl_output;
emulated_mode_ret->server_output_id = 0;
emulated_mode_ret->width = xwl_screen->width;
emulated_mode_ret->height = xwl_screen->height;
emulated_mode_ret->from_vidmode = FALSE;
return TRUE;
}
static Bool
xwl_window_should_enable_viewport(struct xwl_window *xwl_window,
struct xwl_output **xwl_output_ret,
@ -279,7 +314,15 @@ xwl_window_should_enable_viewport(struct xwl_window *xwl_window,
WindowPtr window;
DrawablePtr drawable;
if (!xwl_screen_has_resolution_change_emulation(xwl_screen))
if (!xwl_screen_has_viewport_support(xwl_screen))
return FALSE;
if (xwl_screen->fullscreen)
return xwl_window_should_enable_viewport_fullscreen(xwl_window,
xwl_output_ret,
emulated_mode_ret);
if (!xwl_screen->rootless)
return FALSE;
window = window_get_client_toplevel(xwl_window->window);
@ -401,12 +444,44 @@ send_surface_id_event(struct xwl_window *xwl_window)
&e, 1, SubstructureRedirectMask, NullGrab);
}
static Bool
xwl_window_set_fullscreen(struct xwl_window *xwl_window)
{
struct xwl_output *xwl_output;
struct wl_output *wl_output = NULL;
if (!xwl_window->xdg_toplevel)
return FALSE;
xwl_output = xwl_window_get_output(xwl_window);
if (xwl_output)
wl_output = xwl_output->output;
if (wl_output && xwl_window->wl_output_fullscreen == wl_output)
return FALSE;
xdg_toplevel_set_fullscreen(xwl_window->xdg_toplevel, wl_output);
xwl_window_check_resolution_change_emulation(xwl_window);
wl_surface_commit(xwl_window->surface);
xwl_window->wl_output_fullscreen = wl_output;
return TRUE;
}
static void
xdg_surface_handle_configure(void *data,
struct xdg_surface *xdg_surface,
uint32_t serial)
{
struct xwl_window *xwl_window = data;
struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
if (xwl_screen->fullscreen)
xwl_window_set_fullscreen(xwl_window);
xdg_surface_ack_configure(xdg_surface, serial);
wl_surface_commit(xwl_window->surface);
}
static const struct xdg_surface_listener xdg_surface_listener = {
@ -419,9 +494,14 @@ xwl_window_surface_enter(void *data,
struct wl_output *wl_output)
{
struct xwl_window *xwl_window = data;
struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
if (xwl_window->wl_output != wl_output)
if (xwl_window->wl_output != wl_output) {
xwl_window->wl_output = wl_output;
if (xwl_screen->fullscreen)
xwl_window_set_fullscreen(xwl_window);
}
}
static void
@ -533,7 +613,7 @@ ensure_surface_for_window(WindowPtr window)
/* When a new window-manager window is realized, then the randr emulation
* props may have not been set on the managed client window yet.
*/
if (window_is_wm_window(window)) {
if (!xwl_screen->fullscreen && window_is_wm_window(window)) {
toplevel = window_get_client_toplevel(window);
if (toplevel)
xwl_output_set_window_randr_emu_props(xwl_screen, toplevel);

View File

@ -53,6 +53,7 @@ struct xwl_window {
struct xorg_list window_buffers_unavailable;
OsTimerPtr window_buffers_timer;
struct wl_output *wl_output;
struct wl_output *wl_output_fullscreen;
#ifdef GLAMOR_HAS_GBM
struct xorg_list frame_callback_list;
Bool present_flipped;

View File

@ -91,6 +91,7 @@ void
ddxUseMsg(void)
{
ErrorF("-rootless run rootless, requires wm support\n");
ErrorF("-fullscreen run fullscreen when rootful\n");
ErrorF("-geometry WxH set Xwayland window size when rootful\n");
ErrorF("-wm fd create X client for wm on given fd\n");
ErrorF("-initfd fd add given fd as a listen socket for initialization clients\n");
@ -229,6 +230,9 @@ ddxProcessArgument(int argc, char *argv[], int i)
CHECK_FOR_REQUIRED_ARGUMENTS(1);
return 2;
}
else if (strcmp(argv[i], "-fullscreen") == 0) {
return 1;
}
return 0;
}

View File

@ -14,3 +14,4 @@ have_terminate_delay=true
have_no_touch_pointer_emulation=true
have_force_xrandr_emulation=true
have_geometry=true
have_fullscreen=true