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"); + } }