From 9a290feeeab14d6800a438ce99cda0b9f1c84f29 Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Sat, 16 Oct 2021 19:44:54 +0100 Subject: [PATCH] desktop: simplify interface for view raise/focus Split desktop_focus_view() into the following two functions: - desktop_focus_and_activate_view() - desktop_raise_view() Always call view_set_activated() rather than using the private set_activated(). This keeps the code cleaner and ensures wlr_foreign_toplevel_handle_v1_set_activated() is called. --- include/labwc.h | 16 +++++++++++- src/cursor.c | 6 +++-- src/desktop.c | 69 ++++++++++++++++++++++++++++++++----------------- src/keyboard.c | 4 ++- src/xdg.c | 3 ++- src/xwayland.c | 3 ++- 6 files changed, 72 insertions(+), 29 deletions(-) diff --git a/include/labwc.h b/include/labwc.h index 3f1dea66..27185df2 100644 --- a/include/labwc.h +++ b/include/labwc.h @@ -340,8 +340,22 @@ void view_update_title(struct view *view); void foreign_toplevel_handle_create(struct view *view); +/* + * desktop.c routines deal with a collection of views + * + * Definition of a few keywords used in desktop.c + * raise - Bring view to front. + * focus - Give keyboard focus to view. + * activate - Set view surface as active so that client window decorations + * are painted to show that the window is active,typically by + * using a different color. Although xdg-shell protocol says you + * cannot assume this means that the window actually has keyboard + * or pointer focus, in this compositor are they called together. + */ + void desktop_set_focus_view_only(struct seat *seat, struct view *view); -void desktop_focus_view(struct seat *seat, struct view *view); +void desktop_raise_view(struct view *view); +void desktop_focus_and_activate_view(struct seat *seat, struct view *view); /** * desktop_cycle_view - return view to 'cycle' to diff --git a/src/cursor.c b/src/cursor.c index 64749885..b5dba5c8 100644 --- a/src/cursor.c +++ b/src/cursor.c @@ -182,7 +182,8 @@ process_cursor_motion(struct server *server, uint32_t time) if (view && rc.focus_follow_mouse) { if (rc.raise_on_focus) { - desktop_focus_view(&server->seat, view); + desktop_focus_and_activate_view(&server->seat, view); + desktop_raise_view(view); } else { desktop_set_focus_view_only(&server->seat, view); } @@ -384,7 +385,8 @@ cursor_button(struct wl_listener *listener, void *data) } /* Handle _press_ on view */ - desktop_focus_view(&server->seat, view); + desktop_focus_and_activate_view(&server->seat, view); + desktop_raise_view(view); damage_all_outputs(server); if (is_double_click(rc.doubleclick_time) diff --git a/src/desktop.c b/src/desktop.c index 934bb3c6..482949aa 100644 --- a/src/desktop.c +++ b/src/desktop.c @@ -95,7 +95,31 @@ desktop_set_focus_view_only(struct seat *seat, struct view *view) } void -desktop_focus_view(struct seat *seat, struct view *view) +desktop_raise_view(struct view *view) +{ + if (!view) { + return; + } + move_to_front(view); +#if HAVE_XWAYLAND + move_xwayland_sub_views_to_front(view); +#endif +} + +static void +deactivate_all_views(struct server *server) +{ + struct view *view; + wl_list_for_each (view, &server->views, link) { + if (!view->mapped) { + continue; + } + view_set_activated(view, false); + } +} + +void +desktop_focus_and_activate_view(struct seat *seat, struct view *view) { if (!view) { seat_focus_surface(seat, NULL); @@ -106,30 +130,28 @@ desktop_focus_view(struct seat *seat, struct view *view) } if (view->minimized) { - /* this will unmap and then focus */ + /* + * Unminimizing will map the view which triggers a call to this + * function again. + */ view_minimize(view, false); return; - } else if (view->mapped) { - struct wlr_surface *prev_surface; - prev_surface = seat->seat->keyboard_state.focused_surface; - if (prev_surface == view->surface) { - /* Don't re-focus an already focused surface. */ - move_to_front(view); -#if HAVE_XWAYLAND - move_xwayland_sub_views_to_front(view); -#endif - return; - } - if (prev_surface) { - set_activated(prev_surface, false); - } - move_to_front(view); - set_activated(view->surface, true); - seat_focus_surface(seat, view->surface); -#if HAVE_XWAYLAND - move_xwayland_sub_views_to_front(view); -#endif } + if (!view->mapped) { + return; + } + + struct wlr_surface *prev_surface; + prev_surface = seat->seat->keyboard_state.focused_surface; + + /* Do not re-focus an already focused surface. */ + if (prev_surface == view->surface) { + return; + } + + deactivate_all_views(view->server); + view_set_activated(view, true); + seat_focus_surface(seat, view->surface); } /* @@ -236,7 +258,8 @@ void desktop_focus_topmost_mapped_view(struct server *server) { struct view *view = topmost_mapped_view(server); - desktop_focus_view(&server->seat, view); + desktop_focus_and_activate_view(&server->seat, view); + desktop_raise_view(view); } static bool diff --git a/src/keyboard.c b/src/keyboard.c index 1460ba90..4f7fd253 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -43,7 +43,9 @@ keyboard_modifiers_notify(struct wl_listener *listener, void *data) if ((event->state == WL_KEYBOARD_KEY_STATE_RELEASED) && !any_modifiers_pressed(device->keyboard)) { /* end cycle */ - desktop_focus_view(&server->seat, server->cycle_view); + desktop_focus_and_activate_view(&server->seat, + server->cycle_view); + desktop_raise_view(server->cycle_view); server->cycle_view = NULL; } } diff --git a/src/xdg.c b/src/xdg.c index 202f285d..e8f9400c 100644 --- a/src/xdg.c +++ b/src/xdg.c @@ -343,7 +343,8 @@ xdg_toplevel_view_map(struct view *view) wl_signal_add(&view->surface->events.new_subsurface, &view->new_subsurface); - desktop_focus_view(&view->server->seat, view); + desktop_focus_and_activate_view(&view->server->seat, view); + desktop_raise_view(view); damage_all_outputs(view->server); } diff --git a/src/xwayland.c b/src/xwayland.c index eb730c6e..22d54859 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -208,7 +208,8 @@ map(struct view *view) &view->commit); view->commit.notify = handle_commit; - desktop_focus_view(&view->server->seat, view); + desktop_focus_and_activate_view(&view->server->seat, view); + desktop_raise_view(view); damage_all_outputs(view->server); } -- 2.52.0