diff options
| author | ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> | 2025-03-16 09:10:14 +0100 |
|---|---|---|
| committer | ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> | 2025-03-17 14:49:17 +0100 |
| commit | 6b9fb46b966f8c134004f75ec1b386ba7c6ef586 (patch) | |
| tree | 399ff4be352fc328750dc40905c29f578162bf7e /src | |
| parent | ed4fded9d94f05b8f4e55c818de5b21ffd885278 (diff) | |
Wayland: improve support of addition/removal of displays while FLTK runs
Diffstat (limited to 'src')
| -rw-r--r-- | src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx | 36 | ||||
| -rw-r--r-- | src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx | 21 |
2 files changed, 22 insertions, 35 deletions
diff --git a/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx index 304395936..534d70bb5 100644 --- a/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx +++ b/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx @@ -1114,11 +1114,6 @@ static void output_mode(void *data, struct wl_output *wl_output, uint32_t flags, } -static bool compute_full_and_maximized_areas(Fl_Wayland_Screen_Driver::output *output, - int& Wfullscreen, int& Hfullscreen, - int& Wworkarea, int& Hworkarea); - - static void output_done(void *data, struct wl_output *wl_output) { // Runs at startup and when desktop scale factor is changed or screen added @@ -1147,13 +1142,7 @@ static void output_done(void *data, struct wl_output *wl_output) Fl_Wayland_Screen_Driver *scr_driver = (Fl_Wayland_Screen_Driver*)Fl::screen_driver(); if (scr_driver->screen_count_get() > 0) { // true when output_done runs after initial screen dectection scr_driver->screen_count_set( wl_list_length(&(scr_driver->outputs)) ); - int Wfullscreen, Hfullscreen, Wworkarea, Hworkarea; - compute_full_and_maximized_areas(output, Wfullscreen, Hfullscreen, Wworkarea, Hworkarea); - if (Wfullscreen && Hfullscreen) { - output->width = Wfullscreen * output->wld_scale; // pixels - output->height = Hfullscreen * output->wld_scale; // pixels - } - Fl::handle(FL_SCREEN_CONFIGURATION_CHANGED, NULL); + scr_driver->init_workarea(); } } @@ -1290,7 +1279,11 @@ static void registry_handle_global(void *user_data, struct wl_registry *wl_regis wl_list_for_each(elt, &scr_driver->outputs, link) { if (elt == output) found = true; } - if (!found) wl_list_insert(&(scr_driver->outputs), &output->link); + if (!found) { // add to end of the linked list of displays + struct wl_list *e = &scr_driver->outputs; + while (e->next != &scr_driver->outputs) e = e->next; // move e to end of linked list + wl_list_insert(e, &output->link); + } //fprintf(stderr, "wl_output: id=%d wl_output=%p \n", id, output->wl_output); } else if (strcmp(interface, xdg_wm_base_interface.name) == 0) { @@ -1333,25 +1326,12 @@ static void registry_handle_global(void *user_data, struct wl_registry *wl_regis static void registry_handle_global_remove(void *data, struct wl_registry *registry, uint32_t name) { - Fl_Wayland_Screen_Driver::output *output, *tmp; + Fl_Wayland_Screen_Driver::output *output; //fprintf(stderr, "registry_handle_global_remove data=%p id=%u\n", data, name); Fl_Wayland_Screen_Driver *scr_driver = (Fl_Wayland_Screen_Driver*)Fl::screen_driver(); bool has_removed_screen = false; - wl_list_for_each_safe(output, tmp, &(scr_driver->outputs), link) { // all screens + wl_list_for_each(output, &(scr_driver->outputs), link) { // all screens if (output->id == name) { // the screen being removed - again: - Fl_X *xp = Fl_X::first; - while (xp) { // all mapped windows - struct wld_window *win = (struct wld_window*)xp->xid; - struct Fl_Wayland_Window_Driver::surface_output *s_output; - wl_list_for_each(s_output, &win->outputs, link) { - if (output == s_output->output) { - delete win->fl_win; - goto again; - } - } - xp = xp->next; - } wl_list_remove(&output->link); wl_output_destroy(output->wl_output); free(output); diff --git a/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx index 75d3f05b7..8e12091ba 100644 --- a/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx +++ b/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx @@ -658,6 +658,14 @@ static struct libdecor_interface libdecor_iface = { }; + +static void delayed_rescale(Fl_Window *win) { + Fl_Window_Driver::driver(win)->is_a_rescale(true); + win->size(win->w(), win->h()); + Fl_Window_Driver::driver(win)->is_a_rescale(false); +} + + void change_scale(Fl_Wayland_Screen_Driver::output *output, struct wld_window *window, float pre_scale) { Fl_Wayland_Window_Driver *win_driver = Fl_Wayland_Window_Driver::driver(window->fl_win); @@ -681,9 +689,8 @@ void change_scale(Fl_Wayland_Screen_Driver::output *output, struct wld_window *w Fl_Wayland_Graphics_Driver::buffer_release(window); window->fl_win->redraw(); } else { - win_driver->is_a_rescale(true); - window->fl_win->size(window->fl_win->w(), window->fl_win->h()); - win_driver->is_a_rescale(false); + // delaying the rescaling is necessary to set first the window's size_range according to the new screen + Fl::add_timeout(0, (Fl_Timeout_Handler)delayed_rescale, window->fl_win); } } if (window->fl_win->as_gl_window()) @@ -715,7 +722,7 @@ static void surface_enter(void *data, struct wl_surface *wl_surface, while (e->next != &window->outputs) e = e->next; // move e to end of linked list wl_list_insert(e, &surface_output->link); //printf("window %p enters screen id=%d length=%d\n", window->fl_win, output->id, wl_list_length(&window->outputs)); - if (list_was_empty) { + if (list_was_empty && !window->fl_win->parent()) { change_scale(output, window, pre_scale); } } @@ -741,7 +748,7 @@ static void surface_leave(void *data, struct wl_surface *wl_surface, break; } } - if (count == 1 && !wl_list_empty(&window->outputs)) { + if (count == 1 && !wl_list_empty(&window->outputs) && !window->fl_win->parent()) { s_output = wl_container_of(window->outputs.next, s_output, link); change_scale(s_output->output, window, pre_scale); } @@ -1353,11 +1360,11 @@ bool Fl_Wayland_Window_Driver::process_menu_or_tooltip(struct wld_window *new_wi // results in tall popup windows starting at the top of the screen, what we want. // Unfortunately, we know the work area height exactly only for single-screen systems, // otherwise FLTK returns work area height == screen height. In that case we estimate - // work area height ≈ screen height - 40. + // work area height ≈ screen height - 44. int V, work_area_H, screen_H; Fl::screen_work_area(V, V, V, work_area_H, origin_win->screen_num()); Fl::screen_xywh(V, V, V, screen_H, origin_win->screen_num()); - if (work_area_H == screen_H) work_area_H -= 40; + if (work_area_H == screen_H) work_area_H -= 44; if (positioner_H > work_area_H) positioner_H = work_area_H; } xdg_positioner_set_size(positioner, pWindow->w() * f , positioner_H * f ); |
