mirror of
https://github.com/labwc/labwc.git
synced 2026-02-15 22:05:25 -05:00
view: try to reduce confusion in focused_view tracking
Our current approach to handling the focused/active view is a bit confusing. In particular, it's hard to be sure when server->focused_view is or isn't in sync with the real wlroots keyboard focus. Try to clean things up a bit. In particular: - Add comments to server->focused_view and desktop_focused_view() to clarify that they should match, but it's not guaranteed. - desktop_focused_view() now prints a warning if it detects that server->focused_view is out of sync. We should keep an eye out for this warning, and if we see it, try to figure out why it happened. - For consistency, use only "focus/defocus" as the verbs in function names rather than "activate". This is a bit arbitrary, but the idea is that focus is the primary action while the active/inactive state is a side effect. - view_focus/defocus() replace view_set_activated() and now update both focus and active/inactive state, to try to keep them in sync. - Add comments at view_focus/defocus() to warn against calling them directly (we should generally call the desktop.c functions). - desktop_focus_view(NULL) is now forbidden and is no longer handled as a special case to clear the focus. This was (at least to me) a surprising behavior and caused trouble when working on another change. - To maintain existing behavior, desktop_focus_topmost_mapped_view() now explicitly clears the focus if there are no mapped views. There should be no behavioral change here.
This commit is contained in:
parent
003d1fd494
commit
3022985ba7
11 changed files with 100 additions and 60 deletions
|
|
@ -35,13 +35,9 @@ desktop_arrange_all_views(struct server *server)
|
|||
}
|
||||
|
||||
void
|
||||
desktop_focus_and_activate_view(struct seat *seat, struct view *view)
|
||||
desktop_focus_view(struct view *view)
|
||||
{
|
||||
if (!view) {
|
||||
seat_focus_surface(seat, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
assert(view);
|
||||
/*
|
||||
* Guard against views with no mapped surfaces when handling
|
||||
* 'request_activate' and 'request_minimize'.
|
||||
|
|
@ -51,8 +47,9 @@ desktop_focus_and_activate_view(struct seat *seat, struct view *view)
|
|||
return;
|
||||
}
|
||||
|
||||
if (input_inhibit_blocks_surface(seat, view->surface->resource)
|
||||
|| seat->server->session_lock) {
|
||||
struct server *server = view->server;
|
||||
if (input_inhibit_blocks_surface(&server->seat, view->surface->resource)
|
||||
|| server->session_lock) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -69,16 +66,7 @@ desktop_focus_and_activate_view(struct seat *seat, struct view *view)
|
|||
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;
|
||||
}
|
||||
|
||||
view_set_activated(view);
|
||||
seat_focus_surface(seat, view->surface);
|
||||
view_focus(view);
|
||||
}
|
||||
|
||||
static struct wl_list *
|
||||
|
|
@ -210,28 +198,45 @@ struct view *
|
|||
desktop_focused_view(struct server *server)
|
||||
{
|
||||
struct seat *seat = &server->seat;
|
||||
struct wlr_surface *focused_surface;
|
||||
focused_surface = seat->seat->keyboard_state.focused_surface;
|
||||
if (!focused_surface) {
|
||||
return NULL;
|
||||
}
|
||||
struct view *view;
|
||||
wl_list_for_each(view, &server->views, link) {
|
||||
if (view->surface == focused_surface) {
|
||||
return view;
|
||||
struct wlr_surface *focused_surface =
|
||||
seat->seat->keyboard_state.focused_surface;
|
||||
struct view *focused_view = NULL;
|
||||
|
||||
if (focused_surface) {
|
||||
struct view *view;
|
||||
wl_list_for_each(view, &server->views, link) {
|
||||
if (view->surface == focused_surface) {
|
||||
focused_view = view;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
/* warn so we can identify cases where this occurs */
|
||||
if (focused_view != server->focused_view) {
|
||||
wlr_log(WLR_ERROR, "server->focused_view is out of sync");
|
||||
}
|
||||
|
||||
return focused_view;
|
||||
}
|
||||
|
||||
void
|
||||
desktop_focus_topmost_mapped_view(struct server *server)
|
||||
{
|
||||
struct view *view = desktop_topmost_mapped_view(server);
|
||||
desktop_focus_and_activate_view(&server->seat, view);
|
||||
if (view) {
|
||||
desktop_focus_view(view);
|
||||
view_move_to_front(view);
|
||||
} else {
|
||||
/*
|
||||
* Defocus previous focused surface/view if no longer
|
||||
* focusable (e.g. unmapped or on a different workspace).
|
||||
* Note than a non-view surface may have been focused.
|
||||
*/
|
||||
seat_focus_surface(&server->seat, NULL);
|
||||
if (server->focused_view) {
|
||||
view_defocus(server->focused_view);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -257,7 +262,7 @@ desktop_focus_output(struct output *output)
|
|||
}
|
||||
if (wlr_output_layout_intersects(layout,
|
||||
output->wlr_output, &view->current)) {
|
||||
desktop_focus_and_activate_view(&output->server->seat, view);
|
||||
desktop_focus_view(view);
|
||||
wlr_cursor_warp(output->server->seat.cursor, NULL,
|
||||
view->current.x + view->current.width / 2,
|
||||
view->current.y + view->current.height / 2);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue