mirror of
https://github.com/labwc/labwc.git
synced 2026-04-11 08:21:13 -04:00
view: update focused surface and activated view together
When minimizing the last/only focusable view, its "activated" state is set to false, and server->focused_view is cleared, but at the wlroots level the focused surface is not cleared (seat_focus_surface() is not called). When attempting to unminimize, desktop_focus_and_activate_view() sees that view->surface is still focused, and returns without setting the activated state of the view; server->focused_view also remains NULL. To try and keep everything in sync better, replace view_set_activated() with view_set_focused(), which allows setting or clearing both the focus and the activated state of the view. Then use the new function in both view_minimize() and desktop_focus_and_activate_view().
This commit is contained in:
parent
ce36cbac2d
commit
7327a38d9a
3 changed files with 39 additions and 32 deletions
|
|
@ -257,7 +257,7 @@ bool view_isfocusable(struct view *view);
|
||||||
bool view_inhibits_keybinds(struct view *view);
|
bool view_inhibits_keybinds(struct view *view);
|
||||||
void view_toggle_keybinds(struct view *view);
|
void view_toggle_keybinds(struct view *view);
|
||||||
|
|
||||||
void view_set_activated(struct view *view);
|
void view_set_focused(struct view *view, bool focused);
|
||||||
void view_set_output(struct view *view, struct output *output);
|
void view_set_output(struct view *view, struct output *output);
|
||||||
void view_close(struct view *view);
|
void view_close(struct view *view);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -69,16 +69,7 @@ desktop_focus_and_activate_view(struct seat *seat, struct view *view)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_surface *prev_surface;
|
view_set_focused(view, true);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct wl_list *
|
static struct wl_list *
|
||||||
|
|
|
||||||
54
src/view.c
54
src/view.c
|
|
@ -187,19 +187,46 @@ _view_set_activated(struct view *view, bool activated)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Gives or removes keyboard focus to/from the view and updates the
|
||||||
|
* view's "activated" state to match.
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
view_set_activated(struct view *view)
|
view_set_focused(struct view *view, bool focused)
|
||||||
{
|
{
|
||||||
assert(view);
|
assert(view);
|
||||||
struct view *last = view->server->focused_view;
|
struct seat *seat = &view->server->seat;
|
||||||
if (last == view) {
|
struct view *focused_view = view->server->focused_view;
|
||||||
return;
|
struct wlr_surface *focused_surface =
|
||||||
}
|
seat->seat->keyboard_state.focused_surface;
|
||||||
if (last) {
|
|
||||||
_view_set_activated(last, false);
|
/*
|
||||||
|
* Here we assume that server->focused_view is the only view in
|
||||||
|
* the "activated" state. We do NOT assume that focused_view is
|
||||||
|
* necessarily in sync with focused_surface, since keyboard
|
||||||
|
* focus can be updated independently for various reasons
|
||||||
|
* (screen lockers, unmanaged XWayland surfaces, etc.)
|
||||||
|
*/
|
||||||
|
if (focused) {
|
||||||
|
if (view != focused_view) {
|
||||||
|
if (focused_view) {
|
||||||
|
_view_set_activated(focused_view, false);
|
||||||
}
|
}
|
||||||
_view_set_activated(view, true);
|
_view_set_activated(view, true);
|
||||||
view->server->focused_view = view;
|
view->server->focused_view = view;
|
||||||
|
}
|
||||||
|
if (view->surface != focused_surface) {
|
||||||
|
seat_focus_surface(seat, view->surface);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (view == focused_view) {
|
||||||
|
_view_set_activated(view, false);
|
||||||
|
view->server->focused_view = NULL;
|
||||||
|
}
|
||||||
|
if (view->surface == focused_surface) {
|
||||||
|
seat_focus_surface(seat, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -377,18 +404,7 @@ _minimize(struct view *view, bool minimized)
|
||||||
view->minimized = minimized;
|
view->minimized = minimized;
|
||||||
if (minimized) {
|
if (minimized) {
|
||||||
view->impl->unmap(view, /* client_request */ false);
|
view->impl->unmap(view, /* client_request */ false);
|
||||||
_view_set_activated(view, false);
|
view_set_focused(view, false);
|
||||||
if (view == view->server->focused_view) {
|
|
||||||
/*
|
|
||||||
* Prevents clearing the active view when
|
|
||||||
* we don't actually have keyboard focus.
|
|
||||||
*
|
|
||||||
* This may happen when using a custom mouse
|
|
||||||
* focus configuration or by using the foreign
|
|
||||||
* toplevel protocol via some panel.
|
|
||||||
*/
|
|
||||||
view->server->focused_view = NULL;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
view->impl->map(view);
|
view->impl->map(view);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue