diff --git a/ChangeLog b/ChangeLog index 6fc5a1080..df35791f6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2002-01-05 Havoc Pennington + + GTK 1.2 plug/socket clients still broken, don't know why. + + * src/screen.c (meta_screen_new): select focus change on root + window, for debugging + + * src/display.c (event_callback): when unfocusing, use + no_focus_window to hold the focus + + * src/display.h (struct _MetaDisplay): have a no_focus_window to + hold the focus when we don't want to have anything focused. + Then we can avoid confusing focusing-the-frame stuff. + + * src/window.c (meta_window_notify_focus): improve some debug spew + (meta_window_notify_focus): add hack from WindowMaker to ignore + focus in events with detail > NotifyNonlinearVirtual + 2002-01-04 Havoc Pennington * src/display.c (event_callback): don't lower docks when a grab diff --git a/src/display.c b/src/display.c index b98a0e809..28a627e6d 100644 --- a/src/display.c +++ b/src/display.c @@ -235,7 +235,8 @@ meta_display_open (const char *name) * created in screen_new */ display->leader_window = None; - + display->no_focus_window = None; + screens = NULL; #if 0 /* disable multihead pending GTK support */ @@ -863,7 +864,7 @@ event_callback (XEvent *event, meta_verbose ("Unsetting focus from %s due to LeaveNotify\n", window->desc); XSetInputFocus (display->xdisplay, - PointerRoot, + display->no_focus_window, RevertToPointerRoot, event->xcrossing.time); } @@ -882,7 +883,34 @@ event_callback (XEvent *event, case FocusIn: case FocusOut: if (window) - meta_window_notify_focus (window, event); + { + meta_window_notify_focus (window, event); + } + else if (event->xany.window == display->no_focus_window) + { + meta_topic (META_DEBUG_FOCUS, + "Focus %s event received on no_focus_window 0x%lx " + "mode %s detail %s\n", + event->type == FocusIn ? "in" : + event->type == FocusOut ? "out" : + "???", + event->xany.window, + meta_focus_mode_to_string (event->xfocus.mode), + meta_focus_detail_to_string (event->xfocus.mode)); + } + else if (meta_display_screen_for_root (display, + event->xany.window) != NULL) + { + meta_topic (META_DEBUG_FOCUS, + "Focus %s event received on root window 0x%lx " + "mode %s detail %s\n", + event->type == FocusIn ? "in" : + event->type == FocusOut ? "out" : + "???", + event->xany.window, + meta_focus_mode_to_string (event->xfocus.mode), + meta_focus_detail_to_string (event->xfocus.mode)); + } break; case KeymapNotify: break; @@ -1203,22 +1231,23 @@ event_get_time (MetaDisplay *display, } } - -static const char* -focus_detail (int d) +const char* +meta_focus_detail_to_string (int d) { const char *detail = "???"; switch (d) { + /* We are an ancestor in the A<->B focus change relationship */ case NotifyAncestor: detail = "NotifyAncestor"; break; case NotifyDetailNone: detail = "NotifyDetailNone"; break; + /* We are a descendant in the A<->B focus change relationship */ case NotifyInferior: detail = "NotifyInferior"; - break; + break; case NotifyNonlinear: detail = "NotifyNonlinear"; break; @@ -1239,8 +1268,8 @@ focus_detail (int d) return detail; } -static const char* -focus_mode (int m) +const char* +meta_focus_mode_to_string (int m) { const char *mode = "???"; switch (m) @@ -1254,6 +1283,14 @@ focus_mode (int m) case NotifyUngrab: mode = "NotifyUngrab"; break; + /* not sure any X implementations are missing this, but + * it seems to be absent from some docs. + */ +#ifdef NotifyWhileGrabbed + case NotifyWhileGrabbed: + mode = "NotifyWhileGrabbed"; + break; +#endif } return mode; @@ -1325,14 +1362,14 @@ meta_spew_event (MetaDisplay *display, case FocusIn: name = "FocusIn"; extra = g_strdup_printf ("detail: %s mode: %s\n", - focus_detail (event->xfocus.detail), - focus_mode (event->xfocus.mode)); + meta_focus_detail_to_string (event->xfocus.detail), + meta_focus_mode_to_string (event->xfocus.mode)); break; case FocusOut: name = "FocusOut"; extra = g_strdup_printf ("detail: %s mode: %s\n", - focus_detail (event->xfocus.detail), - focus_mode (event->xfocus.mode)); + meta_focus_detail_to_string (event->xfocus.detail), + meta_focus_mode_to_string (event->xfocus.mode)); break; case KeymapNotify: name = "KeymapNotify"; diff --git a/src/display.h b/src/display.h index cd4a367e8..51f4abada 100644 --- a/src/display.h +++ b/src/display.h @@ -124,6 +124,11 @@ struct _MetaDisplay GSList *error_traps; int server_grab_count; + /* This window holds the focus when we don't want to focus + * any actual clients + */ + Window no_focus_window; + /* for double click */ int double_click_time; Time last_button_time; @@ -215,4 +220,8 @@ void meta_display_unshow_desktop (MetaDisplay *display); guint32 meta_display_get_current_time (MetaDisplay *display); +/* utility goo */ +const char* meta_focus_mode_to_string (int m); +const char* meta_focus_detail_to_string (int d); + #endif diff --git a/src/frames.c b/src/frames.c index 0222562c4..ba81fcae8 100644 --- a/src/frames.c +++ b/src/frames.c @@ -1033,7 +1033,7 @@ meta_frames_button_press_event (GtkWidget *widget, meta_core_user_raise (gdk_display, frame->xwindow); meta_topic (META_DEBUG_FOCUS, - "Focusing frame 0x%lx due to button 1 press\n", + "Focusing window with frame 0x%lx due to button 1 press\n", frame->xwindow); meta_core_user_focus (gdk_display, frame->xwindow, diff --git a/src/screen.c b/src/screen.c index 5168d1491..01e4b8fd8 100644 --- a/src/screen.c +++ b/src/screen.c @@ -183,7 +183,8 @@ meta_screen_new (MetaDisplay *display, SubstructureRedirectMask | SubstructureNotifyMask | ColormapChangeMask | PropertyChangeMask | LeaveWindowMask | EnterWindowMask | - ButtonPressMask | ButtonReleaseMask); + ButtonPressMask | ButtonReleaseMask | + FocusChangeMask); if (meta_error_trap_pop (display) != Success) { meta_warning (_("Screen %d on display '%s' already has a window manager\n"), @@ -211,6 +212,16 @@ meta_screen_new (MetaDisplay *display, screen->xroot, -100, -100, 1, 1, 0, 0, 0); + if (display->no_focus_window == None) + { + display->no_focus_window = XCreateSimpleWindow (display->xdisplay, + screen->xroot, + -100, -100, 1, 1, 0, 0, 0); + XSelectInput (display->xdisplay, display->no_focus_window, + FocusChangeMask); + XMapWindow (display->xdisplay, display->no_focus_window); + } + set_wm_icon_size_hint (screen); set_supported_hint (screen); diff --git a/src/window.c b/src/window.c index 8954cd2e8..ea59ee2c1 100644 --- a/src/window.c +++ b/src/window.c @@ -128,6 +128,13 @@ meta_window_new (MetaDisplay *display, Window xwindow, meta_verbose ("Attempting to manage 0x%lx\n", xwindow); + if (xwindow == display->no_focus_window) + { + meta_verbose ("Not managing no_focus_window 0x%lx\n", + xwindow); + return NULL; + } + /* Grab server */ meta_display_grab (display); @@ -2042,8 +2049,9 @@ meta_window_focus (MetaWindow *window, if (window->display->grab_window && window->display->grab_window->all_keys_grabbed) { - meta_verbose ("Current focus window %s has global keygrab, not focusing window %s after all\n", - window->display->grab_window->desc, window->desc); + meta_topic (META_DEBUG_FOCUS, + "Current focus window %s has global keygrab, not focusing window %s after all\n", + window->display->grab_window->desc, window->desc); return; } @@ -2061,7 +2069,8 @@ meta_window_focus (MetaWindow *window, { if (window->frame) { - meta_verbose ("Focusing frame of %s\n", window->desc); + meta_topic (META_DEBUG_FOCUS, + "Focusing frame of %s\n", window->desc); XSetInputFocus (window->display->xdisplay, window->frame->xwindow, RevertToPointerRoot, @@ -2074,6 +2083,9 @@ meta_window_focus (MetaWindow *window, if (window->input) { + meta_topic (META_DEBUG_FOCUS, + "Calling XSetInputFocus() on client window %s since input = true\n", + window->desc); XSetInputFocus (window->display->xdisplay, window->xwindow, RevertToPointerRoot, @@ -2082,6 +2094,9 @@ meta_window_focus (MetaWindow *window, if (window->take_focus) { + meta_topic (META_DEBUG_FOCUS, + "Sending WM_TAKE_FOCUS to %s since take_focus = true\n", + window->desc); meta_window_send_icccm_message (window, window->display->atom_wm_take_focus, timestamp); @@ -2653,16 +2668,29 @@ meta_window_notify_focus (MetaWindow *window, * user expects once a keybinding is used. */ meta_topic (META_DEBUG_FOCUS, - "Focus %s event received\n", + "Focus %s event received on %s 0x%lx (%s) " + "mode %s detail %s\n", event->type == FocusIn ? "in" : event->type == FocusOut ? "out" : event->type == UnmapNotify ? "unmap" : - "???"); + "???", + window->desc, event->xany.window, + event->xany.window == window->xwindow ? + "client window" : + (window->frame && event->xany.window == window->frame->xwindow) ? + "frame window" : + "unknown window", + event->type != UnmapNotify ? + meta_focus_mode_to_string (event->xfocus.mode) : "n/a", + event->type != UnmapNotify ? + meta_focus_detail_to_string (event->xfocus.mode) : "n/a"); if ((event->type == FocusIn || event->type == FocusOut) && (event->xfocus.mode == NotifyGrab || - event->xfocus.mode == NotifyUngrab)) + event->xfocus.mode == NotifyUngrab || + /* From WindowMaker */ + event->xfocus.detail > NotifyNonlinearVirtual)) { meta_topic (META_DEBUG_FOCUS, "Ignoring focus event generated by a grab\n");