void myDisplayUpdateLastUserTime (DisplayInfo *display, guint32 timestamp) { g_return_if_fail (display != NULL); g_return_if_fail (timestamp != 0); if (TIMESTAMP_IS_BEFORE(display->last_user_time, timestamp)) { display->last_user_time = timestamp; } }
guint32 myDisplayUpdateCurrentTime (DisplayInfo *display, XEvent *ev) { guint32 timestamp; g_return_val_if_fail (display != NULL, (guint32) CurrentTime); timestamp = (guint32) CurrentTime; switch (ev->type) { case KeyPress: case KeyRelease: timestamp = (guint32) ev->xkey.time; break; case ButtonPress: case ButtonRelease: timestamp = (guint32) ev->xbutton.time; break; case MotionNotify: timestamp = (guint32) ev->xmotion.time; break; case EnterNotify: case LeaveNotify: timestamp = (guint32) ev->xcrossing.time; break; case PropertyNotify: timestamp = (guint32) ev->xproperty.time; break; case SelectionClear: timestamp = (guint32) ev->xselectionclear.time; break; case SelectionRequest: timestamp = (guint32) ev->xselectionrequest.time; break; case SelectionNotify: timestamp = (guint32) ev->xselection.time; break; default: #ifdef HAVE_XSYNC if ((display->have_xsync) && (ev->type == display->xsync_event_base + XSyncAlarmNotify)) { timestamp = ((XSyncAlarmNotifyEvent*) ev)->time; } #endif /* HAVE_XSYNC */ break; } if ((timestamp != (guint32) CurrentTime) && TIMESTAMP_IS_BEFORE(display->current_time, timestamp)) { display->current_time = timestamp; } return display->current_time; }
void myDisplaySetLastUserTime (DisplayInfo *display, guint32 timestamp) { g_return_if_fail (display != NULL); g_return_if_fail (timestamp != 0); if (TIMESTAMP_IS_BEFORE(timestamp, display->last_user_time)) { g_warning ("Last user time set back to %u (was %u)", (unsigned int) timestamp, (unsigned int) display->last_user_time); } display->last_user_time = timestamp; }
gboolean clientFocusNew(Client * c) { ScreenInfo *screen_info; DisplayInfo *display_info; gboolean give_focus; gboolean prevent_focus_stealing; gboolean prevented; g_return_val_if_fail (c != NULL, FALSE); screen_info = c->screen_info; display_info = screen_info->display_info; give_focus = (c-> type & WINDOW_REGULAR_FOCUSABLE) && (screen_info->params->focus_new); prevent_focus_stealing = screen_info->params->prevent_focus_stealing; prevented = FALSE; /* Try to avoid focus stealing */ if (!clientAcceptFocus (c) || (c->type & WINDOW_TYPE_DONT_FOCUS)) { give_focus = FALSE; } else if (FLAG_TEST (c->flags, CLIENT_FLAG_HAS_USER_TIME) && (c->user_time == (guint32) 0)) { /* * _NET_WM_USER_TIME definition from http://standards.freedesktop.org/wm-spec * [...] "The special value of zero on a newly mapped window can be used to * request that the window not be initially focused when it is mapped." */ TRACE ("given startup time is nil, not focusing \"%s\"", c->name); give_focus = FALSE; prevented = FALSE; } else if ((client_focus) && (prevent_focus_stealing)) { if (client_focus->win_layer > c->win_layer) { TRACE ("not focusing \"%s\" because the current focused window is on a upper layer", c->name); give_focus = FALSE; prevented = TRUE; } else if (client_focus->win_layer < c->win_layer) { /* We don't use focus stealing prevention against upper layers */ TRACE ("ignoring startup prevention because the current focused window is on a lower layer"); give_focus = TRUE; prevented = FALSE; } else if (FLAG_TEST (client_focus->xfwm_flags, XFWM_FLAG_MOVING_RESIZING)) { give_focus = FALSE; prevented = TRUE; } else if (FLAG_TEST (c->flags, CLIENT_FLAG_HAS_STARTUP_TIME | CLIENT_FLAG_HAS_USER_TIME)) { TRACE ("current time is %u, time for \"%s\" is %u", (unsigned int) client_focus->user_time, c->name, (unsigned int) c->user_time); if (TIMESTAMP_IS_BEFORE (c->user_time, client_focus->user_time)) { give_focus = FALSE; prevented = TRUE; } } } if (FLAG_TEST(c->flags, CLIENT_FLAG_STATE_MODAL)) { give_focus = TRUE; } if (give_focus) { if (client_focus) { clientAdjustFullscreenLayer (client_focus, FALSE); } clientRaise (c, None); clientShow (c, TRUE); clientSetFocus (screen_info, c, myDisplayGetCurrentTime (display_info), FOCUS_IGNORE_MODAL); } else { Client *c2 = clientGetFocus(); clientSortRing(c); if ((c2 != NULL) && (c2->win_layer == c->win_layer) && prevented) { /* * Place windows under the currently focused only if focus * stealing prevention had prevented the focus transition, * otherwise, leave the unfocused window on top. */ clientLower (c, c2->frame); } else { clientRaise (c, None); } clientSortRing(c2); if (prevented) { TRACE ("setting WM_STATE_DEMANDS_ATTENTION flag on \"%s\" (0x%lx)", c->name, c->window); FLAG_SET (c->flags, CLIENT_FLAG_DEMANDS_ATTENTION); } clientShow (c, TRUE); clientSetNetState (c); } return (give_focus); }