summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHavoc Pennington <hp@pobox.com>2003-01-05 18:36:01 +0000
committerHavoc Pennington <hp@src.gnome.org>2003-01-05 18:36:01 +0000
commit90748385c219e123b1a3e058a70f877db07b3e01 (patch)
tree91334dfb14239f137f20816923a9b49befb19e8b
parent1d22cb851850ea53f67ed7414c2595c45ad46dd9 (diff)
downloadmetacity-90748385c219e123b1a3e058a70f877db07b3e01.tar.gz
metacity-90748385c219e123b1a3e058a70f877db07b3e01.tar.bz2
redo using new calc_workspace_layout to fix #98302
2003-01-05 Havoc Pennington <hp@pobox.com> * src/workspace.c (meta_workspace_get_neighbor): redo using new calc_workspace_layout to fix #98302 * src/util.c (topic_name): shorten default prefix * src/screen.c (meta_screen_calc_workspace_layout): enhance this to handle all the funky layouts and calculate more information than before
-rw-r--r--ChangeLog11
-rw-r--r--src/screen.c388
-rw-r--r--src/screen.h21
-rw-r--r--src/tabpopup.c11
-rw-r--r--src/tabpopup.h1
-rw-r--r--src/util.c2
-rw-r--r--src/workspace.c175
7 files changed, 383 insertions, 226 deletions
diff --git a/ChangeLog b/ChangeLog
index f33e87c..21df0d1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2003-01-05 Havoc Pennington <hp@pobox.com>
+
+ * src/workspace.c (meta_workspace_get_neighbor): redo using new
+ calc_workspace_layout to fix #98302
+
+ * src/util.c (topic_name): shorten default prefix
+
+ * src/screen.c (meta_screen_calc_workspace_layout): enhance this
+ to handle all the funky layouts and calculate more information
+ than before
+
2003-01-05 Pauli Virtanen <pauli.virtanen@hut.fi>
* configure.in (ALL_LINGUAS): Added "fi" (Finnish).
diff --git a/src/screen.c b/src/screen.c
index ef06270..1912d89 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -1068,7 +1068,8 @@ meta_screen_ensure_tab_popup (MetaScreen *screen,
entries[i].key = (MetaTabEntryKey) window->xwindow;
entries[i].title = window->title;
entries[i].icon = window->icon;
-
+ entries[i].blank = FALSE;
+
if (!window->minimized || !meta_window_get_icon_geometry (window, &r))
meta_window_get_outer_rect (window, &r);
@@ -1124,79 +1125,66 @@ void
meta_screen_ensure_workspace_popup (MetaScreen *screen)
{
MetaTabEntry *entries;
- int len, rows, cols;
+ int len;
int i;
-
+ MetaWorkspaceLayout layout;
+ int n_workspaces;
+ int current_workspace;
+
if (screen->tab_popup)
return;
- len = meta_screen_get_n_workspaces (screen);
+ current_workspace = meta_workspace_index (screen->active_workspace);
+ n_workspaces = meta_screen_get_n_workspaces (screen);
+ meta_screen_calc_workspace_layout (screen, n_workspaces,
+ current_workspace, &layout);
+
+ len = layout.grid_area;
+
entries = g_new (MetaTabEntry, len + 1);
entries[len].key = NULL;
entries[len].title = NULL;
entries[len].icon = NULL;
-
- meta_screen_calc_workspace_layout (screen, len, &rows, &cols);
-
- /* FIXME: handle screen->starting_corner
- */
- if (screen->vertical_workspaces)
- {
- int j, k, iter;
-
- for (i = 0, iter = 0; i < rows; ++i)
- {
- for (j = 0; j < cols; ++j)
- {
- MetaWorkspace *workspace;
-
- k = i + (j * rows);
- if (k >= len)
- break;
-
- workspace = meta_screen_get_workspace_by_index (screen, k);
- g_assert (workspace);
-
- entries[iter].key = (MetaTabEntryKey) workspace;
- entries[iter].title = meta_workspace_get_name (workspace);
- entries[iter].icon = NULL;
-
- g_assert (entries[iter].title != NULL);
-
- iter++;
- }
- }
- g_assert (iter == len);
- }
- else
+ i = 0;
+ while (i < len)
{
- for (i = 0; i < len; ++i)
+ if (layout.grid[i] >= 0)
{
MetaWorkspace *workspace;
-
- workspace = meta_screen_get_workspace_by_index (screen, i);
-
- g_assert (workspace);
-
+
+ workspace = meta_screen_get_workspace_by_index (screen,
+ layout.grid[i]);
+
entries[i].key = (MetaTabEntryKey) workspace;
entries[i].title = meta_workspace_get_name (workspace);
entries[i].icon = NULL;
-
+ entries[i].blank = FALSE;
+
g_assert (entries[i].title != NULL);
}
+ else
+ {
+ entries[i].key = NULL;
+ entries[i].title = NULL;
+ entries[i].icon = NULL;
+ entries[i].blank = TRUE;
+ }
+
+ ++i;
}
screen->tab_popup = meta_ui_tab_popup_new (entries,
screen->number,
len,
- cols,
+ layout.cols,
FALSE);
g_free (entries);
+ meta_screen_free_workspace_layout (&layout);
- /* don't show tab popup, since proper window isn't selected yet */
+ /* don't show tab popup, since proper space isn't selected yet */
}
/* Focus top window on active workspace */
@@ -1594,36 +1582,39 @@ meta_screen_queue_workarea_recalc (MetaScreen *screen)
}
}
+
+#ifdef WITH_VERBOSE_MODE
+static char *
+meta_screen_corner_to_string (MetaScreenCorner corner)
+{
+ switch (corner)
+ {
+ case META_SCREEN_TOPLEFT:
+ return "TopLeft";
+ case META_SCREEN_TOPRIGHT:
+ return "TopRight";
+ case META_SCREEN_BOTTOMLEFT:
+ return "BottomLeft";
+ case META_SCREEN_BOTTOMRIGHT:
+ return "BottomRight";
+ }
+
+ return "Unknown";
+}
+#endif /* WITH_VERBOSE_MODE */
+
void
-meta_screen_calc_workspace_layout (MetaScreen *screen,
- int num_workspaces,
- int *r,
- int *c)
+meta_screen_calc_workspace_layout (MetaScreen *screen,
+ int num_workspaces,
+ int current_space,
+ MetaWorkspaceLayout *layout)
{
- int cols, rows;
-
- /*
- * 3 rows, 4 columns, horizontal layout
- * and starting from top left:
- * +--+--+--+--+
- * | 1| 2| 3| 4|
- * +--+--+--+--+
- * | 5| 6| 7| 8|
- * +--+--+--+--+
- * | 9|10|11|12|
- * +--+--+--+--+
- *
- * vertical layout:
- * +--+--+--+--+
- * | 1| 4| 7|10|
- * +--+--+--+--+
- * | 2| 5| 8|11|
- * +--+--+--+--+
- * | 3| 6| 9|12|
- * +--+--+--+--+
- *
- */
-
+ int rows, cols;
+ int grid_area;
+ int *grid;
+ int i, r, c;
+ int current_row, current_col;
+
rows = screen->rows_of_workspaces;
cols = screen->columns_of_workspaces;
if (rows <= 0 && cols <= 0)
@@ -1640,8 +1631,251 @@ meta_screen_calc_workspace_layout (MetaScreen *screen,
if (cols < 1)
cols = 1;
- *r = rows;
- *c = cols;
+ g_assert (rows != 0 && cols != 0);
+
+ grid_area = rows * cols;
+
+ meta_verbose ("Getting layout rows = %d cols = %d current = %d "
+ "num_spaces = %d vertical = %s corner = %s\n",
+ rows, cols, current_space, num_workspaces,
+ screen->vertical_workspaces ? "(true)" : "(false)",
+ meta_screen_corner_to_string (screen->starting_corner));
+
+ /* ok, we want to setup the distances in the workspace array to go
+ * in each direction. Remember, there are many ways that a workspace
+ * array can be setup.
+ * see http://www.freedesktop.org/standards/wm-spec/1.2/html/x109.html
+ * and look at the _NET_DESKTOP_LAYOUT section for details.
+ * For instance:
+ */
+ /* starting_corner = META_SCREEN_TOPLEFT
+ * vertical_workspaces = 0 vertical_workspaces=1
+ * 1234 1357
+ * 5678 2468
+ *
+ * starting_corner = META_SCREEN_TOPRIGHT
+ * vertical_workspaces = 0 vertical_workspaces=1
+ * 4321 7531
+ * 8765 8642
+ *
+ * starting_corner = META_SCREEN_BOTTOMLEFT
+ * vertical_workspaces = 0 vertical_workspaces=1
+ * 5678 2468
+ * 1234 1357
+ *
+ * starting_corner = META_SCREEN_BOTTOMRIGHT
+ * vertical_workspaces = 0 vertical_workspaces=1
+ * 8765 8642
+ * 4321 7531
+ *
+ */
+ /* keep in mind that we could have a ragged layout, e.g. the "8"
+ * in the above grids could be missing
+ */
+
+
+ grid = g_new (int, grid_area);
+
+ current_row = -1;
+ current_col = -1;
+ i = 0;
+
+ switch (screen->starting_corner)
+ {
+ case META_SCREEN_TOPLEFT:
+ if (screen->vertical_workspaces)
+ {
+ r = 0;
+ while (r < rows)
+ {
+ c = 0;
+ while (c < cols)
+ {
+ grid[r*cols+c] = i;
+ ++i;
+ ++c;
+ }
+ ++r;
+ }
+ }
+ else
+ {
+ c = 0;
+ while (c < cols)
+ {
+ r = 0;
+ while (r < rows)
+ {
+ grid[r*cols+c] = i;
+ ++i;
+ ++r;
+ }
+ ++c;
+ }
+ }
+ break;
+ case META_SCREEN_TOPRIGHT:
+ if (screen->vertical_workspaces)
+ {
+ r = 0;
+ while (r < rows)
+ {
+ c = cols - 1;
+ while (c >= 0)
+ {
+ grid[r*cols+c] = i;
+ ++i;
+ --c;
+ }
+ ++r;
+ }
+ }
+ else
+ {
+ c = cols - 1;
+ while (c >= 0)
+ {
+ r = 0;
+ while (r < rows)
+ {
+ grid[r*cols+c] = i;
+ ++i;
+ ++r;
+ }
+ --c;
+ }
+ }
+ break;
+ case META_SCREEN_BOTTOMLEFT:
+ if (screen->vertical_workspaces)
+ {
+ r = rows - 1;
+ while (r >= 0)
+ {
+ c = 0;
+ while (c < cols)
+ {
+ grid[r*cols+c] = i;
+ ++i;
+ ++c;
+ }
+ --r;
+ }
+ }
+ else
+ {
+ c = 0;
+ while (c < cols)
+ {
+ r = rows - 1;
+ while (r >= 0)
+ {
+ grid[r*cols+c] = i;
+ ++i;
+ --r;
+ }
+ ++c;
+ }
+ }
+ break;
+ case META_SCREEN_BOTTOMRIGHT:
+ if (screen->vertical_workspaces)
+ {
+ r = rows - 1;
+ while (r >= 0)
+ {
+ c = cols - 1;
+ while (c >= 0)
+ {
+ grid[r*cols+c] = i;
+ ++i;
+ --c;
+ }
+ --r;
+ }
+ }
+ else
+ {
+ c = cols - 1;
+ while (c >= 0)
+ {
+ r = rows - 1;
+ while (r >= 0)
+ {
+ grid[r*cols+c] = i;
+ ++i;
+ --r;
+ }
+ --c;
+ }
+ }
+ break;
+ }
+
+ if (i != grid_area)
+ meta_bug ("did not fill in the whole workspace grid in %s (%d filled)\n",
+ G_GNUC_FUNCTION, i);
+
+ current_row = 0;
+ current_col = 0;
+ r = 0;
+ while (r < rows)
+ {
+ c = 0;
+ while (c < cols)
+ {
+ if (grid[r*cols+c] == current_space)
+ {
+ current_row = r;
+ current_col = c;
+ }
+ else if (grid[r*cols+c] >= num_workspaces)
+ {
+ /* flag nonexistent spaces with -1 */
+ grid[r*cols+c] = -1;
+ }
+ ++c;
+ }
+ ++r;
+ }
+
+ layout->rows = rows;
+ layout->cols = cols;
+ layout->grid = grid;
+ layout->grid_area = grid_area;
+ layout->current_row = current_row;
+ layout->current_col = current_col;
+
+#ifdef WITH_VERBOSE_MODE
+ if (meta_is_verbose ())
+ {
+ r = 0;
+ while (r < layout->rows)
+ {
+ meta_verbose ("");
+ meta_push_no_msg_prefix ();
+ c = 0;
+ while (c < layout->cols)
+ {
+ if (r == layout->current_row &&
+ c == layout->current_col)
+ meta_verbose ("*%2d ", layout->grid[r*layout->cols+c]);
+ else
+ meta_verbose ("%3d ", layout->grid[r*layout->cols+c]);
+ ++c;
+ }
+ meta_verbose ("\n");
+ meta_pop_no_msg_prefix ();
+ ++r;
+ }
+ }
+#endif /* WITH_VERBOSE_MODE */
+}
+
+void
+meta_screen_free_workspace_layout (MetaWorkspaceLayout *layout)
+{
+ g_free (layout->grid);
}
static void
diff --git a/src/screen.h b/src/screen.h
index 351f6b9..5ab5ec3 100644
--- a/src/screen.h
+++ b/src/screen.h
@@ -138,10 +138,23 @@ void meta_screen_queue_workarea_recalc (MetaScreen *scree
Window meta_create_offscreen_window (Display *xdisplay,
Window parent);
-void meta_screen_calc_workspace_layout (MetaScreen *screen,
- int num_workspaces,
- int *r,
- int *c);
+typedef struct MetaWorkspaceLayout MetaWorkspaceLayout;
+
+struct MetaWorkspaceLayout
+{
+ int rows;
+ int cols;
+ int *grid;
+ int grid_area;
+ int current_row;
+ int current_col;
+};
+
+void meta_screen_calc_workspace_layout (MetaScreen *screen,
+ int num_workspaces,
+ int current_space,
+ MetaWorkspaceLayout *layout);
+void meta_screen_free_workspace_layout (MetaWorkspaceLayout *layout);
void meta_screen_resize (MetaScreen *screen,
int width,
diff --git a/src/tabpopup.c b/src/tabpopup.c
index 5dfcf1c..58e2a2a 100644
--- a/src/tabpopup.c
+++ b/src/tabpopup.c
@@ -44,6 +44,7 @@ struct _TabEntry
GtkWidget *widget;
GdkRectangle rect;
GdkRectangle inner_rect;
+ guint blank : 1;
};
struct _MetaTabPopup
@@ -160,6 +161,7 @@ meta_ui_tab_popup_new (const MetaTabEntry *entries,
te->title = g_strdup (entries[i].title);
te->widget = NULL;
te->icon = entries[i].icon;
+ te->blank = entries[i].blank;
if (te->icon)
g_object_ref (G_OBJECT (te->icon));
@@ -227,8 +229,13 @@ meta_ui_tab_popup_new (const MetaTabEntry *entries,
TabEntry *te;
te = tmp->data;
-
- if (outline)
+
+ if (te->blank)
+ {
+ /* just stick a widget here to avoid special cases */
+ image = gtk_alignment_new (0.0, 0.0, 0.0, 0.0);
+ }
+ else if (outline)
{
image = selectable_image_new (te->icon);
diff --git a/src/tabpopup.h b/src/tabpopup.h
index 67a0c74..82f28f5 100644
--- a/src/tabpopup.h
+++ b/src/tabpopup.h
@@ -39,6 +39,7 @@ struct _MetaTabEntry
GdkPixbuf *icon;
int x, y, width, height;
int inner_x, inner_y, inner_width, inner_height;
+ guint blank : 1;
};
MetaTabPopup* meta_ui_tab_popup_new (const MetaTabEntry *entries,
diff --git a/src/util.c b/src/util.c
index 6e43f5f..e104419 100644
--- a/src/util.c
+++ b/src/util.c
@@ -286,7 +286,7 @@ topic_name (MetaDebugTopic topic)
return "SHAPES";
}
- return "Window manager";
+ return "WM";
}
static int sync_count = 0;
diff --git a/src/workspace.c b/src/workspace.c
index d49fd39..40e445d 100644
--- a/src/workspace.c
+++ b/src/workspace.c
@@ -435,168 +435,59 @@ meta_motion_direction_to_string (MetaMotionDirection direction)
}
#endif /* WITH_VERBOSE_MODE */
-#ifdef WITH_VERBOSE_MODE
-static char *
-meta_screen_corner_to_string (MetaScreenCorner corner)
-{
- switch (corner)
- {
- case META_SCREEN_TOPLEFT:
- return "TopLeft";
- case META_SCREEN_TOPRIGHT:
- return "TopRight";
- case META_SCREEN_BOTTOMLEFT:
- return "BottomLeft";
- case META_SCREEN_BOTTOMRIGHT:
- return "BottomRight";
- }
-
- return "Unknown";
-}
-#endif /* WITH_VERBOSE_MODE */
-
MetaWorkspace*
meta_workspace_get_neighbor (MetaWorkspace *workspace,
MetaMotionDirection direction)
{
- int i, num_workspaces, grid_area;
- int rows, cols;
- int new_workspace_idx;
- int up_diff, down_diff, left_diff, right_diff;
- int current_row, current_col;
-
- i = meta_workspace_index (workspace);
+ MetaWorkspaceLayout layout;
+ int i, current_space, num_workspaces;
+
+ current_space = meta_workspace_index (workspace);
num_workspaces = meta_screen_get_n_workspaces (workspace->screen);
-
meta_screen_calc_workspace_layout (workspace->screen, num_workspaces,
- &rows, &cols);
-
- g_assert (rows != 0 && cols != 0);
-
- grid_area = rows * cols;
+ current_space, &layout);
- meta_verbose ("Getting neighbor rows = %d cols = %d current = %d "
- "num_spaces = %d vertical = %s direction = %s corner = %s\n",
- rows, cols, i, num_workspaces,
- workspace->screen->vertical_workspaces ? "(true)" : "(false)",
- meta_motion_direction_to_string (direction),
- meta_screen_corner_to_string (workspace->screen->starting_corner));
+ meta_verbose ("Getting neighbor of %d in direction %s\n",
+ current_space, meta_motion_direction_to_string (direction));
- /* ok, we want to setup the distances in the workspace array to go
- * in each direction. Remember, there are many ways that a workspace
- * array can be setup.
- * see http://www.freedesktop.org/standards/wm-spec/1.2/html/x109.html
- * and look at the _NET_DESKTOP_LAYOUT section for details.
- * For instance:
- */
- /* starting_corner = META_SCREEN_TOPLEFT
- * vertical_workspaces = 0 vertical_workspaces=1
- * 1234 1357
- * 5678 2468
- *
- * starting_corner = META_SCREEN_TOPRIGHT
- * vertical_workspaces = 0 vertical_workspaces=1
- * 4321 7531
- * 8765 8642
- *
- * starting_corner = META_SCREEN_BOTTOMLEFT
- * vertical_workspaces = 0 vertical_workspaces=1
- * 5678 2468
- * 1234 1357
- *
- * starting_corner = META_SCREEN_BOTTOMRIGHT
- * vertical_workspaces = 0 vertical_workspaces=1
- * 8765 8642
- * 4321 7531
- *
- */
-
- if (workspace->screen->vertical_workspaces)
- {
- up_diff = -1;
- down_diff = 1;
- left_diff = -1 * rows;
- right_diff = rows;
- current_col = ((i - 1) / rows) + 1;
- current_row = ((i - 1) % rows) + 1;
- }
- else
- {
- up_diff = -1 * cols;
- down_diff = cols;
- left_diff = -1;
- right_diff = 1;
- current_col = (i % cols) + 1;
- current_row = ((i - 1) / cols) + 1;
- }
-
- switch (workspace->screen->starting_corner)
- {
- default:
- case META_SCREEN_TOPLEFT:
- /* this was the default case setup in the if() above */
- break;
- case META_SCREEN_TOPRIGHT:
- /* ok, we need to inverse the left/right values */
- left_diff = -1 * left_diff;
- right_diff = -1 * right_diff;
- /* also, current column needs to be mirrored */
- current_col = rows - ((current_col-1)%rows) ;
- break;
- case META_SCREEN_BOTTOMLEFT:
- /* ok, we need to inverse the up/down values */
- up_diff = -1 * up_diff;
- down_diff = -1 * up_diff;
- /* also, current row needs to be mirrored */
- current_row = cols - ((current_row-1)%cols);
- break;
- case META_SCREEN_BOTTOMRIGHT:
- /* in this case, we need to inverse everything */
- up_diff = -1 * up_diff;
- down_diff = -1 * up_diff;
- left_diff = -1 * left_diff;
- right_diff = -1 * right_diff;
- /* also, current column and row need to be reversed */
- current_col = rows - ((current_col-1)%rows);
- current_row = cols - ((current_row-1)%cols);
- break;
- }
-
- meta_verbose ("Workspace deltas: up = %d down = %d left = %d right = %d. "
- "Current col = %d row = %d\n", up_diff, down_diff, left_diff,
- right_diff, current_col, current_row);
-
- /* calculate what we think the next spot should be */
- new_workspace_idx = i;
-
switch (direction)
{
case META_MOTION_LEFT:
- if (current_col >= 1)
- new_workspace_idx = i + left_diff;
+ layout.current_col -= 1;
break;
case META_MOTION_RIGHT:
- if (current_col <= cols)
- new_workspace_idx = i + right_diff;
+ layout.current_col += 1;
break;
case META_MOTION_UP:
- if (current_row >= 1)
- new_workspace_idx = i + up_diff;
+ layout.current_row -= 1;
break;
case META_MOTION_DOWN:
- if (current_row <= rows)
- new_workspace_idx = i + down_diff;
- break;
- default:
- new_workspace_idx = 0;
+ layout.current_row += 1;
break;
}
- /* and now make sure we don't over/under flow */
- if ((new_workspace_idx >= 0) && (new_workspace_idx < num_workspaces))
- i = new_workspace_idx;
-
- meta_verbose ("Neighbor workspace is %d\n", i);
+ if (layout.current_col < 0)
+ layout.current_col = 0;
+ if (layout.current_col >= layout.cols)
+ layout.current_col = layout.cols - 1;
+ if (layout.current_row < 0)
+ layout.current_row = 0;
+ if (layout.current_row >= layout.rows)
+ layout.current_row = layout.rows - 1;
+
+ i = layout.grid[layout.current_row * layout.cols + layout.current_col];
+
+ if (i < 0)
+ i = current_space;
+
+ if (i >= num_workspaces)
+ meta_bug ("calc_workspace_layout left an invalid (too-high) workspace number %d in the grid\n",
+ i);
+
+ meta_verbose ("Neighbor workspace is %d at row %d col %d\n",
+ i, layout.current_row, layout.current_col);
+
+ meta_screen_free_workspace_layout (&layout);
return meta_screen_get_workspace_by_index (workspace->screen, i);
}