SteamOS: refactor cursor management to allow the compositor to hide the cursor when not being moved for a period of time, like Tenfoot does.
This commit is contained in:
parent
6f3be23b46
commit
5a11ba7646
1 changed files with 69 additions and 10 deletions
|
@ -99,6 +99,8 @@ typedef struct _win {
|
|||
unsigned int requestedHeight;
|
||||
Bool nudged;
|
||||
Bool ignoreOverrideRedirect;
|
||||
|
||||
Bool mouseMoved;
|
||||
} win;
|
||||
|
||||
typedef struct _conv {
|
||||
|
@ -148,7 +150,13 @@ Bool cursorImageDirty = True;
|
|||
int cursorHotX, cursorHotY;
|
||||
int cursorWidth, cursorHeight;
|
||||
GLuint cursorTextureName;
|
||||
Bool cursorHidden = False;
|
||||
|
||||
Bool cursorVisible = True;
|
||||
Bool hideCursorForScale;
|
||||
Bool hideCursorForMovement;
|
||||
unsigned int lastCursorMovedTime;
|
||||
|
||||
#define CURSOR_HIDE_TIME 3000
|
||||
|
||||
Bool gotXError = False;
|
||||
|
||||
|
@ -430,6 +438,8 @@ teardown_win_resources (Display *dpy, win *w)
|
|||
XFreePixmap(dpy, w->pixmap);
|
||||
w->pixmap = None;
|
||||
}
|
||||
|
||||
w->damaged = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -473,6 +483,9 @@ paint_fake_cursor (Display *dpy, win *w)
|
|||
{
|
||||
XFixesCursorImage* im = XFixesGetCursorImage(dpy);
|
||||
|
||||
if (!im)
|
||||
return;
|
||||
|
||||
cursorHotX = im->xhot;
|
||||
cursorHotY = im->yhot;
|
||||
|
||||
|
@ -876,7 +889,8 @@ paint_all (Display *dpy)
|
|||
// Draw SW cursor if we need to
|
||||
if (w && focusedWindowNeedsScale && gameFocused)
|
||||
{
|
||||
paint_fake_cursor(dpy, w);
|
||||
if (!hideCursorForMovement)
|
||||
paint_fake_cursor(dpy, w);
|
||||
canUnredirect = False;
|
||||
}
|
||||
|
||||
|
@ -900,6 +914,25 @@ paint_all (Display *dpy)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
apply_cursor_state (Display *dpy)
|
||||
{
|
||||
Bool newCursorVisibility = True;
|
||||
|
||||
if (hideCursorForScale || hideCursorForMovement)
|
||||
newCursorVisibility = False;
|
||||
|
||||
if (newCursorVisibility != cursorVisible)
|
||||
{
|
||||
cursorVisible = newCursorVisibility;
|
||||
|
||||
if (cursorVisible)
|
||||
XFixesShowCursor(dpy, DefaultRootWindow(dpy));
|
||||
else
|
||||
XFixesHideCursor(dpy, DefaultRootWindow(dpy));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
setup_pointer_barriers (Display *dpy)
|
||||
{
|
||||
|
@ -918,18 +951,16 @@ setup_pointer_barriers (Display *dpy)
|
|||
|
||||
if (focusedWindowNeedsScale == False)
|
||||
{
|
||||
if (cursorHidden) {
|
||||
XFixesShowCursor(dpy, DefaultRootWindow(dpy));
|
||||
cursorHidden = False;
|
||||
}
|
||||
hideCursorForScale = False;
|
||||
apply_cursor_state(dpy);
|
||||
return;
|
||||
}
|
||||
|
||||
// If we're scaling, take ownership of the cursor
|
||||
if (doRender && !cursorHidden)
|
||||
if (doRender)
|
||||
{
|
||||
XFixesHideCursor(dpy, DefaultRootWindow(dpy));
|
||||
cursorHidden = True;
|
||||
hideCursorForScale = True;
|
||||
apply_cursor_state(dpy);
|
||||
}
|
||||
|
||||
// Constrain it to the window; careful, the corners will leak due to a known X server bug
|
||||
|
@ -1272,6 +1303,8 @@ add_win (Display *dpy, Window id, Window prev, unsigned long sequence)
|
|||
new->nudged = False;
|
||||
new->ignoreOverrideRedirect = False;
|
||||
|
||||
new->mouseMoved = False;
|
||||
|
||||
new->next = *p;
|
||||
*p = new;
|
||||
if (new->a.map_state == IsViewable)
|
||||
|
@ -1788,6 +1821,10 @@ main (int argc, char **argv)
|
|||
|
||||
XF86VidModeLockModeSwitch(dpy, scr, True);
|
||||
|
||||
// Start it with the cursor hidden until moved by user
|
||||
hideCursorForMovement = True;
|
||||
apply_cursor_state(dpy);
|
||||
|
||||
gamesRunningCount = get_prop(dpy, root, gamesRunningAtom, 0);
|
||||
|
||||
determine_and_apply_focus(dpy);
|
||||
|
@ -1963,6 +2000,18 @@ main (int argc, char **argv)
|
|||
{
|
||||
w->damaged = 1;
|
||||
}
|
||||
|
||||
// Ignore the first event as it's likely to be a warp, not user-initiated
|
||||
if (w && !w->mouseMoved)
|
||||
{
|
||||
w->mouseMoved = True;
|
||||
break;
|
||||
}
|
||||
|
||||
lastCursorMovedTime = get_time_in_milliseconds();
|
||||
|
||||
hideCursorForMovement = False;
|
||||
apply_cursor_state(dpy);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -1982,7 +2031,17 @@ main (int argc, char **argv)
|
|||
{
|
||||
paint_all(dpy);
|
||||
|
||||
XSendEvent(dpy, ourWindow, True, ExposureMask, &exposeEvent);
|
||||
// If we're in the middle of a fade, pump an event into the loop to
|
||||
// make sure we keep pushing frames even if the app isn't updating.
|
||||
if (fadeOutWindow.id)
|
||||
XSendEvent(dpy, ourWindow, True, ExposureMask, &exposeEvent);
|
||||
|
||||
if (!hideCursorForMovement &&
|
||||
(get_time_in_milliseconds() - lastCursorMovedTime) > CURSOR_HIDE_TIME)
|
||||
{
|
||||
hideCursorForMovement = True;
|
||||
apply_cursor_state(dpy);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue