[PATCH] Fix not sending XEMBED_REQUEST_FOCUS

Olivier Brunel jjk at jjacky.com
Sat Feb 22 17:18:04 CET 2014


When using -embed and the window is clicked, if we didn't have the focus
we should send XEMBED_REQUEST_FOCUS to the embedder to get it (i.e. it
will respond by sending us a XEMBED_FOCUS_IN).

Signed-off-by: Olivier Brunel <jjk at jjacky.com>
---
Hi,

I'm working on a GTK3 app and I want to embed an urxvt window. Basically
everything works as expected, except that while I can give focus to urxvt using
keyboard (e.g. pressing Tab), clicking on urxvt's (embedded) window would not
focus it -- a majorly annoying thing as you can imagine.

After looking into it, I believe urxvt might be at fault, in that it never sends
XEMBED_REQUEST_FOCUS, even though (I believe) it should do so in situations like
the one I described.

I'm not really familiar with urxvt's code base so this might not be the best way
to do it, but this patch will send the XEMBED_REQUEST_FOCUS to the embeder
whenever the window is clicked and we don't have to focus.
Normal response from the embeder is to send us an XEMBED_FOCUS_IN, which GTK
does, and then everything works like a charm :)

(You can test that using the embed perl example in doc, if instead of adding the
Socket to the window, you add a box with e.g. a button and the socket, you'll
have no way of focusing the urxvt window via mouse.)

Cheers,
-jjacky

 src/command.C | 16 ++++++++++++++++
 src/init.C    |  2 +-
 src/rxvt.h    |  3 +++
 3 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/src/command.C b/src/command.C
index 542d14c..81c4c3d 100644
--- a/src/command.C
+++ b/src/command.C
@@ -1946,6 +1946,22 @@ rxvt_term::button_press (XButtonEvent &ev)
           switch (ev.button)
             {
               case Button1:
+#if ENABLE_XEMBED
+                if (this->parent_window && !focus)
+                  {
+                    XClientMessageEvent event = { 0, };
+                    dLocal (Display *, dpy);
+                    event.type = ClientMessage;
+                    event.display = dpy;
+                    event.window = this->parent_window;
+                    event.send_event = 1;
+                    event.format = 32;
+                    event.message_type = xa[XA_XEMBED];
+                    event.data.l[1] = XEMBED_REQUEST_FOCUS;
+                    XSendEvent (dpy, this->parent_window, False, 0, (XEvent *) &event);
+                  }
+#endif
+
                 /* allow meta + click to select rectangular areas */
                 /* should be done in screen.C */
 #if ENABLE_FRILLS
diff --git a/src/init.C b/src/init.C
index 95cc777..e6bcf80 100644
--- a/src/init.C
+++ b/src/init.C
@@ -1364,7 +1364,7 @@ rxvt_term::create_windows (int argc, const char *const *argv)
     {
       XWindowAttributes wattr;
 
-      parent = strtol (rs[Rs_embed], 0, 0);
+      this->parent_window = parent = strtol (rs[Rs_embed], 0, 0);
 
       if (!XGetWindowAttributes (dpy, parent, &wattr))
         rxvt_fatal ("invalid window-id specified with -embed, aborting.\n");
diff --git a/src/rxvt.h b/src/rxvt.h
index 7c2e641..696d220 100644
--- a/src/rxvt.h
+++ b/src/rxvt.h
@@ -991,6 +991,9 @@ struct TermWin_t
   GC             gc;            /* GC for drawing                           */
   rxvt_drawable *drawable;
   rxvt_fontset  *fontset[4];
+#ifdef ENABLE_XEMBED
+  long int       parent_window; /* parent window id, to send message        */
+#endif
 };
 
 /*
-- 
1.9.0





More information about the rxvt-unicode mailing list