Re: [dev] Bug when unfocusing/focusing GTK3 windows

From: Eckehard Berns <ecki-suckless_AT_ecki.to>
Date: Mon, 20 Aug 2012 11:06:35 +0200

On Fri, Aug 17, 2012 at 03:53:22PM +0200, Eckehard Berns wrote:
> I'll try things at home and maybe I find another workaround.

It was just to hot here over the weekend to do anything productive.

I looked into this again today and could see that GDK just doesn't send
any focus related events any more after the toplevel GTK window has a
flag called has_pointer_focus set. GTK on the other hand doesn't think
it has the focus if a flag called has_focus isn't set.

I found bug reports that indicate that GTK2 also had problems regarding
has_focus and has_pointer_focus in 2005 or so. Now they introduced
something similar with GTK3... Makes me wonder what has_pointer_focus
is good for anyway.

I don't know if this is the best way of dealing with the situation, but
the following patch to gtk+-3.4.4 seems to fix it for me. I haven't tried
it with xombrero yet (webkitgtk is still compiling in the background - my
machine at work is pretty old).

--- gtk+-3.4.4.orig/gdk/x11/gdkdevicemanager-core-x11.c 2012-07-15 17:48:47.000000000 +0200
+++ gtk+-3.4.4/gdk/x11/gdkdevicemanager-core-x11.c 2012-08-20 10:43:58.824103715 +0200
_AT_@ -802,9 +802,9 @@ _gdk_device_manager_core_handle_focus (G
                                        int detail,
                                        int mode)
 {
   GdkToplevelX11 *toplevel;
- gboolean had_focus;
+ gboolean has_focus, had_focus;
 
   g_return_if_fail (GDK_IS_WINDOW (window));
   g_return_if_fail (GDK_IS_DEVICE (device));
   g_return_if_fail (source_device == NULL || GDK_IS_DEVICE (source_device));
_AT_@ -822,9 +822,9 @@ _gdk_device_manager_core_handle_focus (G
 
   if (toplevel->focus_window == original)
     return;
 
- had_focus = HAS_FOCUS (toplevel);
+ had_focus = toplevel->has_focus | (toplevel->has_pointer_focus << 1);
 
   switch (detail)
     {
     case NotifyAncestor:
_AT_@ -869,9 +869,11 @@ _gdk_device_manager_core_handle_focus (G
     default:
       break;
     }
 
- if (HAS_FOCUS (toplevel) != had_focus)
+ has_focus = toplevel->has_focus | (toplevel->has_pointer_focus << 1);
+
+ if (has_focus != had_focus)
     {
       GdkEvent *event;
 
       event = gdk_event_new (GDK_FOCUS_CHANGE);

-- 
Eckehard Berns
Received on Mon Aug 20 2012 - 11:06:35 CEST

This archive was generated by hypermail 2.3.0 : Mon Aug 20 2012 - 11:12:04 CEST