summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog25
-rw-r--r--src/keybindings.c8
-rw-r--r--src/metacity.schemas35
-rw-r--r--src/place.c8
-rw-r--r--src/prefs.c54
-rw-r--r--src/prefs.h4
-rw-r--r--src/tools/metacity-window-demo.c60
-rw-r--r--src/window.c69
8 files changed, 229 insertions, 34 deletions
diff --git a/ChangeLog b/ChangeLog
index 947b6ef..d4be81b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,28 @@
+2002-04-30 Havoc Pennington <hp@pobox.com>
+
+ * src/window.c (recalc_window_features): don't try to decorate
+ toolbars.
+
+ * src/tools/metacity-window-demo.c: add menu and toolbar tests
+
+ * src/place.c (meta_window_place): only dialogs should be centered
+ over parent, not anything with transient for set.
+
+ * src/window.c (meta_window_configure_request): become more
+ fascist about window positioning if workarounds are disabled, and
+ less fascist if they are enabled.
+
+ * src/metacity.schemas: add a "disable_workarounds" option. Kind
+ of crack-smoking. But we just can't get all applications
+ fixed. And I need no-workarounds mode to monitor which apps are
+ broken and what needs fixing in specs.
+
+ * src/window.c (meta_window_configure_request): always allow
+ windows to resize themselves
+
+ * src/keybindings.c (reload_modmap): don't filter out Mode_switch,
+ apparently some people bind window manager shortcuts to that.
+
2002-04-30 Havoc Pennington <hp@redhat.com>
* src/window.c (constrain_position): oops, fix
diff --git a/src/keybindings.c b/src/keybindings.c
index 7181e97..5dd2de4 100644
--- a/src/keybindings.c
+++ b/src/keybindings.c
@@ -269,19 +269,13 @@ reload_modmap (MetaDisplay *display)
while (j < display->keysyms_per_keycode)
{
- if (syms[j] == XK_Mode_switch)
+ if (syms[j] == XK_Num_Lock)
{
- /* This modifier swaps groups */
-
/* Mod1Mask is 1 << 3 for example, i.e. the
* fourth modifier, i / keyspermod is the modifier
* index
*/
- display->mode_switch_mask |= (1 << ( i / modmap->max_keypermod));
- }
- else if (syms[j] == XK_Num_Lock)
- {
display->num_lock_mask |= (1 << ( i / modmap->max_keypermod));
}
else if (syms[j] == XK_Scroll_Lock)
diff --git a/src/metacity.schemas b/src/metacity.schemas
index e772418..9b0a5be 100644
--- a/src/metacity.schemas
+++ b/src/metacity.schemas
@@ -1173,6 +1173,41 @@ you set
</locale>
</schema>
+ <schema>
+ <key>/schemas/apps/metacity/general/disable_workarounds</key>
+ <applyto>/apps/metacity/general/disable_workarounds</applyto>
+ <owner>metacity</owner>
+ <type>bool</type>
+ <default>false</default>
+ <locale name="C">
+ <short>Disable misfeatures that are required by old or broken
+ applications</short>
+ <long>
+ Some applications break specifications in ways that result
+ in window manager misfeatures. For example, ideally Metacity
+ would place all dialogs in a consistent position with
+ respect to their parent window. This requires ignoring
+ application-specified positions for dialogs. But some
+ versions of Java/Swing mark their popup menus as dialogs,
+ so Metacity has to disable dialog positioning to allow
+ menus to work in broken Java applications. There are
+ several other examples like this.
+
+ This option puts Metacity in full-on Correct mode, which
+ perhaps gives a moderately nicer UI if you don't need to run
+ any broken apps. Sadly, workarounds must be enabled by
+ default; the real world is an ugly place.
+
+ Some of the workarounds are workarounds for limitations in
+ the specifications themselves, so sometimes a bug
+ in no-workarounds mode won't be fixable without
+ amending a spec.
+ </long>
+
+ </locale>
+ </schema>
+
+
</schemalist>
</gconfschemafile>
diff --git a/src/place.c b/src/place.c
index ae255f7..ade971b 100644
--- a/src/place.c
+++ b/src/place.c
@@ -220,7 +220,9 @@ meta_window_place (MetaWindow *window,
* put it at 1/5 down and horizontally centered
*/
- if (window->xtransient_for != None)
+ if ((window->type == META_WINDOW_DIALOG ||
+ window->type == META_WINDOW_MODAL_DIALOG) &&
+ window->xtransient_for != None)
{
/* Center horizontally, at top of parent vertically */
@@ -252,6 +254,10 @@ meta_window_place (MetaWindow *window,
}
}
+ /* FIXME UTILITY with transient set should be stacked up
+ * on the sides of the parent window or something.
+ */
+
if (window->type == META_WINDOW_DIALOG ||
window->type == META_WINDOW_MODAL_DIALOG ||
window->type == META_WINDOW_SPLASHSCREEN)
diff --git a/src/prefs.c b/src/prefs.c
index def0f07..58946c4 100644
--- a/src/prefs.c
+++ b/src/prefs.c
@@ -36,6 +36,7 @@
#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"
+#define KEY_DISABLE_WORKAROUNDS "/apps/metacity/general/disable_workarounds"
#define KEY_SCREEN_BINDINGS_PREFIX "/apps/metacity/global_keybindings"
#define KEY_WINDOW_BINDINGS_PREFIX "/apps/metacity/window_keybindings"
@@ -51,6 +52,7 @@ static MetaFocusMode focus_mode = META_FOCUS_MODE_CLICK;
static char* current_theme = NULL;
static int num_workspaces = 4;
static gboolean application_based = FALSE;
+static gboolean disable_workarounds = FALSE;
static gboolean update_use_desktop_font (gboolean value);
static gboolean update_titlebar_font (const char *value);
@@ -59,6 +61,7 @@ static gboolean update_focus_mode (const char *value);
static gboolean update_theme (const char *value);
static gboolean update_num_workspaces (int value);
static gboolean update_application_based (gboolean value);
+static gboolean update_disable_workarounds (gboolean value);
static gboolean update_window_binding (const char *name,
const char *value);
static gboolean update_screen_binding (const char *name,
@@ -265,6 +268,11 @@ meta_prefs_init (void)
cleanup_error (&err);
update_application_based (bool_val);
+ bool_val = gconf_client_get_bool (default_client, KEY_DISABLE_WORKAROUNDS,
+ &err);
+ cleanup_error (&err);
+ update_disable_workarounds (bool_val);
+
/* Load keybindings prefs */
init_bindings ();
@@ -425,6 +433,22 @@ change_notify (GConfClient *client,
if (update_application_based (b))
queue_changed (META_PREF_APPLICATION_BASED);
}
+ else if (strcmp (key, KEY_DISABLE_WORKAROUNDS) == 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) : disable_workarounds;
+
+ if (update_disable_workarounds (b))
+ queue_changed (META_PREF_DISABLE_WORKAROUNDS);
+ }
else if (str_has_prefix (key, KEY_WINDOW_BINDINGS_PREFIX))
{
const char *str;
@@ -651,6 +675,33 @@ meta_prefs_get_application_based (void)
return application_based;
}
+static gboolean
+update_disable_workarounds (gboolean value)
+{
+ gboolean old = disable_workarounds;
+
+ disable_workarounds = value;
+
+ {
+ static gboolean first_disable = TRUE;
+
+ if (disable_workarounds && first_disable)
+ {
+ first_disable = FALSE;
+
+ meta_warning (_("Workarounds for broken applications disabled. Some applications may not behave properly.\n"));
+ }
+ }
+
+ return old != disable_workarounds;
+}
+
+gboolean
+meta_prefs_get_disable_workarounds (void)
+{
+ return disable_workarounds;
+}
+
const char*
meta_preference_to_string (MetaPreference pref)
{
@@ -679,6 +730,9 @@ meta_preference_to_string (MetaPreference pref)
case META_PREF_WINDOW_KEYBINDINGS:
return "WINDOW_KEYBINDINGS";
+
+ case META_PREF_DISABLE_WORKAROUNDS:
+ return "DISABLE_WORKAROUNDS";
}
return "(unknown)";
diff --git a/src/prefs.h b/src/prefs.h
index 2b94ee7..d808cb7 100644
--- a/src/prefs.h
+++ b/src/prefs.h
@@ -35,7 +35,8 @@ typedef enum
META_PREF_NUM_WORKSPACES,
META_PREF_APPLICATION_BASED,
META_PREF_WINDOW_KEYBINDINGS,
- META_PREF_SCREEN_KEYBINDINGS
+ META_PREF_SCREEN_KEYBINDINGS,
+ META_PREF_DISABLE_WORKAROUNDS
} MetaPreference;
typedef void (* MetaPrefsChangedFunc) (MetaPreference pref,
@@ -57,6 +58,7 @@ const PangoFontDescription* meta_prefs_get_titlebar_font (void);
int meta_prefs_get_titlebar_font_size (void);
int meta_prefs_get_num_workspaces (void);
gboolean meta_prefs_get_application_based (void);
+gboolean meta_prefs_get_disable_workarounds (void);
void meta_prefs_set_num_workspaces (int n_workspaces);
diff --git a/src/tools/metacity-window-demo.c b/src/tools/metacity-window-demo.c
index dc64952..73b27c4 100644
--- a/src/tools/metacity-window-demo.c
+++ b/src/tools/metacity-window-demo.c
@@ -260,6 +260,56 @@ utility_cb (gpointer callback_data,
gtk_widget_show_all (window);
}
+static void
+toolbar_cb (gpointer callback_data,
+ guint callback_action,
+ GtkWidget *widget)
+{
+ GtkWidget *window;
+ GtkWidget *vbox;
+ GtkWidget *label;
+
+ window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ set_gtk_window_type (GTK_WINDOW (window), "_NET_WM_WINDOW_TYPE_TOOLBAR");
+ gtk_window_set_title (GTK_WINDOW (window), "Toolbar");
+
+ gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (callback_data));
+
+ vbox = gtk_vbox_new (FALSE, 0);
+
+ gtk_container_add (GTK_CONTAINER (window), vbox);
+
+ label = gtk_label_new ("FIXME this needs a resize grip, etc.");
+ gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
+
+ gtk_widget_show_all (window);
+}
+
+static void
+menu_cb (gpointer callback_data,
+ guint callback_action,
+ GtkWidget *widget)
+{
+ GtkWidget *window;
+ GtkWidget *vbox;
+ GtkWidget *label;
+
+ window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ set_gtk_window_type (GTK_WINDOW (window), "_NET_WM_WINDOW_TYPE_MENU");
+ gtk_window_set_title (GTK_WINDOW (window), "Menu");
+
+ gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (callback_data));
+
+ vbox = gtk_vbox_new (FALSE, 0);
+
+ gtk_container_add (GTK_CONTAINER (window), vbox);
+
+ label = gtk_label_new ("FIXME this isn't a menu.");
+ gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
+
+ gtk_widget_show_all (window);
+}
+
static gboolean
focus_in_event_cb (GtkWidget *window,
GdkEvent *event,
@@ -470,7 +520,9 @@ static GtkItemFactoryEntry menu_items[] =
{ "/Windows/_Left dock", NULL, dock_cb, DOCK_LEFT, NULL },
{ "/Windows/_Right dock", NULL, dock_cb, DOCK_RIGHT, NULL },
{ "/Windows/_All docks", NULL, dock_cb, DOCK_ALL, NULL },
- { "/Windows/Des_ktop", NULL, desktop_cb, 0, NULL }
+ { "/Windows/Des_ktop", NULL, desktop_cb, 0, NULL },
+ { "/Windows/Me_nu", NULL, menu_cb, 0, NULL },
+ { "/Windows/Tool_bar", NULL, toolbar_cb, 0, NULL }
};
static void
@@ -481,8 +533,8 @@ sleep_cb (GtkWidget *button,
}
static void
-toolbar_cb (GtkWidget *button,
- gpointer data)
+clicked_toolbar_cb (GtkWidget *button,
+ gpointer data)
{
GtkWidget *dialog;
@@ -629,7 +681,7 @@ do_appwindow (void)
GTK_STOCK_QUIT,
"This is a demo button with a 'quit' icon",
NULL,
- G_CALLBACK (toolbar_cb),
+ G_CALLBACK (clicked_toolbar_cb),
window, /* user data for callback */
-1); /* -1 means "append" */
diff --git a/src/window.c b/src/window.c
index 534a660..12dab95 100644
--- a/src/window.c
+++ b/src/window.c
@@ -2765,6 +2765,7 @@ meta_window_configure_request (MetaWindow *window,
{
int x, y, width, height;
gboolean only_resize;
+ gboolean allow_position_change;
/* it's essential to use only the explicitly-set fields,
* and otherwise use our current up-to-date position.
@@ -2778,15 +2779,31 @@ meta_window_configure_request (MetaWindow *window,
meta_window_get_gravity_position (window, &x, &y);
only_resize = TRUE;
+
+ allow_position_change = FALSE;
- 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_NORMAL ||
- window->type == META_WINDOW_UTILITY) &&
- (window->size_hints.flags & PPosition)) ||
- (window->size_hints.flags & USPosition))
+ if (meta_prefs_get_disable_workarounds ())
+ {
+ if (window->type == META_WINDOW_DIALOG ||
+ window->type == META_WINDOW_MODAL_DIALOG ||
+ window->type == META_WINDOW_SPLASHSCREEN)
+ ; /* No position change for these */
+ else if ((window->size_hints.flags & PPosition) ||
+ /* USPosition is just stale if window is placed;
+ * no --geometry involved here.
+ */
+ ((window->size_hints.flags & USPosition) &&
+ !window->placed))
+ allow_position_change = TRUE;
+ }
+ else
+ {
+ allow_position_change =
+ (window->size_hints.flags & PPosition) ||
+ (window->size_hints.flags & USPosition);
+ }
+
+ if (allow_position_change)
{
if (event->xconfigurerequest.value_mask & CWX)
x = event->xconfigurerequest.x;
@@ -2795,25 +2812,24 @@ meta_window_configure_request (MetaWindow *window,
y = event->xconfigurerequest.y;
if (event->xconfigurerequest.value_mask & (CWX | CWY))
- only_resize = FALSE;
+ {
+ only_resize = FALSE;
+
+ /* Once manually positioned, windows shouldn't be placed
+ * by the window manager.
+ */
+ window->placed = TRUE;
+ }
}
width = window->rect.width;
height = window->rect.height;
- 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_NORMAL ||
- window->type == META_WINDOW_UTILITY)
- {
- if (event->xconfigurerequest.value_mask & CWWidth)
- width = event->xconfigurerequest.width;
+ if (event->xconfigurerequest.value_mask & CWWidth)
+ width = event->xconfigurerequest.width;
- if (event->xconfigurerequest.value_mask & CWHeight)
- height = event->xconfigurerequest.height;
- }
+ if (event->xconfigurerequest.value_mask & CWHeight)
+ height = event->xconfigurerequest.height;
/* ICCCM 4.1.5 */
@@ -4683,6 +4699,8 @@ recalc_window_features (MetaWindow *window)
window->has_fullscreen_func = TRUE;
/* Semantic category overrides the MWM hints */
+ if (window->type == META_WINDOW_TOOLBAR)
+ window->decorated = FALSE;
if (window->type == META_WINDOW_DESKTOP ||
window->type == META_WINDOW_DOCK ||
@@ -4691,6 +4709,15 @@ recalc_window_features (MetaWindow *window)
window->decorated = FALSE;
window->has_close_func = FALSE;
window->has_shade_func = FALSE;
+
+ /* FIXME this keeps panels and things from using
+ * NET_WM_MOVERESIZE; the problem is that some
+ * panels (edge panels) have fixed possible locations,
+ * and others ("floating panels") do not.
+ *
+ * Perhaps we should require edge panels to explicitly
+ * disable movement?
+ */
window->has_move_func = FALSE;
window->has_resize_func = FALSE;
}