diff --git a/ChangeLog b/ChangeLog index 66b748246..576fa0d7d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,38 @@ +2006-01-10 Elijah Newren + + Add a raise on click option, basically only because all the major + distros are patching it in anyway. See #326156. + + * src/metacity.schemas.in: add the new gconf key and explanation + + * src/prefs.[ch] (#define KEY_RAISE_ON_CLICK, static gboolean + raise_on_click, update_raise_on_click, meta_prefs_init, + change_notify, meta_prefs_get_raise_on_click, + meta_preference_to_string): + Add all the normal preference handling stuff for this new + raise-on-click option. + + * src/core.c (meta_core_show_window_menu): + * src/display.c (event_callback, meta_display_begin_grab_op): + * src/window.c (window_activate, meta_window_configure_request, ): + Only raise the window if in raise_on_click mode. + + * src/display.c (meta_display_begin_grab_op, + meta_display_end_grab_op, meta_display_check_threshold_reached): + * src/display.h (struct MetaDisplay): + * src/window.c (meta_window_handle_mouse_grab_op_event): + if not in raise-on-click mode only raise on button release if the + click didn't start a move or resize operation; needs a few extra + MetaDisplay fields to handle this + + * src/core.c (meta_core_user_lower_and_unfocus): + no need to do the MRU shuffling if not maintaining the stacking + order == MRU order invariant + + * src/frames.c (meta_frames_button_press_event): + * src/window.c (meta_window_begin_grab_op): + remove an unneeded window raising that is already handled elsewhere + 2006-01-10 Elijah Newren Don't "steal" focus from terminal windows for new window mappings diff --git a/src/core.c b/src/core.c index b4b6a5f89..72c49e1ed 100644 --- a/src/core.c +++ b/src/core.c @@ -269,7 +269,8 @@ meta_core_user_lower_and_unfocus (Display *xdisplay, meta_window_lower (window); - if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK) + if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK && + meta_prefs_get_raise_on_click ()) { /* Move window to the back of the focusing workspace's MRU list. * Do extra sanity checks to avoid possible race conditions. @@ -611,7 +612,8 @@ meta_core_show_window_menu (Display *xdisplay, if (window == NULL || window->frame == NULL) meta_bug ("No such frame window 0x%lx!\n", frame_xwindow); - meta_window_raise (window); + if (meta_prefs_get_raise_on_click ()) + meta_window_raise (window); meta_window_focus (window, timestamp); meta_window_show_menu (window, root_x, root_y, button, timestamp); diff --git a/src/display.c b/src/display.c index 30674c1fa..d05f398a0 100644 --- a/src/display.c +++ b/src/display.c @@ -1656,15 +1656,11 @@ event_callback (XEvent *event, */ if (!frame_was_receiver) { - /* Raise on clicking the client area always or only - * in click to focus mode? The debate rages. - * Feel free to change TRUE to FALSE or vice versa - */ - if (TRUE /* meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK */) + if (meta_prefs_get_raise_on_click ()) meta_window_raise (window); else meta_topic (META_DEBUG_FOCUS, - "Not raising window on click due to mouse/sloppy focus mode\n"); + "Not raising window on click due to don't-raise-on-click option\n"); /* Don't focus panels--they must explicitly request focus. * See bug 160470 @@ -1735,6 +1731,8 @@ event_callback (XEvent *event, } else if (event->xbutton.button == 3) { + if (meta_prefs_get_raise_on_click ()) + meta_window_raise (window); meta_window_show_menu (window, event->xbutton.x_root, event->xbutton.y_root, @@ -3227,6 +3225,19 @@ meta_display_begin_grab_op (MetaDisplay *display, return FALSE; } + if (window && + (meta_grab_op_is_moving (op) || meta_grab_op_is_resizing (op))) + { + if (meta_prefs_get_raise_on_click ()) + meta_window_raise (window); + else + { + display->grab_initial_x = root_x; + display->grab_initial_y = root_y; + display->grab_threshold_movement_reached = FALSE; + } + } + /* We'll ignore any events < this serial. */ if (pointer_already_grabbed) display->grab_start_serial = event_serial; @@ -3470,6 +3481,21 @@ meta_display_end_grab_op (MetaDisplay *display, if (display->grab_window != NULL) display->grab_window->shaken_loose = FALSE; + if (display->grab_window != NULL && + !meta_prefs_get_raise_on_click () && + (meta_grab_op_is_moving (display->grab_op) || + meta_grab_op_is_resizing (display->grab_op))) + { + /* Only raise the window in orthogonal raise + * ('do-not-raise-on-click') mode if the user didn't try to move + * or resize the given window by at least a threshold amount. + * For raise on click mode, the window was raised at the + * beginning of the grab_op. + */ + if (!display->grab_threshold_movement_reached) + meta_window_raise (display->grab_window); + } + if (GRAB_OP_IS_WINDOW_SWITCH (display->grab_op) || display->grab_op == META_GRAB_OP_KEYBOARD_WORKSPACE_SWITCHING) { @@ -3574,6 +3600,20 @@ meta_display_end_grab_op (MetaDisplay *display, } } +void +meta_display_check_threshold_reached (MetaDisplay *display, + int x, + int y) +{ + /* Don't bother doing the check again if we've already reached the threshold */ + if (display->grab_threshold_movement_reached) + return; + + if (ABS (display->grab_initial_x - x) >= 8 || + ABS (display->grab_initial_y - y) >= 8) + display->grab_threshold_movement_reached = TRUE; +} + static void meta_change_button_grab (MetaDisplay *display, Window xwindow, diff --git a/src/display.h b/src/display.h index 49bce7c13..0c47db92c 100644 --- a/src/display.h +++ b/src/display.h @@ -261,6 +261,8 @@ struct _MetaDisplay MetaRectangle grab_wireframe_rect; MetaRectangle grab_wireframe_last_xor_rect; MetaRectangle grab_initial_window_pos; + int grab_initial_x, grab_initial_y; + gboolean grab_threshold_movement_reached; MetaResizePopup *grab_resize_popup; GTimeVal grab_last_moveresize_time; Time grab_motion_notify_time; @@ -441,6 +443,9 @@ gboolean meta_display_begin_grab_op (MetaDisplay *display, void meta_display_end_grab_op (MetaDisplay *display, Time timestamp); +void meta_display_check_threshold_reached (MetaDisplay *display, + int x, + int y); void meta_display_grab_window_buttons (MetaDisplay *display, Window xwindow); void meta_display_ungrab_window_buttons (MetaDisplay *display, diff --git a/src/frames.c b/src/frames.c index c5f1b9c9f..0cc9e7308 100644 --- a/src/frames.c +++ b/src/frames.c @@ -1261,13 +1261,11 @@ meta_frames_button_press_event (GtkWidget *widget, control = get_control (frames, frame, event->x, event->y); - /* raise/focus on click, even if click was on client area */ + /* focus on click, even if click was on client area */ if (event->button == 1 && !(control == META_FRAME_CONTROL_MINIMIZE || control == META_FRAME_CONTROL_DELETE)) { - meta_core_user_raise (gdk_display, - frame->xwindow); meta_topic (META_DEBUG_FOCUS, "Focusing window with frame 0x%lx due to button 1 press\n", frame->xwindow); diff --git a/src/metacity.schemas.in b/src/metacity.schemas.in index 337b1ae59..bc31785b3 100644 --- a/src/metacity.schemas.in +++ b/src/metacity.schemas.in @@ -61,6 +61,30 @@ + + /schemas/apps/metacity/general/raise_on_click + /apps/metacity/general/raise_on_click + metacity + bool + true + + Whether raising should be a side-effect of other user + interactions + + Many actions (e.g. clicking in the client area, moving or + resizing the window) normally raise the window as a side-effect. + Set this option to false to decouple raising from other user + interactions. When false, windows can still be raised by an + alt-left-click anywhere on the window or a normal click on the + window decorations (assuming such clicks aren't used to start a + move or resize operation). Special messages, such as activation + requests from pagers, may also raise windows when this option is + false. This option is currently disabled in click-to-focus + mode. + + + + /schemas/apps/metacity/general/action_double_click_titlebar /apps/metacity/general/action_double_click_titlebar diff --git a/src/prefs.c b/src/prefs.c index 97262fd7a..1557cd6ee 100644 --- a/src/prefs.c +++ b/src/prefs.c @@ -41,6 +41,7 @@ */ #define KEY_MOUSE_BUTTON_MODS "/apps/metacity/general/mouse_button_modifier" #define KEY_FOCUS_MODE "/apps/metacity/general/focus_mode" +#define KEY_RAISE_ON_CLICK "/apps/metacity/general/raise_on_click" #define KEY_ACTION_DOUBLE_CLICK_TITLEBAR "/apps/metacity/general/action_double_click_titlebar" #define KEY_AUTO_RAISE "/apps/metacity/general/auto_raise" #define KEY_AUTO_RAISE_DELAY "/apps/metacity/general/auto_raise_delay" @@ -80,6 +81,7 @@ static gboolean use_system_font = TRUE; static PangoFontDescription *titlebar_font = NULL; static MetaVirtualModifier mouse_button_mods = Mod1Mask; static MetaFocusMode focus_mode = META_FOCUS_MODE_CLICK; +static gboolean raise_on_click = TRUE; static char* current_theme = NULL; static int num_workspaces = 4; static MetaActionDoubleClickTitlebar action_double_click_titlebar = @@ -123,6 +125,7 @@ static gboolean update_use_system_font (gboolean value); static gboolean update_titlebar_font (const char *value); static gboolean update_mouse_button_mods (const char *value); static gboolean update_focus_mode (const char *value); +static gboolean update_raise_on_click (gboolean value); static gboolean update_theme (const char *value); static gboolean update_visual_bell (gboolean v1, gboolean v2); static gboolean update_visual_bell_type (const char *value); @@ -346,6 +349,11 @@ meta_prefs_init (void) update_focus_mode (str_val); g_free (str_val); + bool_val = gconf_client_get_bool (default_client, KEY_RAISE_ON_CLICK, + &err); + cleanup_error (&err); + update_raise_on_click (bool_val); + str_val = gconf_client_get_string (default_client, KEY_ACTION_DOUBLE_CLICK_TITLEBAR, &err); @@ -551,6 +559,22 @@ change_notify (GConfClient *client, if (update_focus_mode (str)) queue_changed (META_PREF_FOCUS_MODE); } + else if (strcmp (key, KEY_RAISE_ON_CLICK) == 0) + { + gboolean b; + + if (value && value->type != GCONF_VALUE_BOOL) + { + meta_warning (_("GConf key \"%s\" is set to an invalid type\n"), + KEY_RAISE_ON_CLICK); + goto out; + } + + b = value ? gconf_value_get_bool (value) : TRUE; + + if (update_raise_on_click (b)) + queue_changed (META_PREF_RAISE_ON_CLICK); + } else if (strcmp (key, KEY_THEME) == 0) { const char *str; @@ -972,6 +996,18 @@ update_focus_mode (const char *value) } #endif /* HAVE_GCONF */ +#ifdef HAVE_GCONF +static gboolean +update_raise_on_click (gboolean value) +{ + gboolean old = raise_on_click; + + raise_on_click = value; + + return old != value; +} +#endif /* HAVE_GCONF */ + #ifdef HAVE_GCONF static gboolean update_theme (const char *value) @@ -1018,6 +1054,15 @@ meta_prefs_get_focus_mode (void) return focus_mode; } +gboolean +meta_prefs_get_raise_on_click (void) +{ + /* Force raise_on_click on for click-to-focus, as requested by Havoc + * in #326156. + */ + return raise_on_click || focus_mode == META_FOCUS_MODE_CLICK; +} + const char* meta_prefs_get_theme (void) { @@ -1496,6 +1541,9 @@ meta_preference_to_string (MetaPreference pref) case META_PREF_FOCUS_MODE: return "FOCUS_MODE"; + case META_PREF_RAISE_ON_CLICK: + return "RAISE_ON_CLICK"; + case META_PREF_THEME: return "THEME"; diff --git a/src/prefs.h b/src/prefs.h index 8b437d737..390e5352c 100644 --- a/src/prefs.h +++ b/src/prefs.h @@ -30,6 +30,7 @@ typedef enum { META_PREF_MOUSE_BUTTON_MODS, META_PREF_FOCUS_MODE, + META_PREF_RAISE_ON_CLICK, META_PREF_ACTION_DOUBLE_CLICK_TITLEBAR, META_PREF_AUTO_RAISE, META_PREF_AUTO_RAISE_DELAY, @@ -66,6 +67,7 @@ const char* meta_preference_to_string (MetaPreference pref); MetaVirtualModifier meta_prefs_get_mouse_button_mods (void); MetaFocusMode meta_prefs_get_focus_mode (void); +gboolean meta_prefs_get_raise_on_click (void); const char* meta_prefs_get_theme (void); /* returns NULL if GTK default should be used */ const PangoFontDescription* meta_prefs_get_titlebar_font (void); diff --git a/src/window.c b/src/window.c index b2ebfa75f..e736d4f42 100644 --- a/src/window.c +++ b/src/window.c @@ -1953,17 +1953,19 @@ meta_window_show (MetaWindow *window) ensure_mru_position_after (window, focus_window); /* We don't want the denied-focus window to obscure the focus - * window, and in click-to-focus-mode we want to maintain the - * invariant that MRU order == stacking order. The need for - * this if comes from the fact that in sloppy/mouse focus the - * focus window may not overlap other windows and also can be - * considered "below" them; this combination means that placing - * the denied-focus window "below" the focus window in the - * stack when it doesn't overlap it confusingly places that new - * window below a lot of other windows. + * window, and if we're in both click-to-focus mode and + * raise-on-click mode then we want to maintain the invariant + * that MRU order == stacking order. The need for this if + * comes from the fact that in sloppy/mouse focus the focus + * window may not overlap other windows and also can be + * considered "below" them; this combination means that + * placing the denied-focus window "below" the focus window + * in the stack when it doesn't overlap it confusingly places + * that new window below a lot of other windows. */ if (overlap || - meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK) + (meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK && + meta_prefs_get_raise_on_click ())) meta_window_stack_just_below (window, focus_window); /* If the window will be obscured by the focus window, then the @@ -2466,8 +2468,11 @@ window_activate (MetaWindow *window, meta_window_unshade (window); unminimize_window_and_all_transient_parents (window); - - meta_window_raise (window); + + if (meta_prefs_get_raise_on_click () || + source_indication == META_CLIENT_TYPE_PAGER) + meta_window_raise (window); + meta_topic (META_DEBUG_FOCUS, "Focusing window %s due to activation\n", window->desc); @@ -4217,7 +4222,8 @@ meta_window_configure_request (MetaWindow *window, { MetaWindow *active_window; active_window = window->display->expected_focus_window; - if (meta_prefs_get_disable_workarounds ()) + if (meta_prefs_get_disable_workarounds () || + !meta_prefs_get_raise_on_click ()) { meta_topic (META_DEBUG_STACK, "%s sent an xconfigure stacking request; this is " @@ -7156,6 +7162,9 @@ meta_window_handle_mouse_grab_op_event (MetaWindow *window, switch (event->type) { case ButtonRelease: + meta_display_check_threshold_reached (window->display, + event->xbutton.x_root, + event->xbutton.y_root); /* If the user was snap moving then ignore the button release * because they may have let go of shift before releasing the * mouse button and they almost certainly do not want a @@ -7184,6 +7193,9 @@ meta_window_handle_mouse_grab_op_event (MetaWindow *window, break; case MotionNotify: + meta_display_check_threshold_reached (window->display, + event->xmotion.x_root, + event->xmotion.y_root); if (meta_grab_op_is_moving (window->display->grab_op)) { if (event->xmotion.root == window->screen->xroot) @@ -7680,8 +7692,6 @@ meta_window_begin_grab_op (MetaWindow *window, grab_start_serial = XNextRequest (window->display->xdisplay); - meta_window_raise (window); - warp_grab_pointer (window, op, &x, &y);