diff --git a/ChangeLog b/ChangeLog index d2e8a2b82..b62f8104d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2002-01-27 Havoc Pennington + + * src/display.c (event_callback): make the check for whether to + eat focus click a lot more complicated + + * src/window.c (meta_window_same_application): new function + + * src/prefs.h, src/prefs.c: add application based pref + + * src/metacity.schemas: add "application_based" setting to + give me a mode to fool with being application based, + without being unusable in the meantime. Yeah the crack flows + freely these days. Everyone knew it would happen. + 2002-01-27 Havoc Pennington * src/frames.c: separate code to draw frame from the diff --git a/src/display.c b/src/display.c index c84c4511a..8528f8e8f 100644 --- a/src/display.c +++ b/src/display.c @@ -771,13 +771,18 @@ event_callback (XEvent *event, */ int mode; - /* Eat clicks used to focus a window, except - * pass through when focusing a dock/desktop + /* When clicking a different app in click-to-focus + * in application-based mode, and the different + * app is not a dock or desktop, eat the focus click. */ if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK && + meta_prefs_get_application_based () && !window->has_focus && window->type != META_WINDOW_DOCK && - window->type != META_WINDOW_DESKTOP) + window->type != META_WINDOW_DESKTOP && + (display->focus_window == NULL || + !meta_window_same_application (window, + display->focus_window))) mode = AsyncPointer; /* eat focus click */ else mode = ReplayPointer; /* give event back */ diff --git a/src/metacity.schemas b/src/metacity.schemas index 355a90943..4f6fb4b63 100644 --- a/src/metacity.schemas +++ b/src/metacity.schemas @@ -116,6 +116,32 @@ + + /schemas/apps/metacity/general/application_based + /apps/metacity/general/application_based + metacity + bool + false + + Navigation works in terms of applications not windows + + If true, then Metacity works in terms of applications rather + than windows. The concept is a bit abstract, but + in general an application-based setup is more like + the Mac and less like Windows. When you focus a window + in application-based mode, all the windows in the + application will be raised. Also, in application-based + mode, focus clicks are not passed through to windows + in other applications. + The existence of this setting is somewhat questionable. + But it's better than having settings for all the specific + details of application-based vs. window-based, e.g. + whether to pass through clicks. Also, application-based mode + is largely unimplemented at the moment. + + + + diff --git a/src/prefs.c b/src/prefs.c index eefb0916e..79a2d1a01 100644 --- a/src/prefs.c +++ b/src/prefs.c @@ -33,6 +33,7 @@ #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" +#define KEY_APPLICATION_BASED "/apps/metacity/general/application_based" static GConfClient *client = NULL; static GList *listeners = NULL; @@ -43,12 +44,14 @@ 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 application_based = FALSE; 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 gboolean update_application_based (gboolean value); static void queue_changed (MetaPreference pref); static void change_notify (GConfClient *client, @@ -234,6 +237,11 @@ meta_prefs_init (void) &err); cleanup_error (&err); update_num_workspaces (int_val); + + bool_val = gconf_client_get_bool (client, KEY_APPLICATION_BASED, + &err); + cleanup_error (&err); + update_application_based (bool_val); gconf_client_notify_add (client, "/apps/metacity", change_notify, @@ -334,16 +342,33 @@ change_notify (GConfClient *client, goto out; } - /* 4 is a fallback that should never be used */ - d = value ? gconf_value_get_int (value) : 4; + d = value ? gconf_value_get_int (value) : num_workspaces; if (update_num_workspaces (d)) queue_changed (META_PREF_NUM_WORKSPACES); } - else - meta_verbose ("Key %s doesn't mean anything to Metacity\n", - key); + else if (strcmp (key, KEY_APPLICATION_BASED) == 0) + { + gboolean b; + if (value && value->type != GCONF_VALUE_BOOL) + { + meta_warning (_("GConf key \"%s\" is set to an invalid type\n"), + KEY_APPLICATION_BASED); + goto out; + } + + b = value ? gconf_value_get_bool (value) : application_based; + + if (update_application_based (b)) + queue_changed (META_PREF_APPLICATION_BASED); + } + else + { + meta_verbose ("Key %s doesn't mean anything to Metacity\n", + key); + } + out: /* nothing */ } @@ -478,6 +503,22 @@ meta_prefs_get_num_workspaces (void) return num_workspaces; } +static gboolean +update_application_based (gboolean value) +{ + gboolean old = application_based; + + application_based = value; + + return old != application_based; +} + +gboolean +meta_prefs_get_application_based (void) +{ + return application_based; +} + const char* meta_preference_to_string (MetaPreference pref) { @@ -498,6 +539,10 @@ meta_preference_to_string (MetaPreference pref) case META_PREF_NUM_WORKSPACES: return "NUM_WORKSPACES"; break; + + case META_PREF_APPLICATION_BASED: + return "APPLICATION_BASED"; + break; } return "(unknown)"; diff --git a/src/prefs.h b/src/prefs.h index 2acb4102e..3abdd36c9 100644 --- a/src/prefs.h +++ b/src/prefs.h @@ -31,7 +31,8 @@ typedef enum META_PREF_FOCUS_MODE, META_PREF_TITLEBAR_FONT, META_PREF_TITLEBAR_FONT_SIZE, - META_PREF_NUM_WORKSPACES + META_PREF_NUM_WORKSPACES, + META_PREF_APPLICATION_BASED } MetaPreference; @@ -52,6 +53,7 @@ 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); +gboolean meta_prefs_get_application_based (void); #endif diff --git a/src/window.c b/src/window.c index e728d826f..4d7699dcc 100644 --- a/src/window.c +++ b/src/window.c @@ -5740,3 +5740,12 @@ meta_window_get_work_area (MetaWindow *window, meta_verbose ("Window %s has work area %d,%d %d x %d\n", window->desc, area->x, area->y, area->width, area->height); } + +gboolean +meta_window_same_application (MetaWindow *window, + MetaWindow *other_window) +{ + return (window->xgroup_leader != None && + other_window->xgroup_leader != None && + window->xgroup_leader == other_window->xgroup_leader); +} diff --git a/src/window.h b/src/window.h index e8dc976cf..4ecc457de 100644 --- a/src/window.h +++ b/src/window.h @@ -349,4 +349,7 @@ gboolean meta_window_visible_on_workspace (MetaWindow *window, void meta_window_get_work_area (MetaWindow *window, MetaRectangle *area); +gboolean meta_window_same_application (MetaWindow *window, + MetaWindow *other_window); + #endif