autoWorkspaces: fix creation of new workspaces with application launchers
In the workspace-collecting code we add a check to avoid collecting a workspace if any startup sequence is running there. Since the sequence can take some time to load, an helper function is also added which keeps the (empty) workspace around for a very short time, while waiting for the sequence to start. https://bugzilla.gnome.org/show_bug.cgi?id=664202
This commit is contained in:
parent
b2bc73c3fe
commit
3c6737f738
@ -171,9 +171,11 @@ function start() {
|
||||
// and recalculate application associations, so to avoid
|
||||
// races for now we initialize it here. It's better to
|
||||
// be predictable anyways.
|
||||
Shell.WindowTracker.get_default();
|
||||
let tracker = Shell.WindowTracker.get_default();
|
||||
Shell.AppUsage.get_default();
|
||||
|
||||
tracker.connect('startup-sequence-changed', _queueCheckWorkspaces);
|
||||
|
||||
// The stage is always covered so Clutter doesn't need to clear it; however
|
||||
// the color is used as the default contents for the Mutter root background
|
||||
// actor so set it anyways.
|
||||
@ -286,15 +288,23 @@ function _checkWorkspaces() {
|
||||
|
||||
for (i = 0; i < _workspaces.length; i++) {
|
||||
let lastRemoved = _workspaces[i]._lastRemovedWindow;
|
||||
if (lastRemoved &&
|
||||
(lastRemoved.get_window_type() == Meta.WindowType.SPLASHSCREEN ||
|
||||
lastRemoved.get_window_type() == Meta.WindowType.DIALOG ||
|
||||
lastRemoved.get_window_type() == Meta.WindowType.MODAL_DIALOG))
|
||||
if ((lastRemoved &&
|
||||
(lastRemoved.get_window_type() == Meta.WindowType.SPLASHSCREEN ||
|
||||
lastRemoved.get_window_type() == Meta.WindowType.DIALOG ||
|
||||
lastRemoved.get_window_type() == Meta.WindowType.MODAL_DIALOG)) ||
|
||||
_workspaces[i]._keepAliveId)
|
||||
emptyWorkspaces[i] = false;
|
||||
else
|
||||
emptyWorkspaces[i] = true;
|
||||
}
|
||||
|
||||
let sequences = Shell.WindowTracker.get_default().get_startup_sequences();
|
||||
for (i = 0; i < sequences.length; i++) {
|
||||
let index = sequences[i].get_workspace();
|
||||
if (index >= 0 && index <= global.screen.n_workspaces)
|
||||
emptyWorkspaces[index] = false;
|
||||
}
|
||||
|
||||
let windows = global.get_window_actors();
|
||||
for (i = 0; i < windows.length; i++) {
|
||||
let win = windows[i];
|
||||
@ -342,6 +352,17 @@ function _checkWorkspaces() {
|
||||
return false;
|
||||
}
|
||||
|
||||
function keepWorkspaceAlive(workspace, duration) {
|
||||
if (workspace._keepAliveId)
|
||||
Mainloop.source_remove(workspace._keepAliveId);
|
||||
|
||||
workspace._keepAliveId = Mainloop.timeout_add(duration, function() {
|
||||
workspace._keepAliveId = 0;
|
||||
_queueCheckWorkspaces();
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
function _windowRemoved(workspace, window) {
|
||||
workspace._lastRemovedWindow = window;
|
||||
_queueCheckWorkspaces();
|
||||
|
@ -25,6 +25,8 @@ const SLIDE_ANIMATION_TIME = 0.2;
|
||||
// placeholder exactly.
|
||||
const WORKSPACE_CUT_SIZE = 10;
|
||||
|
||||
const WORKSPACE_KEEP_ALIVE_TIME = 100;
|
||||
|
||||
const WindowClone = new Lang.Class({
|
||||
Name: 'WindowClone',
|
||||
|
||||
@ -684,9 +686,16 @@ const ThumbnailsBox = new Lang.Class({
|
||||
// ... and bam, a workspace, good as new.
|
||||
source.metaWindow.change_workspace_by_index(newWorkspaceIndex,
|
||||
true, time);
|
||||
else if (source.shellWorkspaceLaunch)
|
||||
else if (source.shellWorkspaceLaunch) {
|
||||
source.shellWorkspaceLaunch({ workspace: newWorkspaceIndex,
|
||||
timestamp: time });
|
||||
// This new workspace will be automatically removed if the application fails
|
||||
// to open its first window within some time, as tracked by Shell.WindowTracker.
|
||||
// Here, we only add a very brief timeout to avoid the _immediate_ removal of the
|
||||
// workspace while we wait for the startup sequence to load.
|
||||
Main.keepWorkspaceAlive(global.screen.get_workspace_by_index(newWorkspaceIndex),
|
||||
WORKSPACE_KEEP_ALIVE_TIME);
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
@ -816,6 +816,12 @@ shell_startup_sequence_get_completed (ShellStartupSequence *sequence)
|
||||
return sn_startup_sequence_get_completed ((SnStartupSequence*)sequence);
|
||||
}
|
||||
|
||||
int
|
||||
shell_startup_sequence_get_workspace (ShellStartupSequence *sequence)
|
||||
{
|
||||
return sn_startup_sequence_get_workspace ((SnStartupSequence*)sequence);
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_startup_sequence_create_icon:
|
||||
* @sequence:
|
||||
|
@ -50,6 +50,7 @@ const char *shell_startup_sequence_get_id (ShellStartupSequence *sequence);
|
||||
ShellApp *shell_startup_sequence_get_app (ShellStartupSequence *sequence);
|
||||
const char *shell_startup_sequence_get_name (ShellStartupSequence *sequence);
|
||||
gboolean shell_startup_sequence_get_completed (ShellStartupSequence *sequence);
|
||||
int shell_startup_sequence_get_workspace (ShellStartupSequence *sequence);
|
||||
ClutterActor *shell_startup_sequence_create_icon (ShellStartupSequence *sequence, guint size);
|
||||
|
||||
G_END_DECLS
|
||||
|
Loading…
Reference in New Issue
Block a user