diff --git a/data/gala.gschema.xml b/data/gala.gschema.xml
index b727649b0..4ed322a74 100644
--- a/data/gala.gschema.xml
+++ b/data/gala.gschema.xml
@@ -107,6 +107,11 @@
What action should be performed on Super + Scroll
+
+ 0
+ How many workspaces should be permanent
+
+
diff --git a/src/DesktopIntegration.vala b/src/DesktopIntegration.vala
index 83a03642e..3f9bbc22e 100644
--- a/src/DesktopIntegration.vala
+++ b/src/DesktopIntegration.vala
@@ -183,4 +183,24 @@ public class Gala.DesktopIntegration : GLib.Object {
wm.window_overview.open (hints);
}
+
+ public void set_workspace_permanent (int index, bool permanent) throws DBusError, IOError {
+ unowned var manager = wm.get_display ().get_workspace_manager ();
+
+ if (index < 0 || index >= manager.n_workspaces) {
+ throw new IOError.FAILED ("Invalid workspace index");
+ }
+
+ WorkspaceManager.get_default ().set_permanent (manager.get_workspace_by_index (index), permanent);
+ }
+
+ public bool is_workspace_permanent (int index) throws DBusError, IOError {
+ unowned var manager = wm.get_display ().get_workspace_manager ();
+
+ if (index < 0 || index >= manager.n_workspaces) {
+ throw new IOError.FAILED ("Invalid workspace index");
+ }
+
+ return WorkspaceManager.get_default ().is_permanent (manager.get_workspace_by_index (index));
+ }
}
diff --git a/src/InternalUtils.vala b/src/InternalUtils.vala
index 1f5ccd599..4692accea 100644
--- a/src/InternalUtils.vala
+++ b/src/InternalUtils.vala
@@ -74,26 +74,14 @@ namespace Gala {
* @param new_window A window that should be moved to the new workspace
*/
public static void insert_workspace_with_window (int index, Meta.Window new_window) {
+ unowned var manager = new_window.get_display ().get_workspace_manager ();
unowned WorkspaceManager workspace_manager = WorkspaceManager.get_default ();
workspace_manager.freeze_remove ();
- new_window.change_workspace_by_index (index, false);
-
- unowned List actors = new_window.get_display ().get_window_actors ();
- foreach (unowned Meta.WindowActor actor in actors) {
- if (actor.is_destroyed ())
- continue;
-
- unowned Meta.Window window = actor.get_meta_window ();
- if (window == new_window)
- continue;
+ var new_workspace = manager.append_new_workspace (false, Meta.CURRENT_TIME);
+ manager.reorder_workspace (new_workspace, index);
- var current_index = window.get_workspace ().index ();
- if (current_index >= index
- && !window.on_all_workspaces) {
- window.change_workspace_by_index (current_index + 1, true);
- }
- }
+ new_window.change_workspace_by_index (index, false);
workspace_manager.thaw_remove ();
}
diff --git a/src/WorkspaceManager.vala b/src/WorkspaceManager.vala
index 013435e90..17ab2cf99 100644
--- a/src/WorkspaceManager.vala
+++ b/src/WorkspaceManager.vala
@@ -28,6 +28,8 @@ public class Gala.WorkspaceManager : Object {
public WindowManager wm { get; construct; }
+ private Settings behavior_settings;
+
private Gee.LinkedList workspaces_marked_removed;
private int remove_freeze_count = 0;
@@ -37,9 +39,23 @@ public class Gala.WorkspaceManager : Object {
construct {
workspaces_marked_removed = new Gee.LinkedList ();
+ behavior_settings = new GLib.Settings ("io.elementary.desktop.wm.behavior");
+
unowned Meta.Display display = wm.get_display ();
unowned Meta.WorkspaceManager manager = display.get_workspace_manager ();
+ for (int i = 0; i < behavior_settings.get_int ("permanent-workspaces"); i++) {
+ Meta.Workspace workspace;
+ if (i < manager.get_n_workspaces ()) {
+ workspace = manager.get_workspace_by_index (i);
+ } else {
+ workspace = manager.append_new_workspace (false, display.get_current_time ());
+ }
+ workspace.set_data ("permanent", true);
+ }
+
+ append_workspace ();
+
// There are some empty workspace at startup
cleanup ();
@@ -58,13 +74,6 @@ public class Gala.WorkspaceManager : Object {
manager.workspace_removed.connect_after (workspace_removed);
display.window_entered_monitor.connect (window_entered_monitor);
display.window_left_monitor.connect (window_left_monitor);
-
- // make sure the last workspace has no windows on it
- if (Meta.Prefs.get_dynamic_workspaces ()
- && Utils.get_n_windows (manager.get_workspace_by_index (manager.get_n_workspaces () - 1)) > 0
- ) {
- append_workspace ();
- }
}
~WorkspaceManager () {
@@ -114,6 +123,7 @@ public class Gala.WorkspaceManager : Object {
var prev_workspace = manager.get_workspace_by_index (from);
if (Utils.get_n_windows (prev_workspace) < 1
&& from != manager.get_n_workspaces () - 1
+ && !is_permanent (prev_workspace)
) {
// If we're about to remove a workspace, cancel any DnD going on in the multitasking view
@@ -177,15 +187,14 @@ public class Gala.WorkspaceManager : Object {
&& remove_freeze_count < 1
&& Utils.get_n_windows (workspace, true, window) == 0
&& workspace != last_workspace
+ && !is_permanent (workspace)
) {
queue_remove_workspace (workspace);
- }
-
- // if window is the second last and empty, make it the last workspace
- if (is_active_workspace
+ } else if (is_active_workspace // if window is the second last and empty, make it the last workspace
&& remove_freeze_count < 1
&& Utils.get_n_windows (workspace, true, window) == 0
&& workspace.index () == last_workspace_index - 1
+ && !is_permanent (workspace)
) {
queue_remove_workspace (last_workspace);
}
@@ -301,9 +310,29 @@ public class Gala.WorkspaceManager : Object {
foreach (var workspace in manager.get_workspaces ()) {
var last_index = manager.get_n_workspaces () - 1;
- if (Utils.get_n_windows (workspace) == 0 && workspace.index () != last_index) {
+ if (Utils.get_n_windows (workspace) == 0 && workspace.index () != last_index && !is_permanent (workspace)) {
queue_remove_workspace (workspace);
}
}
}
+
+ public void set_permanent (Meta.Workspace workspace, bool permanent) {
+ workspace.set_data ("permanent", permanent);
+
+ unowned var manager = wm.get_display ().get_workspace_manager ();
+ int n_permanent = 0;
+ foreach (var ws in manager.get_workspaces ()) {
+ if (ws.get_data ("permanent")) {
+ n_permanent++;
+ }
+ }
+
+ behavior_settings.set_int ("permanent-workspaces", n_permanent);
+
+ cleanup ();
+ }
+
+ public bool is_permanent (Meta.Workspace workspace) {
+ return workspace.get_data ("permanent");
+ }
}