unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Timo Savola <timo.savola@iki.fi>
Subject: XEmbed patch
Date: Wed, 01 Feb 2006 21:09:19 +0200	[thread overview]
Message-ID: <1138820959.9429.54.camel@localhost.localdomain> (raw)

[-- Attachment #1: Type: text/plain, Size: 1241 bytes --]

Here is a patch (against CVS HEAD) that adds XEmbed support for all X
flavours and makes keyboard focus work for the GTK version.  It needs
the gtkplug, parentid and parent-fix patches [1].

[1] http://lists.gnu.org/archive/html/emacs-devel/2005-12/msg01558.html

Some issues:

* The current implementation is minimal although all XEmbed message
  types and parameters are enumerated in src/xterm.h.  It is not clear
  to me if the additional protocol features are feasible for Emacs or
  how to implement them.

* Emacs requests focus only when the buffer area is clicked.  It might
  be a good idea to request focus also when the menubar or the toolbar
  is clicked.

* I'm not sure if src/xterm.h and src/xterm.c are the correct files for
  the XEmbed enums and utility functions.

* The implementation of XEMBED_FOCUS_{IN,OUT} seems clumsy.

* I tested only --with-x and --with-gtk configurations.

* The keyboard focus works correctly (at least) under Metacity, but
  there seems to be a problem when using the Ion 3 window manager.  The
  original GtkPlug version could only be used with Ion because it seems
  to treat embedded windows like top-levels as far as focus is
  concerned; the embedder application is not in charge.

timo


[-- Attachment #2: emacs-xembed.patch --]
[-- Type: text/x-patch, Size: 6386 bytes --]

Wed Feb  1 17:55:17 EET 2006  Timo Savola <timo.savola@iki.fi>
  * xembed
diff -rN -u old-work/src/xterm.c new-work-1/src/xterm.c
--- old-work/src/xterm.c	2006-02-01 17:56:27.055682312 +0200
+++ new-work-1/src/xterm.c	2006-02-01 17:45:11.000000000 +0200
@@ -3284,6 +3284,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;
     }
 }
 
@@ -5836,6 +5845,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)
@@ -6734,6 +6755,10 @@
 		      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
@@ -8535,6 +8560,51 @@
     x_lower_frame (f);
 }
 \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_X_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);
+}
+\f
 /* Change of visibility.  */
 
 /* This tries to wait until the frame is really visible.
@@ -8575,14 +8645,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
@@ -8734,6 +8812,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
   {
 #ifdef HAVE_X11R4
@@ -10479,6 +10561,9 @@
   dpyinfo->Xatom_Scrollbar = XInternAtom (dpyinfo->display, "SCROLLBAR",
 					  False);
 
+  dpyinfo->Xatom_XEMBED = XInternAtom (dpyinfo->display, "_XEMBED",
+				       False);
+
   dpyinfo->cut_buffers_initialized = 0;
 
   connection = ConnectionNumber (dpyinfo->display);
diff -rN -u old-work/src/xterm.h new-work-1/src/xterm.h
--- old-work/src/xterm.h	2006-02-01 17:56:27.047683528 +0200
+++ new-work-1/src/xterm.h	2006-02-01 17:54:32.000000000 +0200
@@ -327,6 +327,9 @@
   /* Atom used in toolkit scroll bar client messages.  */
   Atom Xatom_Scrollbar;
 
+  /* Atom used in XEmbed client messages.  */
+  Atom Xatom_XEMBED;
+
 #ifdef MULTI_KBOARD
   struct kboard *kboard;
 #endif
@@ -1091,6 +1094,66 @@
 extern int x_session_have_connection P_ ((void));
 #endif
 
+/* XEmbed implementation.  */
+
+#define XEMBED_VERSION 0
+
+enum xembed_info
+  {
+    XEMBED_MAPPED = 1 << 0
+  };
+
+enum xembed_message
+  {
+    XEMBED_EMBEDDED_NOTIFY        = 0,
+    XEMBED_WINDOW_ACTIVATE        = 1,
+    XEMBED_WINDOW_DEACTIVATE      = 2,
+    XEMBED_REQUEST_FOCUS          = 3,
+    XEMBED_FOCUS_IN               = 4,
+    XEMBED_FOCUS_OUT              = 5,
+    XEMBED_FOCUS_NEXT             = 6,
+    XEMBED_FOCUS_PREV             = 7,
+
+    XEMBED_MODALITY_ON            = 10,
+    XEMBED_MODALITY_OFF           = 11,
+    XEMBED_REGISTER_ACCELERATOR   = 12,
+    XEMBED_UNREGISTER_ACCELERATOR = 13,
+    XEMBED_ACTIVATE_ACCELERATOR   = 14
+  };
+
+enum xembed_focus
+  {
+    XEMBED_FOCUS_CURRENT = 0,
+    XEMBED_FOCUS_FIRST   = 1,
+    XEMBED_FOCUS_LAST    = 2
+  };
+
+enum xembed_modifier
+  {
+    XEMBED_MODIFIER_SHIFT   = 1 << 0,
+    XEMBED_MODIFIER_CONTROL = 1 << 1,
+    XEMBED_MODIFIER_ALT     = 1 << 2,
+    XEMBED_MODIFIER_SUPER   = 1 << 3,
+    XEMBED_MODIFIER_HYPER   = 1 << 4
+  };
+
+enum xembed_accelerator
+  {
+    XEMBED_ACCELERATOR_OVERLOADED = 1 << 0
+  };
+
+/* Defined in xterm.c */
+
+extern void xembed_set_info P_ ((struct frame *f, enum xembed_info flags));
+extern void xembed_send_message P_ ((struct frame *f, Time time,
+				     enum xembed_message message,
+				     long detail, long data1, long data2));
+
+/* Is the frame embedded into another application? */
+
+#define FRAME_X_EMBEDDED_P(f) (FRAME_X_OUTPUT(f)->explicit_parent != 0)
+
+
 #define FONT_TYPE_FOR_UNIBYTE(font, ch) 0
 #define FONT_TYPE_FOR_MULTIBYTE(font, ch) 0
 


[-- Attachment #3: Type: text/plain, Size: 142 bytes --]

_______________________________________________
Emacs-devel mailing list
Emacs-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-devel

             reply	other threads:[~2006-02-01 19:09 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-02-01 19:09 Timo Savola [this message]
2006-02-04 18:27 ` XEmbed patch Richard M. Stallman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1138820959.9429.54.camel@localhost.localdomain \
    --to=timo.savola@iki.fi \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).