diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js index 5fad513f6..6a88e8c40 100644 --- a/js/ui/appDisplay.js +++ b/js/ui/appDisplay.js @@ -54,7 +54,7 @@ AppDisplayItem.prototype = { let windows = app.get_windows(); if (windows.length > 0) { let mostRecentWindow = windows[0]; - Main.overview.activateWindow(mostRecentWindow, Main.currentTime()); + Main.overview.activateWindow(mostRecentWindow, global.get_current_time()); } else { this._appInfo.launch(); } @@ -346,7 +346,7 @@ BaseWellItem.prototype = { if (this.actor.pressed && this._dragStartX != null) { this.actor.fake_release(); this._draggable.startDrag(this._dragStartX, this._dragStartY, - Main.currentTime()); + global.get_current_time()); } else { this._dragStartX = null; this._dragStartY = null; @@ -599,7 +599,7 @@ AppIconMenu.prototype = { this._redisplay(); - this._windowContainer.popup(activatingButton, Main.currentTime()); + this._windowContainer.popup(activatingButton, global.get_current_time()); this.emit('popup', true); @@ -756,7 +756,7 @@ RunningWellItem.prototype = { activateMostRecentWindow: function () { let mostRecentWindow = this.app.get_windows()[0]; - Main.overview.activateWindow(mostRecentWindow, Main.currentTime()); + Main.overview.activateWindow(mostRecentWindow, global.get_current_time()); }, highlightWindow: function(metaWindow) { @@ -766,7 +766,7 @@ RunningWellItem.prototype = { activateWindow: function(metaWindow) { if (metaWindow) { this._didActivateWindow = true; - Main.overview.activateWindow(metaWindow, Main.currentTime()); + Main.overview.activateWindow(metaWindow, global.get_current_time()); } else Main.overview.hide(); }, diff --git a/js/ui/appIcon.js b/js/ui/appIcon.js index 5202a1da6..27182fede 100644 --- a/js/ui/appIcon.js +++ b/js/ui/appIcon.js @@ -472,7 +472,7 @@ AppIconMenu.prototype = { this._redisplay(); - this._windowContainer.popup(activatingButton, Main.currentTime()); + this._windowContainer.popup(activatingButton, global.get_current_time()); this.emit('popup', true); diff --git a/js/ui/main.js b/js/ui/main.js index 18ce34b35..d481cc78e 100644 --- a/js/ui/main.js +++ b/js/ui/main.js @@ -293,7 +293,7 @@ function _findModal(actor) { */ function pushModal(actor) { if (modalCount == 0) { - if (!global.begin_modal(currentTime())) { + if (!global.begin_modal(global.get_current_time())) { log("pushModal: invocation of begin_modal failed"); return false; } @@ -346,7 +346,7 @@ function popModal(actor) { if (modalCount > 0) return; - global.end_modal(currentTime()); + global.end_modal(global.get_current_time()); global.set_stage_input_mode(Shell.StageInputMode.NORMAL); } @@ -365,45 +365,6 @@ function getRunDialog() { return runDialog; } -function createAppLaunchContext() { - let context = new Gdk.AppLaunchContext(); - 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(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(); -} - /** * activateWindow: * @window: the Meta.Window to activate @@ -416,7 +377,7 @@ function activateWindow(window, time) { let windowWorkspaceNum = window.get_workspace().index(); if (!time) - time = currentTime(); + time = global.get_current_time(); if (windowWorkspaceNum != activeWorkspaceNum) { let workspace = global.screen.get_workspace_by_index(windowWorkspaceNum); diff --git a/js/ui/overview.js b/js/ui/overview.js index e217bfe1a..1b13a5d09 100644 --- a/js/ui/overview.js +++ b/js/ui/overview.js @@ -457,7 +457,7 @@ Overview.prototype = { }, _addNewWorkspace: function() { - global.screen.append_new_workspace(false, Main.currentTime()); + global.screen.append_new_workspace(false, global.get_current_time()); }, _acceptNewWorkspaceDrop: function(source, dropActor, x, y, time) { diff --git a/js/ui/placeDisplay.js b/js/ui/placeDisplay.js index f408fc978..82a36745d 100644 --- a/js/ui/placeDisplay.js +++ b/js/ui/placeDisplay.js @@ -65,7 +65,7 @@ PlacesManager.prototype = { return Shell.TextureCache.get_default().load_gicon(homeIcon, size); }, function() { - Gio.app_info_launch_default_for_uri(homeUri, Main.createAppLaunchContext()); + Gio.app_info_launch_default_for_uri(homeUri, global.create_app_launch_context()); }); let desktopPath = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_DESKTOP); @@ -78,7 +78,7 @@ PlacesManager.prototype = { return Shell.TextureCache.get_default().load_gicon(desktopIcon, size); }, function() { - Gio.app_info_launch_default_for_uri(desktopUri, Main.createAppLaunchContext()); + Gio.app_info_launch_default_for_uri(desktopUri, global.create_app_launch_context()); }); this._connect = new PlaceInfo(_("Connect to..."), @@ -243,7 +243,7 @@ PlacesManager.prototype = { return Shell.TextureCache.get_default().load_gicon(icon, size); }, function() { - Gio.app_info_launch_default_for_uri(bookmark, Main.createAppLaunchContext()); + Gio.app_info_launch_default_for_uri(bookmark, global.create_app_launch_context()); }); this._bookmarks.push(item); } @@ -272,7 +272,7 @@ PlacesManager.prototype = { return Shell.TextureCache.get_default().load_gicon(mountIcon, size); }, function() { - Gio.app_info_launch_default_for_uri(mountUri, Main.createAppLaunchContext()); + Gio.app_info_launch_default_for_uri(mountUri, global.create_app_launch_context()); }); this._mounts.push(devItem); }, diff --git a/src/shell-global.c b/src/shell-global.c index a36753e9a..542f28dc1 100644 --- a/src/shell-global.c +++ b/src/shell-global.c @@ -1064,3 +1064,63 @@ shell_popup_menu (GtkMenu *menu, int button, guint32 time, gtk_menu_popup (menu, NULL, NULL, shell_popup_menu_position_func, NULL, button, time); } + +/** + * shell_global_get_current_time: + * @global: A #ShellGlobal + * + * Returns: 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. + */ +guint32 +shell_global_get_current_time (ShellGlobal *global) +{ + guint32 time; + MetaDisplay *display; + + /* 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(). + */ + + display = meta_screen_get_display (shell_global_get_screen (global)); + time = meta_display_get_current_time (display); + if (time != CLUTTER_CURRENT_TIME) + return time; + + return clutter_get_current_event_time (); +} + +/** + * shell_global_get_app_launch_context: + * @global: A #ShellGlobal + * + * Create a #GAppLaunchContext set up with the correct timestamp, and + * targeted to activate on the current workspace. + * + * Return value: A new #GAppLaunchContext + */ +GAppLaunchContext * +shell_global_create_app_launch_context (ShellGlobal *global) +{ + GdkAppLaunchContext *context; + + context = gdk_app_launch_context_new (); + gdk_app_launch_context_set_timestamp (context, shell_global_get_current_time (global)); + + // Make sure that the app is opened on the current workspace even if + // the user switches before it starts + gdk_app_launch_context_set_desktop (context, meta_screen_get_active_workspace_index (shell_global_get_screen (global))); + + return (GAppLaunchContext *)context; +} diff --git a/src/shell-global.h b/src/shell-global.h index 60b9cb552..ef70b6afd 100644 --- a/src/shell-global.h +++ b/src/shell-global.h @@ -82,6 +82,9 @@ ClutterModifierType shell_get_event_state (ClutterEvent *event); void shell_popup_menu (GtkMenu *menu, int button, guint32 time, int menu_x, int menu_y); +guint32 shell_global_get_current_time (ShellGlobal *global); + +GAppLaunchContext *shell_global_create_app_launch_context (ShellGlobal *global); G_END_DECLS