steamcompmgr: extend input focus concept to allow mouse-only focus

This commit is contained in:
Pierre-Loup A. Griffais 2021-05-25 23:13:38 -07:00 committed by Pierre-Loup A. Griffais
parent 9d40b61645
commit 9a20f630ad

View file

@ -117,7 +117,7 @@ typedef struct _win {
Bool isSteam; Bool isSteam;
Bool isSteamStreamingClient; Bool isSteamStreamingClient;
Bool isSteamStreamingClientVideo; Bool isSteamStreamingClientVideo;
Bool wantsInputFocus; uint32_t inputFocusMode;
uint32_t appID; uint32_t appID;
Bool isOverlay; Bool isOverlay;
Bool isFullscreen; Bool isFullscreen;
@ -161,6 +161,7 @@ uint32_t currentOutputWidth, currentOutputHeight;
static Window currentFocusWindow; static Window currentFocusWindow;
static win* currentFocusWin; static win* currentFocusWin;
static Window currentInputFocusWindow; static Window currentInputFocusWindow;
uint32_t currentInputFocusMode;
static Window currentOverlayWindow; static Window currentOverlayWindow;
static Window currentNotificationWindow; static Window currentNotificationWindow;
@ -530,6 +531,10 @@ find_win (Display *dpy, Window id)
return w; return w;
} }
} }
if ( dpy == nullptr )
return nullptr;
// Didn't find, must be a children somewhere; try again with parent. // Didn't find, must be a children somewhere; try again with parent.
Window root = None; Window root = None;
Window parent = None; Window parent = None;
@ -1490,7 +1495,7 @@ determine_and_apply_focus (Display *dpy, MouseCursor *cursor)
} }
} }
if ( w->wantsInputFocus ) if ( w->inputFocusMode )
{ {
inputFocus = w; inputFocus = w;
} }
@ -1634,29 +1639,36 @@ found:
currentFocusWindow = focus->id; currentFocusWindow = focus->id;
currentFocusWin = focus; currentFocusWin = focus;
if ( currentInputFocusWindow != inputFocus->id ) if ( currentInputFocusWindow != inputFocus->id ||
currentInputFocusMode != inputFocus->inputFocusMode )
{ {
if ( currentInputFocusWindow != focus->id ) if ( currentInputFocusWindow != focus->id )
{ {
set_win_hidden( dpy, find_win(dpy, currentInputFocusWindow), True ); set_win_hidden( dpy, find_win(dpy, currentInputFocusWindow), True );
} }
win *keyboardFocusWin = inputFocus;
if ( inputFocus->inputFocusMode == 2 )
keyboardFocusWin = focus;
if ( focus->surface.wlr != nullptr ) if ( inputFocus->surface.wlr != nullptr || keyboardFocusWin->surface.wlr != nullptr )
{ {
wlserver_lock(); wlserver_lock();
if ( focus->surface.wlr != nullptr ) if ( inputFocus->surface.wlr != nullptr )
{ wlserver_mousefocus( inputFocus->surface.wlr );
wlserver_keyboardfocus( focus->surface.wlr );
wlserver_mousefocus( focus->surface.wlr ); if ( keyboardFocusWin->surface.wlr != nullptr )
} wlserver_keyboardfocus( keyboardFocusWin->surface.wlr );
wlserver_unlock(); wlserver_unlock();
} }
XSetInputFocus(dpy, inputFocus->id, RevertToNone, CurrentTime); XSetInputFocus(dpy, keyboardFocusWin->id, RevertToNone, CurrentTime);
currentInputFocusWindow = inputFocus->id; currentInputFocusWindow = inputFocus->id;
currentInputFocusMode = inputFocus->inputFocusMode;
} }
w = focus; w = focus;
@ -1856,7 +1868,7 @@ map_win (Display *dpy, Window id, unsigned long sequence)
get_win_title( dpy, w, netWMNameAtom ); get_win_title( dpy, w, netWMNameAtom );
get_win_title( dpy, w, XA_WM_NAME ); get_win_title( dpy, w, XA_WM_NAME );
w->wantsInputFocus = get_prop(dpy, w->id, steamInputFocusAtom, 0); w->inputFocusMode = get_prop(dpy, w->id, steamInputFocusAtom, 0);
w->isSteamStreamingClient = get_prop(dpy, w->id, steamStreamingClientAtom, 0); w->isSteamStreamingClient = get_prop(dpy, w->id, steamStreamingClientAtom, 0);
w->isSteamStreamingClientVideo = get_prop(dpy, w->id, steamStreamingClientVideoAtom, 0); w->isSteamStreamingClientVideo = get_prop(dpy, w->id, steamStreamingClientVideoAtom, 0);
@ -2102,7 +2114,7 @@ add_win (Display *dpy, Window id, Window prev, unsigned long sequence)
new_win->isSteam = False; new_win->isSteam = False;
new_win->isSteamStreamingClient = False; new_win->isSteamStreamingClient = False;
new_win->isSteamStreamingClientVideo = False; new_win->isSteamStreamingClientVideo = False;
new_win->wantsInputFocus = False; new_win->inputFocusMode = 0;
if ( steamMode == True ) if ( steamMode == True )
{ {
@ -2326,7 +2338,7 @@ damage_win (Display *dpy, XDamageNotifyEvent *de)
w->damage_sequence = damageSequence++; w->damage_sequence = damageSequence++;
// If we just passed the focused window, we might be eliglible to take over // If we just passed the focused window, we might be eliglible to take over
if (focus && focus != w && w->appID && if ( !focusControlled && focus && focus != w && w->appID &&
w->damage_sequence > focus->damage_sequence) w->damage_sequence > focus->damage_sequence)
focusDirty = True; focusDirty = True;
@ -2355,10 +2367,16 @@ handle_wl_surface_id(win *w, long surfaceID)
// If we already focused on our side and are handling this late, // If we already focused on our side and are handling this late,
// let wayland know now. // let wayland know now.
if ( w->id == currentInputFocusWindow ) if ( w->id == currentInputFocusWindow )
{
wlserver_keyboardfocus( surface );
wlserver_mousefocus( surface ); wlserver_mousefocus( surface );
}
win *inputFocusWin = find_win( nullptr, currentInputFocusWindow );
Window keyboardFocusWindow = currentInputFocusWindow;
if ( inputFocusWin && inputFocusWin->inputFocusMode == 2 )
keyboardFocusWindow = currentFocusWindow;
if ( w->id == keyboardFocusWindow )
wlserver_keyboardfocus( surface );
// Pull the first buffer out of that window, if needed // Pull the first buffer out of that window, if needed
xwayland_surface_role_commit( surface ); xwayland_surface_role_commit( surface );
@ -2517,7 +2535,7 @@ handle_property_notify(Display *dpy, XPropertyEvent *ev)
win * w = find_win(dpy, ev->window); win * w = find_win(dpy, ev->window);
if (w) if (w)
{ {
w->wantsInputFocus = get_prop(dpy, w->id, steamInputFocusAtom, 0); w->inputFocusMode = get_prop(dpy, w->id, steamInputFocusAtom, 0);
focusDirty = True; focusDirty = True;
} }
} }