mirror of
https://github.com/labwc/labwc.git
synced 2025-10-29 05:40:24 -04:00
view: add view_wants_focus enum (NEVER/ALWAYS/OFFER) and function
This allows identifying XWayland views using the ICCCM "Globally Active" input model. Later commits will improve handling of these views. No functional change in this commit.
This commit is contained in:
parent
8bb2e2123f
commit
dd7f563a50
3 changed files with 79 additions and 20 deletions
|
|
@ -36,6 +36,21 @@ enum view_edge {
|
|||
VIEW_EDGE_CENTER,
|
||||
};
|
||||
|
||||
enum view_wants_focus {
|
||||
/* View does not want focus */
|
||||
VIEW_WANTS_FOCUS_NEVER = 0,
|
||||
/* View wants focus */
|
||||
VIEW_WANTS_FOCUS_ALWAYS,
|
||||
/*
|
||||
* View should be offered focus and may accept or decline
|
||||
* (a.k.a. ICCCM Globally Active input model). Labwc generally
|
||||
* avoids focusing these views automatically (e.g. when another
|
||||
* view on top is closed) but they may be focused by user action
|
||||
* (e.g. mouse click).
|
||||
*/
|
||||
VIEW_WANTS_FOCUS_OFFER,
|
||||
};
|
||||
|
||||
struct view;
|
||||
struct wlr_surface;
|
||||
|
||||
|
|
@ -72,8 +87,8 @@ struct view_impl {
|
|||
/* determines if view and surface are owned by the same process */
|
||||
bool (*is_related)(struct view *self, struct wlr_surface *surface);
|
||||
struct view_size_hints (*get_size_hints)(struct view *self);
|
||||
/* if not implemented, view is assumed to want focus */
|
||||
bool (*wants_focus)(struct view *self);
|
||||
/* if not implemented, VIEW_WANTS_FOCUS_ALWAYS is assumed */
|
||||
enum view_wants_focus (*wants_focus)(struct view *self);
|
||||
};
|
||||
|
||||
struct view {
|
||||
|
|
@ -273,6 +288,8 @@ struct view *view_next(struct wl_list *head, struct view *view,
|
|||
void view_array_append(struct server *server, struct wl_array *views,
|
||||
enum lab_view_criteria criteria);
|
||||
|
||||
enum view_wants_focus view_wants_focus(struct view *view);
|
||||
|
||||
/**
|
||||
* view_is_focusable() - Check whether or not a view can be focused
|
||||
* @view: view to be checked
|
||||
|
|
|
|||
12
src/view.c
12
src/view.c
|
|
@ -143,6 +143,16 @@ view_array_append(struct server *server, struct wl_array *views,
|
|||
}
|
||||
}
|
||||
|
||||
enum view_wants_focus
|
||||
view_wants_focus(struct view *view)
|
||||
{
|
||||
assert(view);
|
||||
if (view->impl->wants_focus) {
|
||||
return view->impl->wants_focus(view);
|
||||
}
|
||||
return VIEW_WANTS_FOCUS_ALWAYS;
|
||||
}
|
||||
|
||||
bool
|
||||
view_is_focusable(struct view *view)
|
||||
{
|
||||
|
|
@ -150,7 +160,7 @@ view_is_focusable(struct view *view)
|
|||
if (!view->surface) {
|
||||
return false;
|
||||
}
|
||||
if (view->impl->wants_focus && !view->impl->wants_focus(view)) {
|
||||
if (view_wants_focus(view) != VIEW_WANTS_FOCUS_ALWAYS) {
|
||||
return false;
|
||||
}
|
||||
return (view->mapped || view->minimized);
|
||||
|
|
|
|||
|
|
@ -30,29 +30,61 @@ xwayland_view_get_size_hints(struct view *view)
|
|||
};
|
||||
}
|
||||
|
||||
static bool
|
||||
static enum view_wants_focus
|
||||
xwayland_view_wants_focus(struct view *view)
|
||||
{
|
||||
xcb_icccm_wm_hints_t *hints = xwayland_surface_from_view(view)->hints;
|
||||
if (!hints) {
|
||||
return true;
|
||||
}
|
||||
struct wlr_xwayland_surface *xsurface =
|
||||
xwayland_surface_from_view(view);
|
||||
|
||||
switch (wlr_xwayland_icccm_input_model(xsurface)) {
|
||||
/*
|
||||
* Paraphrased from ICCCM section 4.1.7 (Input Focus):
|
||||
* Abbreviated from ICCCM section 4.1.7 (Input Focus):
|
||||
*
|
||||
* Clients set the input field of WM_HINTS to True to indicate
|
||||
* that they require window manager assistance in acquiring the
|
||||
* input focus. Clients set the input field to False to request
|
||||
* that the window manager not set the input focus to their
|
||||
* top-level window.
|
||||
* Passive Input - The client expects keyboard input but never
|
||||
* explicitly sets the input focus.
|
||||
* Locally Active Input - The client expects keyboard input and
|
||||
* explicitly sets the input focus, but it only does so when one
|
||||
* of its windows already has the focus.
|
||||
*
|
||||
* Clients that use XSetInputFocus() to explicitly set the input
|
||||
* focus should set the WM_TAKE_FOCUS atom in WM_PROTOCOLS.
|
||||
* Currently, labwc does not support this method of taking focus
|
||||
* and thus ignores WM_TAKE_FOCUS. These views can still be
|
||||
* focused by explicit user action (e.g. clicking in them).
|
||||
* Passive and Locally Active clients set the input field of
|
||||
* WM_HINTS to True, which indicates that they require window
|
||||
* manager assistance in acquiring the input focus.
|
||||
*/
|
||||
return (bool)hints->input;
|
||||
case WLR_ICCCM_INPUT_MODEL_PASSIVE:
|
||||
case WLR_ICCCM_INPUT_MODEL_LOCAL:
|
||||
return VIEW_WANTS_FOCUS_ALWAYS;
|
||||
|
||||
/*
|
||||
* Globally Active Input - The client expects keyboard input and
|
||||
* explicitly sets the input focus, even when it is in windows
|
||||
* the client does not own. ... It wants to prevent the window
|
||||
* manager from setting the input focus to any of its windows
|
||||
* [because it may or may not want focus].
|
||||
*
|
||||
* Globally Active client windows may receive a WM_TAKE_FOCUS
|
||||
* message from the window manager. If they want the focus, they
|
||||
* should respond with a SetInputFocus request.
|
||||
*
|
||||
* [Currently, labwc does not fully support clients voluntarily
|
||||
* taking focus via the WM_TAKE_FOCUS + SetInputFocus mechanism
|
||||
* and avoids automatically focusing Globally Active windows.
|
||||
* This may change in future.]
|
||||
*/
|
||||
case WLR_ICCCM_INPUT_MODEL_GLOBAL:
|
||||
return VIEW_WANTS_FOCUS_OFFER;
|
||||
|
||||
/*
|
||||
* No Input - The client never expects keyboard input.
|
||||
*
|
||||
* No Input and Globally Active clients set the input field to
|
||||
* False, which requests that the window manager not set the
|
||||
* input focus to their top-level window.
|
||||
*/
|
||||
case WLR_ICCCM_INPUT_MODEL_NONE:
|
||||
break;
|
||||
}
|
||||
|
||||
return VIEW_WANTS_FOCUS_NEVER;
|
||||
}
|
||||
|
||||
static struct wlr_xwayland_surface *
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue