summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHavoc Pennington <hp@pobox.com>2001-12-10 03:55:26 +0000
committerHavoc Pennington <hp@src.gnome.org>2001-12-10 03:55:26 +0000
commit041b33c450ec54ad85d9f642035f0cc9d9195e26 (patch)
treefba66e02b3e5af9b8b88d44a49803b8c946de82a /src
parent06a0c62f86fb4096023ce5ee22aa37861180763c (diff)
downloadmetacity-041b33c450ec54ad85d9f642035f0cc9d9195e26.tar.gz
metacity-041b33c450ec54ad85d9f642035f0cc9d9195e26.tar.bz2
update number of workspaces hint
2001-12-09 Havoc Pennington <hp@pobox.com> * src/workspace.c (meta_workspace_free): update number of workspaces hint * src/screen.c (update_num_workspaces): implement number of workspaces setting * src/window.c (meta_window_configure_request): honor configure requests on windows of type NORMAL, but still be mean to those of type DIALOG * src/main.c (main): add more log domains to those we set a log handler for, and only set warnings fatal in debug mode * src/metacity.schemas: add number of workspaces setting
Diffstat (limited to 'src')
-rw-r--r--src/errors.c2
-rw-r--r--src/main.c24
-rw-r--r--src/metacity.schemas16
-rw-r--r--src/prefs.c65
-rw-r--r--src/prefs.h4
-rw-r--r--src/screen.c107
-rw-r--r--src/window.c10
-rw-r--r--src/workspace.c50
-rw-r--r--src/workspace.h2
9 files changed, 263 insertions, 17 deletions
diff --git a/src/errors.c b/src/errors.c
index 3bf480f..95d1a33 100644
--- a/src/errors.c
+++ b/src/errors.c
@@ -51,7 +51,7 @@ meta_error_trap_push (MetaDisplay *display)
int
meta_error_trap_pop (MetaDisplay *display)
{
- /* just use GDK trap */
+ /* just use GDK trap, but we do the sync since GDK doesn't */
XSync (display->xdisplay, False);
return gdk_error_trap_pop ();
diff --git a/src/main.c b/src/main.c
index f00d87e..2228bb7 100644
--- a/src/main.c
+++ b/src/main.c
@@ -49,7 +49,7 @@ log_handler (const gchar *log_domain,
const gchar *message,
gpointer user_data)
{
- meta_warning ("GLib log level %d: %s\n", log_level, message);
+ meta_warning ("Log level %d: %s\n", log_level, message);
}
static void
@@ -184,8 +184,28 @@ main (int argc, char **argv)
g_log_set_handler (NULL,
G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,
log_handler, NULL);
- g_log_set_always_fatal (G_LOG_LEVEL_MASK);
+ g_log_set_handler ("Gtk",
+ G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,
+ log_handler, NULL);
+ g_log_set_handler ("Gdk",
+ G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,
+ log_handler, NULL);
+ g_log_set_handler ("GLib",
+ G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,
+ log_handler, NULL);
+ g_log_set_handler ("Pango",
+ G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,
+ log_handler, NULL);
+ g_log_set_handler ("GLib-GObject",
+ G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,
+ log_handler, NULL);
+ g_log_set_handler ("GThread",
+ G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,
+ log_handler, NULL);
+ if (meta_is_debugging ())
+ g_log_set_always_fatal (G_LOG_LEVEL_MASK);
+
/* Connect to SM as late as possible - but before managing display,
* or we might try to manage a window before we have the session
* info
diff --git a/src/metacity.schemas b/src/metacity.schemas
index e8caa56..355a909 100644
--- a/src/metacity.schemas
+++ b/src/metacity.schemas
@@ -76,6 +76,22 @@
</locale>
</schema>
+ <schema>
+ <key>/schemas/apps/metacity/general/num_workspaces</key>
+ <applyto>/apps/metacity/general/num_workspaces</applyto>
+ <owner>metacity</owner>
+ <type>int</type>
+ <default>4</default>
+ <locale name="C">
+ <short>Number of workspaces</short>
+ <long>
+ Number of workspaces. Must be more than zero, and
+ has a fixed maximum (to prevent accidentally destroying
+ your desktop by asking for 34 million workspaces).
+ </long>
+ </locale>
+ </schema>
+
<!-- Keybindings -->
<schema>
diff --git a/src/prefs.c b/src/prefs.c
index a82d69a..eefb091 100644
--- a/src/prefs.c
+++ b/src/prefs.c
@@ -32,6 +32,7 @@
#define KEY_USE_DESKTOP_FONT "/apps/metacity/general/titlebar_uses_desktop_font"
#define KEY_TITLEBAR_FONT "/apps/metacity/general/titlebar_font"
#define KEY_TITLEBAR_FONT_SIZE "/apps/metacity/general/titlebar_font_size"
+#define KEY_NUM_WORKSPACES "/apps/metacity/general/num_workspaces"
static GConfClient *client = NULL;
static GList *listeners = NULL;
@@ -41,11 +42,13 @@ static gboolean use_desktop_font = TRUE;
static PangoFontDescription *titlebar_font = NULL;
static int titlebar_font_size = 0;
static MetaFocusMode focus_mode = META_FOCUS_MODE_CLICK;
+static int num_workspaces = 4;
static gboolean update_use_desktop_font (gboolean value);
static gboolean update_titlebar_font (const char *value);
static gboolean update_titlebar_font_size (int value);
static gboolean update_focus_mode (const char *value);
+static gboolean update_num_workspaces (int value);
static void queue_changed (MetaPreference pref);
static void change_notify (GConfClient *client,
@@ -174,7 +177,7 @@ cleanup_error (GError **error)
{
if (*error)
{
- meta_warning ("%s", (*error)->message);
+ meta_warning ("%s\n", (*error)->message);
g_error_free (*error);
*error = NULL;
@@ -206,6 +209,11 @@ meta_prefs_init (void)
update_focus_mode (str_val);
g_free (str_val);
+ /* If the keys aren't set in the database, we use essentially
+ * bogus values instead of any kind of default. This is
+ * just lazy. But they keys ought to be set, anyhow.
+ */
+
bool_val = gconf_client_get_bool (client, KEY_USE_DESKTOP_FONT,
&err);
cleanup_error (&err);
@@ -222,6 +230,11 @@ meta_prefs_init (void)
update_titlebar_font (str_val);
g_free (str_val);
+ int_val = gconf_client_get_int (client, KEY_NUM_WORKSPACES,
+ &err);
+ cleanup_error (&err);
+ update_num_workspaces (int_val);
+
gconf_client_notify_add (client, "/apps/metacity",
change_notify,
NULL,
@@ -310,6 +323,23 @@ change_notify (GConfClient *client,
if (update_use_desktop_font (b))
queue_changed (META_PREF_TITLEBAR_FONT);
}
+ else if (strcmp (key, KEY_NUM_WORKSPACES) == 0)
+ {
+ int d;
+
+ if (value && value->type != GCONF_VALUE_INT)
+ {
+ meta_warning (_("GConf key \"%s\" is set to an invalid type\n"),
+ KEY_NUM_WORKSPACES);
+ goto out;
+ }
+
+ /* 4 is a fallback that should never be used */
+ d = value ? gconf_value_get_int (value) : 4;
+
+ if (update_num_workspaces (d))
+ queue_changed (META_PREF_NUM_WORKSPACES);
+ }
else
meta_verbose ("Key %s doesn't mean anything to Metacity\n",
key);
@@ -419,6 +449,35 @@ meta_prefs_get_titlebar_font_size (void)
return titlebar_font_size;
}
+
+#define MAX_REASONABLE_WORKSPACES 32
+
+static gboolean
+update_num_workspaces (int value)
+{
+ int old = num_workspaces;
+
+ if (value < 1 || value > MAX_REASONABLE_WORKSPACES)
+ {
+ meta_warning (_("%d stored in GConf key %s is not a reasonable number of workspaces, current maximum is %d\n"),
+ value, KEY_NUM_WORKSPACES, MAX_REASONABLE_WORKSPACES);
+ if (value < 1)
+ value = 1;
+ else if (value > MAX_REASONABLE_WORKSPACES)
+ value = MAX_REASONABLE_WORKSPACES;
+ }
+
+ num_workspaces = value;
+
+ return old != num_workspaces;
+}
+
+int
+meta_prefs_get_num_workspaces (void)
+{
+ return num_workspaces;
+}
+
const char*
meta_preference_to_string (MetaPreference pref)
{
@@ -435,6 +494,10 @@ meta_preference_to_string (MetaPreference pref)
case META_PREF_TITLEBAR_FONT_SIZE:
return "TITLEBAR_FONT_SIZE";
break;
+
+ case META_PREF_NUM_WORKSPACES:
+ return "NUM_WORKSPACES";
+ break;
}
return "(unknown)";
diff --git a/src/prefs.h b/src/prefs.h
index 3b45a61..2acb410 100644
--- a/src/prefs.h
+++ b/src/prefs.h
@@ -30,7 +30,8 @@ typedef enum
{
META_PREF_FOCUS_MODE,
META_PREF_TITLEBAR_FONT,
- META_PREF_TITLEBAR_FONT_SIZE
+ META_PREF_TITLEBAR_FONT_SIZE,
+ META_PREF_NUM_WORKSPACES
} MetaPreference;
@@ -50,6 +51,7 @@ MetaFocusMode meta_prefs_get_focus_mode (void);
const PangoFontDescription* meta_prefs_get_titlebar_font (void);
/* returns 0 if default should be used */
int meta_prefs_get_titlebar_font_size (void);
+int meta_prefs_get_num_workspaces (void);
#endif
diff --git a/src/screen.c b/src/screen.c
index 970751b..a04f39f 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -25,6 +25,7 @@
#include "errors.h"
#include "window.h"
#include "frame.h"
+#include "prefs.h"
#include "workspace.h"
#include "keybindings.h"
#include "stack.h"
@@ -36,6 +37,9 @@
static char* get_screen_name (MetaDisplay *display,
int number);
+static void update_num_workspaces (MetaScreen *screen);
+static void prefs_changed_callback (MetaPreference pref,
+ gpointer data);
static int
set_wm_check_hint (MetaScreen *screen)
@@ -231,6 +235,8 @@ meta_screen_new (MetaDisplay *display,
screen->tab_popup = NULL;
screen->stack = meta_stack_new (screen);
+
+ meta_prefs_add_listener (prefs_changed_callback, screen);
meta_verbose ("Added screen %d ('%s') root 0x%lx\n",
screen->number, screen->screen_name, screen->xroot);
@@ -240,7 +246,9 @@ meta_screen_new (MetaDisplay *display,
void
meta_screen_free (MetaScreen *screen)
-{
+{
+ meta_prefs_remove_listener (prefs_changed_callback, screen);
+
meta_screen_ungrab_keys (screen);
meta_ui_free (screen->ui);
@@ -303,6 +311,19 @@ meta_screen_for_x_screen (Screen *xscreen)
return meta_display_screen_for_x_screen (display, xscreen);
}
+static void
+prefs_changed_callback (MetaPreference pref,
+ gpointer data)
+{
+ MetaScreen *screen = data;
+
+ if (pref == META_PREF_NUM_WORKSPACES)
+ {
+ update_num_workspaces (screen);
+ }
+}
+
+
static char*
get_screen_name (MetaDisplay *display,
int number)
@@ -437,7 +458,91 @@ meta_screen_get_n_workspaces (MetaScreen *screen)
}
return i;
+}
+static void
+update_num_workspaces (MetaScreen *screen)
+{
+ int new_num;
+ GList *tmp;
+ int i;
+ GList *extras;
+ MetaWorkspace *last_remaining;
+ gboolean need_change_space;
+
+ new_num = meta_prefs_get_num_workspaces ();
+
+ g_assert (new_num > 0);
+
+ last_remaining = NULL;
+ extras = NULL;
+ i = 0;
+ tmp = screen->display->workspaces;
+ while (tmp != NULL)
+ {
+ MetaWorkspace *w = tmp->data;
+
+ if (w->screen == screen)
+ {
+ ++i;
+
+ if (i > new_num)
+ extras = g_list_prepend (extras, w);
+ else
+ last_remaining = w;
+ }
+
+ tmp = tmp->next;
+ }
+
+ g_assert (last_remaining);
+
+ /* Get rid of the extra workspaces by moving all their windows
+ * to last_remaining, then activating last_remaining if
+ * one of the removed workspaces was active. This will be a bit
+ * wacky if the config tool for changing number of workspaces
+ * is on a removed workspace ;-)
+ */
+ need_change_space = FALSE;
+ tmp = extras;
+ while (tmp != NULL)
+ {
+ MetaWorkspace *w = tmp->data;
+
+ meta_workspace_relocate_windows (w, last_remaining);
+
+ if (w == screen->active_workspace)
+ need_change_space = TRUE;
+
+ tmp = tmp->next;
+ }
+
+ if (need_change_space)
+ meta_workspace_activate (last_remaining);
+
+ /* Should now be safe to free the workspaces */
+ tmp = extras;
+ while (tmp != NULL)
+ {
+ MetaWorkspace *w = tmp->data;
+
+ g_assert (w->windows == NULL);
+ meta_workspace_free (w);
+
+ tmp = tmp->next;
+ }
+
+ g_list_free (extras);
+
+ /* Add missing workspaces. FIXME This will keep setting the
+ * number-of-workspaces root window property on each workspace
+ * creation, kind of a lame thing
+ */
+ while (i < new_num)
+ {
+ meta_workspace_new (screen);
+ ++i;
+ }
}
void
diff --git a/src/window.c b/src/window.c
index b7b47cd..fd15a99 100644
--- a/src/window.c
+++ b/src/window.c
@@ -2200,12 +2200,9 @@ meta_window_configure_request (MetaWindow *window,
if (((window->type == META_WINDOW_DESKTOP ||
window->type == META_WINDOW_DOCK ||
window->type == META_WINDOW_TOOLBAR ||
- window->type == META_WINDOW_MENU) &&
+ window->type == META_WINDOW_MENU ||
+ window->type == META_WINDOW_NORMAL) &&
(window->size_hints.flags & PPosition)) ||
- /* This is here exactly until some crap app annoys me
- * by misusing it. ;-) Then I remove it and only honor
- * USPosition at map time.
- */
(window->size_hints.flags & USPosition))
{
if (event->xconfigurerequest.value_mask & CWX)
@@ -2224,7 +2221,8 @@ meta_window_configure_request (MetaWindow *window,
if (window->type == META_WINDOW_DESKTOP ||
window->type == META_WINDOW_DOCK ||
window->type == META_WINDOW_TOOLBAR ||
- window->type == META_WINDOW_MENU)
+ window->type == META_WINDOW_MENU ||
+ window->type == META_WINDOW_NORMAL)
{
if (event->xconfigurerequest.value_mask & CWWidth)
width = event->xconfigurerequest.width;
diff --git a/src/workspace.c b/src/workspace.c
index 7bf51e9..20eb11e 100644
--- a/src/workspace.c
+++ b/src/workspace.c
@@ -58,24 +58,39 @@ void
meta_workspace_free (MetaWorkspace *workspace)
{
GList *tmp;
+ MetaScreen *screen;
+
+ g_return_if_fail (workspace != workspace->screen->active_workspace);
+
+ /* Here we assume all the windows are already on another workspace
+ * as well, so they won't be "orphaned"
+ */
tmp = workspace->windows;
while (tmp != NULL)
{
GList *next;
+ MetaWindow *window = tmp->data;
next = tmp->next;
- /* pop front of list */
- meta_workspace_remove_window (workspace, tmp->data);
+
+ /* pop front of list we're iterating over */
+ meta_workspace_remove_window (workspace, window);
+ g_assert (window->workspaces != NULL);
tmp = next;
}
g_assert (workspace->windows == NULL);
+
+ screen = workspace->screen;
workspace->screen->display->workspaces =
g_list_remove (workspace->screen->display->workspaces, workspace);
g_free (workspace);
+
+ /* Update hint for current number of workspaces */
+ set_number_of_spaces_hint (screen);
}
void
@@ -106,6 +121,34 @@ meta_workspace_remove_window (MetaWorkspace *workspace,
meta_window_queue_calc_showing (window);
}
+void
+meta_workspace_relocate_windows (MetaWorkspace *workspace,
+ MetaWorkspace *new_home)
+{
+ GList *tmp;
+ GList *copy;
+
+ g_return_if_fail (workspace != new_home);
+
+ /* can't modify list we're iterating over */
+ copy = g_list_copy (workspace->windows);
+
+ tmp = copy;
+ while (tmp != NULL)
+ {
+ MetaWindow *window = tmp->data;
+
+ meta_workspace_add_window (new_home, window);
+ meta_workspace_remove_window (workspace, window);
+
+ tmp = tmp->next;
+ }
+
+ g_list_free (copy);
+
+ g_assert (workspace->windows == NULL);
+}
+
gboolean
meta_workspace_contains_window (MetaWorkspace *workspace,
MetaWindow *window)
@@ -226,6 +269,3 @@ set_active_space_hint (MetaScreen *screen)
32, PropModeReplace, (guchar*) data, 1);
return meta_error_trap_pop (screen->display);
}
-
-
-
diff --git a/src/workspace.h b/src/workspace.h
index 6620eee..97f12ec 100644
--- a/src/workspace.h
+++ b/src/workspace.h
@@ -39,6 +39,8 @@ void meta_workspace_add_window (MetaWorkspace *workspace,
MetaWindow *window);
void meta_workspace_remove_window (MetaWorkspace *workspace,
MetaWindow *window);
+void meta_workspace_relocate_windows (MetaWorkspace *workspace,
+ MetaWorkspace *new_home);
/* don't confuse with meta_window_visible_on_workspace() */
gboolean meta_workspace_contains_window (MetaWorkspace *workspace,
MetaWindow *window);