[mutter] workspace: Don't keep state given logical monitor indices



commit 68f3b5849a9fb438fbc92ab426b3555dc5deecf2
Author: Jonas Ådahl <jadahl gmail com>
Date:   Fri Dec 2 17:39:01 2016 +0800

    workspace: Don't keep state given logical monitor indices
    
    Don't store logical monitor specific state in an array where the index
    from the monitor manager is used as index locally. Instead just use
    table associating a logical monitor with a monitor specific state
    holder, and store the state in there. This way we don't have the
    workspace implementation relying on implementation details of other
    units.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=777732

 src/core/constraints.c       |    6 +-
 src/core/workspace-private.h |   10 +--
 src/core/workspace.c         |  145 ++++++++++++++++++++++++++----------------
 3 files changed, 96 insertions(+), 65 deletions(-)
---
diff --git a/src/core/constraints.c b/src/core/constraints.c
index 7ccce51..2aa2764 100644
--- a/src/core/constraints.c
+++ b/src/core/constraints.c
@@ -410,8 +410,7 @@ setup_constraint_info (ConstraintInfo      *info,
   info->usable_screen_region   =
     meta_workspace_get_onscreen_region (cur_workspace);
   info->usable_monitor_region =
-    meta_workspace_get_onmonitor_region (cur_workspace,
-                                         logical_monitor->number);
+    meta_workspace_get_onmonitor_region (cur_workspace, logical_monitor);
 
   /* Log all this information for debugging */
   meta_topic (META_DEBUG_GEOMETRY,
@@ -496,8 +495,7 @@ place_window_if_needed(MetaWindow     *window,
                                                      &info->work_area_monitor);
       cur_workspace = window->screen->active_workspace;
       info->usable_monitor_region =
-        meta_workspace_get_onmonitor_region (cur_workspace,
-                                             logical_monitor->number);
+        meta_workspace_get_onmonitor_region (cur_workspace, logical_monitor);
 
       info->current.x = placed_rect.x;
       info->current.y = placed_rect.y;
diff --git a/src/core/workspace-private.h b/src/core/workspace-private.h
index 3b5e940..54d9db0 100644
--- a/src/core/workspace-private.h
+++ b/src/core/workspace-private.h
@@ -54,12 +54,10 @@ struct _MetaWorkspace
 
   GList  *list_containing_self;
 
+  GHashTable *logical_monitor_data;
+
   MetaRectangle work_area_screen;
-  MetaRectangle *work_area_monitor;
-  gint n_work_area_monitor;
   GList  *screen_region;
-  GList  **monitor_region;
-  gint n_monitor_regions;
   GList  *screen_edges;
   GList  *monitor_edges;
   GSList *builtin_struts;
@@ -90,8 +88,8 @@ void meta_workspace_get_work_area_for_logical_monitor (MetaWorkspace      *works
 void meta_workspace_invalidate_work_area (MetaWorkspace *workspace);
 
 GList* meta_workspace_get_onscreen_region       (MetaWorkspace *workspace);
-GList* meta_workspace_get_onmonitor_region      (MetaWorkspace *workspace,
-                                                 int            which_monitor);
+GList * meta_workspace_get_onmonitor_region (MetaWorkspace      *workspace,
+                                             MetaLogicalMonitor *logical_monitor);
 
 void meta_workspace_focus_default_window (MetaWorkspace *workspace,
                                           MetaWindow    *not_this_one,
diff --git a/src/core/workspace.c b/src/core/workspace.c
index dd1538c..7f56b62 100644
--- a/src/core/workspace.c
+++ b/src/core/workspace.c
@@ -78,6 +78,59 @@ enum
 
 static guint signals[LAST_SIGNAL] = { 0 };
 
+typedef struct _MetaWorkspaceLogicalMonitorData
+{
+  GList *logical_monitor_region;
+  MetaRectangle logical_monitor_work_area;
+} MetaWorkspaceLogicalMonitorData;
+
+static MetaWorkspaceLogicalMonitorData *
+meta_workspace_get_logical_monitor_data (MetaWorkspace      *workspace,
+                                         MetaLogicalMonitor *logical_monitor)
+{
+  if (!workspace->logical_monitor_data)
+    return NULL;
+  return g_hash_table_lookup (workspace->logical_monitor_data, logical_monitor);
+}
+
+static void
+workspace_logical_monitor_data_free (MetaWorkspaceLogicalMonitorData *data)
+{
+  g_clear_pointer (&data->logical_monitor_region,
+                   meta_rectangle_free_list_and_elements);
+}
+
+static MetaWorkspaceLogicalMonitorData *
+meta_workspace_ensure_logical_monitor_data (MetaWorkspace      *workspace,
+                                            MetaLogicalMonitor *logical_monitor)
+{
+  MetaWorkspaceLogicalMonitorData *data;
+
+  data = meta_workspace_get_logical_monitor_data (workspace, logical_monitor);
+  if (data)
+    return data;
+
+  if (!workspace->logical_monitor_data)
+    {
+      workspace->logical_monitor_data =
+        g_hash_table_new_full (g_direct_hash,
+                               g_direct_equal,
+                               NULL,
+                               (GDestroyNotify) workspace_logical_monitor_data_free);
+    }
+
+  data = g_new0 (MetaWorkspaceLogicalMonitorData, 1);
+  g_hash_table_insert (workspace->logical_monitor_data, logical_monitor, data);
+
+  return data;
+}
+
+static void
+meta_workspace_clear_logical_monitor_data (MetaWorkspace *workspace)
+{
+  g_clear_pointer (&workspace->logical_monitor_data, g_hash_table_destroy);
+}
+
 static void
 meta_workspace_finalize (GObject *object)
 {
@@ -182,14 +235,12 @@ meta_workspace_new (MetaScreen *screen)
   workspace->mru_list = NULL;
 
   workspace->work_areas_invalid = TRUE;
-  workspace->work_area_monitor = NULL;
   workspace->work_area_screen.x = 0;
   workspace->work_area_screen.y = 0;
   workspace->work_area_screen.width = 0;
   workspace->work_area_screen.height = 0;
 
   workspace->screen_region = NULL;
-  workspace->monitor_region = NULL;
   workspace->screen_edges = NULL;
   workspace->monitor_edges = NULL;
   workspace->list_containing_self = g_list_prepend (NULL, workspace);
@@ -273,7 +324,7 @@ meta_workspace_remove (MetaWorkspace *workspace)
   workspace->screen->workspaces =
     g_list_remove (workspace->screen->workspaces, workspace);
 
-  g_free (workspace->work_area_monitor);
+  meta_workspace_clear_logical_monitor_data (workspace);
 
   g_list_free (workspace->mru_list);
   g_list_free (workspace->list_containing_self);
@@ -289,12 +340,7 @@ meta_workspace_remove (MetaWorkspace *workspace)
 
   if (!workspace->work_areas_invalid)
     {
-      int i;
-
       workspace_free_all_struts (workspace);
-      for (i = 0; i < workspace->n_monitor_regions; i++)
-        meta_rectangle_free_list_and_elements (workspace->monitor_region[i]);
-      g_free (workspace->monitor_region);
       meta_rectangle_free_list_and_elements (workspace->screen_region);
       meta_rectangle_free_list_and_elements (workspace->screen_edges);
       meta_rectangle_free_list_and_elements (workspace->monitor_edges);
@@ -677,7 +723,6 @@ meta_workspace_list_windows (MetaWorkspace *workspace)
 void
 meta_workspace_invalidate_work_area (MetaWorkspace *workspace)
 {
-  int i;
   GList *windows, *l;
 
   if (workspace->work_areas_invalid)
@@ -697,18 +742,13 @@ meta_workspace_invalidate_work_area (MetaWorkspace *workspace)
   if (workspace == workspace->screen->active_workspace)
     meta_display_cleanup_edges (workspace->screen->display);
 
-  g_free (workspace->work_area_monitor);
-  workspace->work_area_monitor = NULL;
+  meta_workspace_clear_logical_monitor_data (workspace);
 
   workspace_free_all_struts (workspace);
 
-  for (i = 0; i < workspace->n_monitor_regions; i++)
-    meta_rectangle_free_list_and_elements (workspace->monitor_region[i]);
-  g_free (workspace->monitor_region);
   meta_rectangle_free_list_and_elements (workspace->screen_region);
   meta_rectangle_free_list_and_elements (workspace->screen_edges);
   meta_rectangle_free_list_and_elements (workspace->monitor_edges);
-  workspace->monitor_region = NULL;
   workspace->screen_region = NULL;
   workspace->screen_edges = NULL;
   workspace->monitor_edges = NULL;
@@ -755,14 +795,12 @@ ensure_work_areas_validated (MetaWorkspace *workspace)
   GList *windows;
   GList *tmp;
   GList *logical_monitors, *l;
-  int i;
   MetaRectangle work_area;
 
   if (!workspace->work_areas_invalid)
     return;
 
   g_assert (workspace->all_struts == NULL);
-  g_assert (workspace->monitor_region == NULL);
   g_assert (workspace->screen_region == NULL);
   g_assert (workspace->screen_edges == NULL);
   g_assert (workspace->monitor_edges == NULL);
@@ -787,26 +825,24 @@ ensure_work_areas_validated (MetaWorkspace *workspace)
   /* STEP 2: Get the maximal/spanning rects for the onscreen and
    *         on-single-monitor regions
    */
-  g_assert (workspace->monitor_region == NULL);
   g_assert (workspace->screen_region   == NULL);
 
   logical_monitors =
     meta_monitor_manager_get_logical_monitors (monitor_manager);
-
-  workspace->n_monitor_regions =
-    (int) meta_monitor_manager_get_num_logical_monitors (monitor_manager);
-  workspace->monitor_region = g_new (GList*, workspace->n_monitor_regions);
-  i = 0;
   for (l = logical_monitors; l; l = l->next)
     {
       MetaLogicalMonitor *logical_monitor = l->data;
+      MetaWorkspaceLogicalMonitorData *data;
+
+      g_assert (!meta_workspace_get_logical_monitor_data (workspace,
+                                                          logical_monitor));
 
-      workspace->monitor_region[i] =
+      data = meta_workspace_ensure_logical_monitor_data (workspace,
+                                                         logical_monitor);
+      data->logical_monitor_region =
         meta_rectangle_get_minimal_spanning_set_for_region (
           &logical_monitor->rect,
           workspace->all_struts);
-
-      i++;
     }
 
   workspace->screen_region =
@@ -871,41 +907,36 @@ ensure_work_areas_validated (MetaWorkspace *workspace)
               workspace->work_area_screen.height);
 
   /* Now find the work areas for each monitor */
-  g_free (workspace->work_area_monitor);
-  workspace->n_work_area_monitor =
-    meta_monitor_manager_get_num_logical_monitors (monitor_manager);
-  workspace->work_area_monitor = g_new (MetaRectangle,
-                                        workspace->n_work_area_monitor);
-
-  i = 0;
   for (l = logical_monitors; l; l = l->next)
     {
       MetaLogicalMonitor *logical_monitor = l->data;
+      MetaWorkspaceLogicalMonitorData *data;
 
+      data = meta_workspace_get_logical_monitor_data (workspace,
+                                                      logical_monitor);
       work_area = logical_monitor->rect;
 
-      if (workspace->monitor_region[i] == NULL)
+      if (!data->logical_monitor_region)
         /* FIXME: constraints.c untested with this, but it might be nice for
          * a screen reader or magnifier.
          */
         work_area = meta_rect (work_area.x, work_area.y, -1, -1);
       else
-        meta_rectangle_clip_to_region (workspace->monitor_region[i],
+        meta_rectangle_clip_to_region (data->logical_monitor_region,
                                        FIXED_DIRECTION_NONE,
                                        &work_area);
 
-      workspace->work_area_monitor[i] = work_area;
+      data->logical_monitor_work_area = work_area;
+
       meta_topic (META_DEBUG_WORKAREA,
                   "Computed work area for workspace %d "
                   "monitor %d: %d,%d %d x %d\n",
                   meta_workspace_index (workspace),
-                  i,
-                  workspace->work_area_monitor[i].x,
-                  workspace->work_area_monitor[i].y,
-                  workspace->work_area_monitor[i].width,
-                  workspace->work_area_monitor[i].height);
-
-      i++;
+                  logical_monitor->number,
+                  data->logical_monitor_work_area.x,
+                  data->logical_monitor_work_area.y,
+                  data->logical_monitor_work_area.width,
+                  data->logical_monitor_work_area.height);
     }
 
   /* STEP 4: Make sure the screen_region is nonempty (separate from step 2
@@ -1061,20 +1092,20 @@ meta_workspace_get_work_area_for_monitor (MetaWorkspace *workspace,
                                           int            which_monitor,
                                           MetaRectangle *area)
 {
-#ifndef G_DISABLE_ASSERT
   MetaBackend *backend = meta_get_backend();
   MetaMonitorManager *monitor_manager =
     meta_backend_get_monitor_manager (backend);
-  int n_logical_monitors =
-    meta_monitor_manager_get_num_logical_monitors (monitor_manager);
-#endif
-
-  g_assert (which_monitor >= 0);
+  MetaLogicalMonitor *logical_monitor;
+  MetaWorkspaceLogicalMonitorData *data;
 
   ensure_work_areas_validated (workspace);
-  g_assert (which_monitor < n_logical_monitors);
 
-  *area = workspace->work_area_monitor[which_monitor];
+  logical_monitor =
+    meta_monitor_manager_get_logical_monitor_from_number (monitor_manager,
+                                                          which_monitor);
+  data = meta_workspace_get_logical_monitor_data (workspace, logical_monitor);
+
+  *area = data->logical_monitor_work_area;
 }
 
 /**
@@ -1101,13 +1132,17 @@ meta_workspace_get_onscreen_region (MetaWorkspace *workspace)
   return workspace->screen_region;
 }
 
-GList*
-meta_workspace_get_onmonitor_region (MetaWorkspace *workspace,
-                                     int            which_monitor)
+GList *
+meta_workspace_get_onmonitor_region (MetaWorkspace      *workspace,
+                                     MetaLogicalMonitor *logical_monitor)
 {
+  MetaWorkspaceLogicalMonitorData *data;
+
   ensure_work_areas_validated (workspace);
 
-  return workspace->monitor_region[which_monitor];
+  data = meta_workspace_get_logical_monitor_data (workspace, logical_monitor);
+
+  return data->logical_monitor_region;
 }
 
 #ifdef WITH_VERBOSE_MODE


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]