Browse Source

Wayland: add control of targeted screen by fullscreen windows

pull/758/head
ManoloFLTK 2 years ago
parent
commit
6f05af3c12
  1. 8
      documentation/src/wayland.dox
  2. 37
      src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx

8
documentation/src/wayland.dox

@ -382,6 +382,14 @@ to detect that Wayland needs be informed of the desired size change, which gets @@ -382,6 +382,14 @@ to detect that Wayland needs be informed of the desired size change, which gets
to \c libdecor_frame_commit(). Wayland later calls \c handle_configure() and events described
above unfold.
Wayland generally does not provide a way to control where the compositor should map a window
in the system displays. Nevertheless, for multi-display systems, Wayland allows to control
on what display should the compositor map a fullscreen window. That is done inside function
\c handle_configure() which calls \c libdecor_frame_set_fullscreen() for DECORATED windows
and inside function \c xdg_toplevel_configure() which calls \c xdg_toplevel_set_fullscreen()
for UNFRAMED. The <tt>struct wl_output</tt> pointer for the targetted display is transmitted
as 2nd argument of these calls.
\section menu-windows Menu windows and other popups
Menu windows, tiny menu title windows, and tooltip windows are implemented using Wayland's
popup mechanism which allows to position a popup window relatively to a previously mapped

37
src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx

@ -749,6 +749,17 @@ Fl_Window *Fl_Wayland_Window_Driver::surface_to_window(struct wl_surface *surfac @@ -749,6 +749,17 @@ Fl_Window *Fl_Wayland_Window_Driver::surface_to_window(struct wl_surface *surfac
}
static struct Fl_Wayland_Screen_Driver::output *screen_num_to_output(int num_screen) {
Fl_Wayland_Screen_Driver *scr_driver = (Fl_Wayland_Screen_Driver*)Fl::screen_driver();
int i = 0;
Fl_Wayland_Screen_Driver::output *output;
wl_list_for_each(output, &(scr_driver->outputs), link) { // all screens of the system
if (i++ == num_screen) return output;
}
return NULL;
}
static void handle_configure(struct libdecor_frame *frame,
struct libdecor_configuration *configuration, void *user_data)
{
@ -766,9 +777,14 @@ static void handle_configure(struct libdecor_frame *frame, @@ -766,9 +777,14 @@ static void handle_configure(struct libdecor_frame *frame,
if (!window->xdg_surface) window->xdg_surface = libdecor_frame_get_xdg_surface(frame);
struct wl_output *wl_output = NULL;
if (window->fl_win->fullscreen_active()) {
if (!(window->state & LIBDECOR_WINDOW_STATE_FULLSCREEN)) {
libdecor_frame_set_fullscreen(window->frame, NULL);
if (Fl_Window_Driver::driver(window->fl_win)->force_position()) {
struct Fl_Wayland_Screen_Driver::output *output = screen_num_to_output(window->fl_win->screen_num());
if (output) wl_output = output->wl_output;
}
libdecor_frame_set_fullscreen(window->frame, wl_output);
}
} else if (driver->show_iconic()) {
libdecor_frame_set_minimized(window->frame);
@ -799,6 +815,13 @@ static void handle_configure(struct libdecor_frame *frame, @@ -799,6 +815,13 @@ static void handle_configure(struct libdecor_frame *frame,
} else { width = height = 0; }
}
if (window->fl_win->fullscreen_active() &&
Fl_Window_Driver::driver(window->fl_win)->force_position()) {
int X, Y, W, H;
Fl::screen_xywh(X, Y, W, H, window->fl_win->screen_num());
width = W * f; height = H * f;
}
if (width == 0) {
width = window->floating_width;
height = window->floating_height;
@ -808,6 +831,7 @@ static void handle_configure(struct libdecor_frame *frame, @@ -808,6 +831,7 @@ static void handle_configure(struct libdecor_frame *frame,
driver->in_handle_configure = true;
window->fl_win->resize(0, 0, ceil(width / f), ceil(height / f));
driver->in_handle_configure = false;
if (wl_output) window->fl_win->redraw();
if (ceil(width / f) != window->configured_width || ceil(height / f) != window->configured_height) {
if (window->buffer) {
@ -956,7 +980,16 @@ static void xdg_toplevel_configure(void *data, struct xdg_toplevel *xdg_toplevel @@ -956,7 +980,16 @@ static void xdg_toplevel_configure(void *data, struct xdg_toplevel *xdg_toplevel
struct wld_window *window = (struct wld_window*)data;
//fprintf(stderr, "xdg_toplevel_configure: surface=%p size: %dx%d\n", window->wl_surface, width, height);
if (window->fl_win->fullscreen_active() && !parse_states_fullscreen(states)) {
xdg_toplevel_set_fullscreen(xdg_toplevel, NULL);
struct wl_output *wl_output = NULL;
if (Fl_Window_Driver::driver(window->fl_win)->force_position()) {
struct Fl_Wayland_Screen_Driver::output *output = screen_num_to_output(window->fl_win->screen_num());
if (output) wl_output = output->wl_output;
}
xdg_toplevel_set_fullscreen(xdg_toplevel, wl_output);
if (wl_output) {
int X, Y;
Fl::screen_xywh(X, Y, width, height, window->fl_win->screen_num());
}
}
if (window->configured_width) Fl_Window_Driver::driver(window->fl_win)->wait_for_expose_value = 0;
float f = Fl::screen_scale(window->fl_win->screen_num());

Loading…
Cancel
Save