diff --git a/ChangeLog b/ChangeLog index 023e53860..cb9408ffc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2001-12-10 Havoc Pennington + + * src/screen.c (meta_screen_foreach_window): fix broken + "tmp = tmp->data" + + Implement do-not-pass-thru-click for click-to-focus mode. + + * src/screen.c (update_focus_mode): when focus mode changes, + update all the window grabs + + * src/display.c (meta_display_grab_unfocused_window_buttons): + implement grabbing button 1 on client area of unfocused + click-to-focus windows + + * src/window.c (meta_window_update_unfocused_button_grabs): update + whether we're grabbing unmodified button 1 on client area + according to focus state and focus mode + (meta_window_new): start out with proper grab state + 2001-12-10 Havoc Pennington * src/menu.c (meta_window_menu_new): don't do mnemonics for diff --git a/src/display.c b/src/display.c index 06de0eccf..d0e604935 100644 --- a/src/display.c +++ b/src/display.c @@ -704,11 +704,13 @@ event_callback (XEvent *event, if (g_getenv ("METACITY_DEBUG_BUTTON_GRABS")) grab_mask |= ControlMask; - if ((event->xbutton.state & grab_mask) == 0) + if (!window->unfocused_buttons_grabbed && + (event->xbutton.state & grab_mask) == 0) { ; /* nothing, not getting event from our button grabs, * rather from a client that just let button presses - * pass through to our frame + * pass through to our frame, and we don't have + * the click-to-focus first-click-to-raise grab */ } else if (event->xbutton.button == 1) @@ -716,7 +718,11 @@ event_callback (XEvent *event, meta_window_raise (window); meta_window_focus (window, event->xbutton.time); - begin_move = TRUE; + /* you can move on alt-click but not on + * first-unmodified-click + */ + if (!window->unfocused_buttons_grabbed) + begin_move = TRUE; } else if (event->xbutton.button == 2) { @@ -1737,6 +1743,50 @@ meta_display_ungrab_window_buttons (MetaDisplay *display, } } +/* Grab buttons we only grab while unfocused in click-to-focus mode */ +void +meta_display_grab_unfocused_window_buttons (MetaDisplay *display, + Window xwindow) +{ + /* Grab button 1 for activating unfocused windows */ + meta_verbose ("Grabbing unfocused window buttons for 0x%lx\n", xwindow); + + /* FIXME If we ignored errors here instead of spewing, we could + * put one big error trap around the loop and avoid a bunch of + * XSync() + */ + + { + int i = 1; + while (i < 2) + { + meta_change_button_grab (display, + xwindow, + TRUE, i, 0); + + ++i; + } + } +} + +void +meta_display_ungrab_unfocused_window_buttons (MetaDisplay *display, + Window xwindow) +{ + meta_verbose ("Ungrabbing unfocused window buttons for 0x%lx\n", xwindow); + + { + int i = 1; + while (i < 2) + { + meta_change_button_grab (display, xwindow, + FALSE, i, 0); + + ++i; + } + } +} + void meta_display_increment_event_serial (MetaDisplay *display) { diff --git a/src/display.h b/src/display.h index 0074b9cbf..6416cffe6 100644 --- a/src/display.h +++ b/src/display.h @@ -195,6 +195,12 @@ void meta_display_grab_window_buttons (MetaDisplay *display, void meta_display_ungrab_window_buttons (MetaDisplay *display, Window xwindow); +void meta_display_grab_unfocused_window_buttons (MetaDisplay *display, + Window xwindow); +void meta_display_ungrab_unfocused_window_buttons (MetaDisplay *display, + Window xwindow); + + /* make a request to ensure the event serial has changed */ void meta_display_increment_event_serial (MetaDisplay *display); diff --git a/src/screen.c b/src/screen.c index 5b7f655f5..cfcfaeba6 100644 --- a/src/screen.c +++ b/src/screen.c @@ -38,6 +38,7 @@ static char* get_screen_name (MetaDisplay *display, int number); static void update_num_workspaces (MetaScreen *screen); +static void update_focus_mode (MetaScreen *screen); static void prefs_changed_callback (MetaPreference pref, gpointer data); @@ -316,6 +317,10 @@ prefs_changed_callback (MetaPreference pref, { update_num_workspaces (screen); } + else if (pref == META_PREF_FOCUS_MODE) + { + update_focus_mode (screen); + } } @@ -404,7 +409,7 @@ meta_screen_foreach_window (MetaScreen *screen, (* func) (screen, window, data); } - tmp = tmp->data; + tmp = tmp->next; } g_slist_free (winlist); } @@ -540,6 +545,20 @@ update_num_workspaces (MetaScreen *screen) } } +static void +update_grabs_func (MetaScreen *screen, MetaWindow *window, + gpointer user_data) +{ + meta_window_update_unfocused_button_grabs (window); +} + + +static void +update_focus_mode (MetaScreen *screen) +{ + meta_screen_foreach_window (screen, update_grabs_func, NULL); +} + void meta_screen_set_cursor (MetaScreen *screen, MetaCursor cursor) diff --git a/src/window.c b/src/window.c index fd15a993b..bff2e8f36 100644 --- a/src/window.c +++ b/src/window.c @@ -31,6 +31,7 @@ #include "place.h" #include "session.h" #include "effects.h" +#include "prefs.h" #include @@ -303,6 +304,7 @@ meta_window_new (MetaDisplay *display, Window xwindow, window->keys_grabbed = FALSE; window->grab_on_frame = FALSE; window->all_keys_grabbed = FALSE; + window->unfocused_buttons_grabbed = FALSE; window->withdrawn = FALSE; window->initial_workspace_set = FALSE; window->calc_placement = FALSE; @@ -421,6 +423,7 @@ meta_window_new (MetaDisplay *display, Window xwindow, meta_window_grab_keys (window); meta_display_grab_window_buttons (window->display, window->xwindow); + meta_window_update_unfocused_button_grabs (window); /* For the workspace, first honor hints, * if that fails put transients with parents, @@ -2021,6 +2024,53 @@ meta_window_focus (MetaWindow *window, } } +void +meta_window_update_unfocused_button_grabs (MetaWindow *window) +{ + /* Grab buttons if we're unfocused and in click-to-focus mode, + * ungrab otherwise + */ + if (window->unfocused_buttons_grabbed) + { + if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK) + { + if (window->has_focus) + { + /* Focused so undo grab */ + meta_verbose ("Ungrabbing on focused window %s since mode is click-to-focus\n", + window->desc); + meta_display_ungrab_unfocused_window_buttons (window->display, + window->xwindow); + window->unfocused_buttons_grabbed = FALSE; + } + } + else + { + /* Not in click-to-focus so undo grab */ + meta_verbose ("Ungrabbing on window %s since mode is not click-to-focus\n", + window->desc); + meta_display_ungrab_unfocused_window_buttons (window->display, + window->xwindow); + window->unfocused_buttons_grabbed = FALSE; + } + } + else + { + if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK) + { + if (!window->has_focus) + { + /* Not focused so grab */ + meta_verbose ("Grabbing on unfocused window %s since mode is click-to-focus\n", + window->desc); + meta_display_grab_unfocused_window_buttons (window->display, + window->xwindow); + window->unfocused_buttons_grabbed = TRUE; + } + } + } +} + void meta_window_change_workspace (MetaWindow *window, MetaWorkspace *workspace) @@ -2609,6 +2659,7 @@ meta_window_notify_focus (MetaWindow *window, window->has_focus = TRUE; if (window->frame) meta_frame_queue_draw (window->frame); + meta_window_update_unfocused_button_grabs (window); } else if (event->type == FocusOut || event->type == UnmapNotify) @@ -2624,6 +2675,7 @@ meta_window_notify_focus (MetaWindow *window, window->has_focus = FALSE; if (window->frame) meta_frame_queue_draw (window->frame); + meta_window_update_unfocused_button_grabs (window); } /* Now set _NET_ACTIVE_WINDOW hint */ diff --git a/src/window.h b/src/window.h index dd89edd13..edc528de3 100644 --- a/src/window.h +++ b/src/window.h @@ -173,6 +173,9 @@ struct _MetaWindow guint keys_grabbed : 1; /* normal keybindings grabbed */ guint grab_on_frame : 1; /* grabs are on the frame */ guint all_keys_grabbed : 1; /* AnyKey grabbed */ + + /* Used by display.c */ + guint unfocused_buttons_grabbed : 1; /* have the unmodified buttons grabbed */ /* Set if the reason for unmanaging the window is that * it was withdrawn @@ -303,6 +306,7 @@ void meta_window_focus (MetaWindow *window, void meta_window_raise (MetaWindow *window); void meta_window_lower (MetaWindow *window); +void meta_window_update_unfocused_button_grabs (MetaWindow *window); /* Sends a client message */ void meta_window_send_icccm_message (MetaWindow *window,