From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Timo Savola Newsgroups: gmane.emacs.devel Subject: XEmbed patch Date: Wed, 01 Feb 2006 21:09:19 +0200 Message-ID: <1138820959.9429.54.camel@localhost.localdomain> NNTP-Posting-Host: main.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-ym3JSpDNb/9E6idQIgpd" X-Trace: sea.gmane.org 1138832977 2940 80.91.229.2 (1 Feb 2006 22:29:37 GMT) X-Complaints-To: usenet@sea.gmane.org NNTP-Posting-Date: Wed, 1 Feb 2006 22:29:37 +0000 (UTC) Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Wed Feb 01 23:29:36 2006 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by ciao.gmane.org with esmtp (Exim 4.43) id 1F4QO4-0003hn-2d for ged-emacs-devel@m.gmane.org; Wed, 01 Feb 2006 23:23:41 +0100 Original-Received: from localhost ([127.0.0.1] helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1F4QQH-0003Sb-SI for ged-emacs-devel@m.gmane.org; Wed, 01 Feb 2006 17:25:57 -0500 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1F4NXq-0000vt-Ei for emacs-devel@gnu.org; Wed, 01 Feb 2006 14:21:34 -0500 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1F4NUq-0000EQ-R9 for emacs-devel@gnu.org; Wed, 01 Feb 2006 14:18:30 -0500 Original-Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1F4NPN-0007dp-QP for emacs-devel@gnu.org; Wed, 01 Feb 2006 14:12:50 -0500 Original-Received: from [213.243.153.35] (helo=smtp2.pp.htv.fi) by monty-python.gnu.org with esmtp (Exim 4.52) id 1F4NNu-0005ts-5r; Wed, 01 Feb 2006 14:11:18 -0500 Original-Received: from [192.168.1.100] (cs78235208.pp.htv.fi [62.78.235.208]) by smtp2.pp.htv.fi (Postfix) with ESMTP id 33FF9296BF8; Wed, 1 Feb 2006 21:09:20 +0200 (EET) Original-To: rms@gnu.org, jan.h.d@swipnet.se, emacs-devel@gnu.org X-Mailer: Evolution 2.4.1 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:49885 Archived-At: --=-ym3JSpDNb/9E6idQIgpd Content-Type: text/plain Content-Transfer-Encoding: 7bit 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 --=-ym3JSpDNb/9E6idQIgpd Content-Disposition: attachment; filename=emacs-xembed.patch Content-Type: text/x-patch; name=emacs-xembed.patch; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Wed Feb 1 17:55:17 EET 2006 Timo Savola * 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); } +/* 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); +} + /* 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 --=-ym3JSpDNb/9E6idQIgpd Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Emacs-devel mailing list Emacs-devel@gnu.org http://lists.gnu.org/mailman/listinfo/emacs-devel --=-ym3JSpDNb/9E6idQIgpd--