diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js index ea02da16c..9fff7cb38 100644 --- a/js/ui/appDisplay.js +++ b/js/ui/appDisplay.js @@ -60,7 +60,7 @@ AppDisplayItem.prototype = { let windows = Shell.AppMonitor.get_default().get_windows_for_app(this._appInfo.get_id()); if (windows.length > 0) { let mostRecentWindow = windows[0]; - Main.overview.activateWindow(mostRecentWindow, Clutter.get_current_event_time()); + Main.overview.activateWindow(mostRecentWindow, Main.currentTime()); } else { this._appInfo.launch(); } @@ -486,7 +486,7 @@ BaseWellItem.prototype = { if (this.actor.pressed && this._dragStartX != null) { this.actor.fake_release(); this._draggable.startDrag(this._dragStartX, this._dragStartY, - Clutter.get_current_event_time()); + Main.currentTime()); } else { this._dragStartX = null; this._dragStartY = null; @@ -547,7 +547,7 @@ RunningWellItem.prototype = { activateMostRecentWindow: function () { // The _get_windows_for_app sorts them for us let mostRecentWindow = this.windows[0]; - Main.overview.activateWindow(mostRecentWindow, Clutter.get_current_event_time()); + Main.overview.activateWindow(mostRecentWindow, Main.currentTime()); }, highlightWindow: function(metaWindow) { @@ -557,7 +557,7 @@ RunningWellItem.prototype = { activateWindow: function(metaWindow) { if (metaWindow) { this._didActivateWindow = true; - Main.overview.activateWindow(metaWindow, Clutter.get_current_event_time()); + Main.overview.activateWindow(metaWindow, Main.currentTime()); } else Main.overview.hide(); }, diff --git a/js/ui/appIcon.js b/js/ui/appIcon.js index 59dcf4a5b..6a74e7de9 100644 --- a/js/ui/appIcon.js +++ b/js/ui/appIcon.js @@ -447,7 +447,7 @@ AppIconMenu.prototype = { this._redisplay(); - this._windowContainer.popup(0, Clutter.get_current_event_time()); + this._windowContainer.popup(0, Main.currentTime()); this.emit('popup', true); diff --git a/js/ui/main.js b/js/ui/main.js index e0a095360..310a3edd5 100644 --- a/js/ui/main.js +++ b/js/ui/main.js @@ -218,10 +218,8 @@ function _findModal(actor) { * Returns: true iff we successfully acquired a grab or already had one */ function pushModal(actor) { - let timestamp = global.screen.get_display().get_current_time(); - if (modalCount == 0) { - if (!global.begin_modal(timestamp)) { + if (!global.begin_modal(currentTime())) { log("pushModal: invocation of begin_modal failed"); return false; } @@ -257,8 +255,6 @@ function pushModal(actor) { * previous focus at the time when pushModal() was invoked. */ function popModal(actor) { - let timestamp = global.screen.get_display().get_current_time(); - modalCount -= 1; let focusIndex = _findModal(actor); if (focusIndex >= 0) { @@ -276,7 +272,7 @@ function popModal(actor) { if (modalCount > 0) return; - global.end_modal(timestamp); + global.end_modal(currentTime()); global.set_stage_input_mode(Shell.StageInputMode.NORMAL); } @@ -296,15 +292,40 @@ function getRunDialog() { } function createAppLaunchContext() { - let screen = global.screen; - let display = screen.get_display(); - let context = new Gdk.AppLaunchContext(); - context.set_timestamp(display.get_current_time()); + context.set_timestamp(currentTime()); // Make sure that the app is opened on the current workspace even if // the user switches before it starts - context.set_desktop(screen.get_active_workspace_index()); + context.set_desktop(global.screen.get_active_workspace_index()); return context; } + +/** + * currentTime: + * + * Gets the current X server time from the current Clutter, Gdk, or X + * event. If called from outside an event handler, this may return + * %Clutter.CURRENT_TIME (aka 0), or it may return a slightly + * out-of-date timestamp. + */ +function currentTime() { + // meta_display_get_current_time() will return the correct time + // when handling an X or Gdk event, but will return CurrentTime + // from some Clutter event callbacks. + // + // clutter_get_current_event_time() will return the correct time + // from a Clutter event callback, but may return an out-of-date + // timestamp if called at other times. + // + // So we try meta_display_get_current_time() first, since we + // can recognize a "wrong" answer from that, and then fall back + // to clutter_get_current_event_time(). + + let time = global.screen.get_display().get_current_time(); + if (time != Clutter.CURRENT_TIME) + return time; + + return Clutter.get_current_event_time(); +} diff --git a/js/ui/overview.js b/js/ui/overview.js index cccf2e4c6..060041413 100644 --- a/js/ui/overview.js +++ b/js/ui/overview.js @@ -442,7 +442,7 @@ Overview.prototype = { }, _addNewWorkspace: function() { - global.screen.append_new_workspace(false, global.screen.get_display().get_current_time()); + global.screen.append_new_workspace(false, Main.currentTime()); }, _acceptNewWorkspaceDrop: function(source, dropActor, x, y, time) {