changeset 91630:f3b50ee54418

(x_detect_focus_change): Handle embed client message. (handle_one_xevent): Ditto. (handle_one_xevent): If embedded and we get a button press/release, request focus. (xembed_set_info, xembed_send_message): New functions. (x_make_frame_visible): Call xembed_set_info if embedded. (x_make_frame_invisible): Call xembed_set_info if embedded. (x_term_init): Initialize Xatom_XEMBED. (x_make_frame_visible): Check for FRAME_X_EMBEDDED_P also. (x_iconify_frame): Ditto.
author Jan Djärv <jan.h.d@swipnet.se>
date Thu, 07 Feb 2008 14:07:35 +0000
parents d2d6b0b017fa
children bcad1e8fbfa2
files src/xterm.c
diffstat 1 files changed, 94 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/src/xterm.c	Thu Feb 07 14:07:00 2008 +0000
+++ b/src/xterm.c	Thu Feb 07 14:07:35 2008 +0000
@@ -3610,6 +3610,15 @@
 			FOCUS_IMPLICIT : FOCUS_EXPLICIT),
 		       dpyinfo, frame, bufp);
       break;
+
+    case ClientMessage:
+      if (event->xclient.message_type == dpyinfo->Xatom_XEMBED)
+	{
+	  enum xembed_message msg = event->xclient.data.l[1];
+	  x_focus_changed ((msg == XEMBED_FOCUS_IN ? FocusIn : FocusOut),
+			   FOCUS_EXPLICIT, dpyinfo, frame, bufp);
+	}
+      break;
     }
 }
 
@@ -6201,6 +6210,18 @@
           }
 #endif /* USE_TOOLKIT_SCROLL_BARS */
 
+	/* XEmbed messages from the embedder (if any).  */
+        if (event.xclient.message_type
+	    == dpyinfo->Xatom_XEMBED)
+          {
+	    enum xembed_message msg = event.xclient.data.l[1];
+	    if (msg == XEMBED_FOCUS_IN || msg == XEMBED_FOCUS_OUT)
+	      x_detect_focus_change (dpyinfo, &event, &inev.ie);
+
+	    *finish = X_EVENT_GOTO_OUT;
+            goto done;
+          }
+
 	f = x_any_window_to_frame (dpyinfo, event.xclient.window);
 	if (!f)
 	  goto OTHER;
@@ -7086,6 +7107,9 @@
                   else
                     construct_mouse_click (&inev.ie, &event.xbutton, f);
                 }
+            if (FRAME_X_EMBEDDED_P (f))
+              xembed_send_message (f, event.xbutton.time,
+                                   XEMBED_REQUEST_FOCUS, 0, 0, 0);
           }
         else
           {
@@ -9285,6 +9309,51 @@
     x_lower_frame (f);
 }
 
+/* XEmbed implementation.  */
+
+void
+xembed_set_info (f, flags)
+     struct frame *f;
+     enum xembed_info flags;
+{
+  Atom atom;
+  unsigned long data[2];
+
+  atom = XInternAtom (FRAME_X_DISPLAY (f), "_XEMBED_INFO", False);
+
+  data[0] = XEMBED_VERSION;
+  data[1] = flags;
+
+  XChangeProperty (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), atom, atom,
+		   32, PropModeReplace, (unsigned char *) data, 2);
+}
+
+void
+xembed_send_message (f, time, message, detail, data1, data2)
+     struct frame *f;
+     Time time;
+     enum xembed_message message;
+     long detail;
+     long data1;
+     long data2;
+{
+  XEvent event;
+
+  event.xclient.type = ClientMessage;
+  event.xclient.window = FRAME_X_OUTPUT (f)->parent_desc;
+  event.xclient.message_type = FRAME_X_DISPLAY_INFO (f)->Xatom_XEMBED;
+  event.xclient.format = 32;
+  event.xclient.data.l[0] = time;
+  event.xclient.data.l[1] = message;
+  event.xclient.data.l[2] = detail;
+  event.xclient.data.l[3] = data1;
+  event.xclient.data.l[4] = data2;
+
+  XSendEvent (FRAME_X_DISPLAY (f), FRAME_X_OUTPUT (f)->parent_desc,
+	      False, NoEventMask, &event);
+  XSync (FRAME_X_DISPLAY (f), False);
+}
+
 /* Change of visibility.  */
 
 /* This tries to wait until the frame is really visible.
@@ -9317,6 +9386,7 @@
 	 if we get to x_make_frame_visible a second time
 	 before the window gets really visible.  */
       if (! FRAME_ICONIFIED_P (f)
+	  && ! FRAME_X_EMBEDDED_P (f)
 	  && ! f->output_data.x->asked_for_visible)
 	x_set_offset (f, f->left_pos, f->top_pos, 0);
 
@@ -9325,14 +9395,22 @@
       if (! EQ (Vx_no_window_manager, Qt))
 	x_wm_set_window_state (f, NormalState);
 #ifdef USE_X_TOOLKIT
-      /* This was XtPopup, but that did nothing for an iconified frame.  */
-      XtMapWidget (f->output_data.x->widget);
+      if (FRAME_X_EMBEDDED_P (f))
+	xembed_set_info (f, XEMBED_MAPPED);
+      else
+	{
+	  /* This was XtPopup, but that did nothing for an iconified frame.  */
+	  XtMapWidget (f->output_data.x->widget);
+	}
 #else /* not USE_X_TOOLKIT */
 #ifdef USE_GTK
       gtk_widget_show_all (FRAME_GTK_OUTER_WIDGET (f));
       gtk_window_deiconify (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)));
 #else
-      XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
+      if (FRAME_X_EMBEDDED_P (f))
+	xembed_set_info (f, XEMBED_MAPPED);
+      else
+	XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
 #endif /* not USE_GTK */
 #endif /* not USE_X_TOOLKIT */
 #if 0 /* This seems to bring back scroll bars in the wrong places
@@ -9373,7 +9451,9 @@
        because the window manager may choose the position
        and we don't want to override it.  */
 
-    if (! FRAME_VISIBLE_P (f) && ! FRAME_ICONIFIED_P (f)
+    if (! FRAME_VISIBLE_P (f)
+	&& ! FRAME_ICONIFIED_P (f)
+	&& ! FRAME_X_EMBEDDED_P (f)
 	&& f->win_gravity == NorthWestGravity
 	&& previously_visible)
       {
@@ -9484,6 +9564,10 @@
   if (FRAME_GTK_OUTER_WIDGET (f))
     gtk_widget_hide (FRAME_GTK_OUTER_WIDGET (f));
   else
+#else
+  if (FRAME_X_EMBEDDED_P (f))
+    xembed_set_info (f, 0);
+  else
 #endif
   {
 
@@ -9588,7 +9672,9 @@
 
   /* Make sure the X server knows where the window should be positioned,
      in case the user deiconifies with the window manager.  */
-  if (! FRAME_VISIBLE_P (f) && !FRAME_ICONIFIED_P (f))
+  if (! FRAME_VISIBLE_P (f)
+      && ! FRAME_ICONIFIED_P (f)
+      && ! FRAME_X_EMBEDDED_P (f))
     x_set_offset (f, f->left_pos, f->top_pos, 0);
 
   /* Since we don't know which revision of X we're running, we'll use both
@@ -11399,6 +11485,9 @@
   dpyinfo->Xatom_Scrollbar = XInternAtom (dpyinfo->display, "SCROLLBAR",
 					  False);
 
+  dpyinfo->Xatom_XEMBED = XInternAtom (dpyinfo->display, "_XEMBED",
+				       False);
+
   dpyinfo->cut_buffers_initialized = 0;
 
   dpyinfo->x_dnd_atoms_size = 8;