Re: Patch for xembed updated
podarcis <[email protected]>
| Newsgroups | gmane.comp.web.dillo.devel |
|---|---|
| Message-ID | <[email protected]> |
> > When porting dillo to fltk we had to implement xembed on our own or > break support for the claws-mail plugin. > That's why we added xembed.cc. > Thank you for the infos. Keeping compatability is of course a main goal... Nevertheless I am still not really certain, what the current xembed protocol implementation does - or does *NOT*. Please have a look at the enclosed diff 'xembed_removed_demo.diff', that removes the *WHOLE* xembed protocol implementation and only keeps the window creation. Still embedding with 'tabbed' works as before. This really makes me wonder... > I would prefer a minimal fltk-based example program in the test > directory, that implements the embedder side of xembed. > It shouldn't be too hard to do (e.g. by looking at the tabbed > sources). > It would be cool if you would like to work on that. Sorry, but I don't feel able to do this proper. Looking at the xembed protocol specification makes me consider that as an extremely time-consuming task. One idea, which could make us both happy: I have again updated my patch, so that using the xembed protocol can be specified by the application. If using it (and that's the default of course) will run the current xembed code effectively unchanged. This way there should be no compatabiliy issues (The way I have designed that option is only an outline, maybe this can be done better). Only if running with xembed protocol disabled my patch comes into action. --> xembed_patch_xembed_protocol_set.diff --> dembed.cxx Cheers, Podarcis _______________________________________________ Dillo-dev mailing list [email protected] http://lists.auriga.wearlab.de/cgi-bin/mailman/listinfo/dillo-dev
xembed_removed_demo.diff
(text/x-patch, 3.2 KB)
diff -r 88ac1e8678aa src/xembed.cc
--- a/src/xembed.cc Thu Jan 03 07:47:25 2013 +0000
+++ b/src/xembed.cc Wed Jan 09 17:49:23 2013 +0100
@@ -13,101 +13,14 @@
#include <ctype.h>
#define FL_INTERNALS
-#include <FL/Fl_Window.H>
-#include <FL/Fl.H>
#include <FL/x.H>
#include "xembed.hh"
#ifdef X_PROTOCOL
-typedef enum {
- 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_GRAB_KEY = 8,
- XEMBED_UNGRAB_KEY = 9,
- XEMBED_MODALITY_ON = 10,
- XEMBED_MODALITY_OFF = 11,
-} XEmbedMessageType;
-
-void
-Xembed::setXembedInfo(unsigned long flags)
-{
- unsigned long buffer[2];
-
- Atom xembed_info_atom = XInternAtom (fl_display, "_XEMBED_INFO", false);
-
- buffer[0] = 1;
- buffer[1] = flags;
-
- XChangeProperty (fl_display,
- xid,
- xembed_info_atom, xembed_info_atom, 32,
- PropModeReplace,
- (unsigned char *)buffer, 2);
-}
-
-void
-Xembed::sendXembedEvent(uint32_t message) {
- XClientMessageEvent xclient;
-
- memset (&xclient, 0, sizeof (xclient));
- xclient.window = xid;
- xclient.type = ClientMessage;
- xclient.message_type = XInternAtom (fl_display, "_XEMBED", false);
- xclient.format = 32;
- xclient.data.l[0] = fl_event_time;
- xclient.data.l[1] = message;
-
- XSendEvent(fl_display, xid, False, NoEventMask, (XEvent *)&xclient);
- XSync(fl_display, False);
-}
-
-int
-Xembed::handle(int e) {
- if (e == FL_PUSH)
- sendXembedEvent(XEMBED_REQUEST_FOCUS);
-
- return Fl_Window::handle(e);
-}
-
-static int event_handler(int e, Fl_Window *w) {
- Atom xembed_atom = XInternAtom (fl_display, "_XEMBED", false);
-
- if (fl_xevent->type == ClientMessage) {
- if (fl_xevent->xclient.message_type == xembed_atom) {
- long message = fl_xevent->xclient.data.l[1];
-
- switch (message) {
- case XEMBED_WINDOW_ACTIVATE:
- // Force a ConfigureNotify message so fltk can get the new
- // coordinates after a move of the embedder window.
- if (w)
- w->resize(0,0, w->w(), w->h());
- break;
- case XEMBED_WINDOW_DEACTIVATE:
- break;
- default:
- break;
- }
- }
- }
-
- return Fl::handle_(e, w);
-}
-
-// TODO: Implement more XEMBED support;
-
void Xembed::show() {
createInternal(xid);
- setXembedInfo(1);
- Fl::event_dispatch(event_handler);
}
void Xembed::createInternal(uint32_t parent) {
diff -r 88ac1e8678aa src/xembed.hh
--- a/src/xembed.hh Thu Jan 03 07:47:25 2013 +0000
+++ b/src/xembed.hh Wed Jan 09 17:49:23 2013 +0100
@@ -9,15 +9,12 @@
private:
uint32_t xid;
void createInternal(uint32_t parent);
- void setXembedInfo(unsigned long flags);
- void sendXembedEvent(uint32_t message);
public:
Xembed(uint32_t xid, int _w, int _h) : Fl_Window(_w, _h) {
this->xid = xid;
};
void show();
- int handle(int event);
};
#endif
xembed_patch_xembed_protocol_set.diff
(text/x-patch, 7 KB)
diff -r 9195a2df5ca3 src/dillo.cc
--- a/src/dillo.cc Fri Jan 04 11:17:00 2013 +0100
+++ b/src/dillo.cc Wed Jan 09 18:49:22 2013 +0100
@@ -64,6 +64,7 @@
DILLO_CLI_VERSION = 1 << 3,
DILLO_CLI_LOCAL = 1 << 4,
DILLO_CLI_GEOMETRY = 1 << 5,
+ DILLO_CLI_XID_NO_XEMBED = 1 << 14,
DILLO_CLI_ERROR = 1 << 15,
} OptID;
@@ -92,6 +93,11 @@
{"-x", "--xid", 1, DILLO_CLI_XID,
" -x, --xid XID Open first Dillo window in an existing\n"
" window whose window ID is XID."},
+ {"-X", "--Xid", 1, DILLO_CLI_XID_NO_XEMBED,
+ " -X, --Xid XID Open first Dillo window in an existing\n"
+ " window whose window ID is XID.\n"
+ " This variant of -x does not use the xembed\n"
+ " protocol but handles resize itself."},
{NULL, NULL, 0, DILLO_CLI_NONE, NULL}
};
@@ -314,6 +320,7 @@
uint_t opt_id;
uint_t options_got = 0;
uint32_t xid = 0;
+ bool xembed_protocol = true;
int idx = 1;
int xpos = PREFS_GEOMETRY_DEFAULT_XPOS, ypos = PREFS_GEOMETRY_DEFAULT_YPOS,
width = PREFS_GEOMETRY_DEFAULT_WIDTH,
@@ -334,6 +341,9 @@
case DILLO_CLI_FULLWINDOW:
case DILLO_CLI_LOCAL:
break;
+ case DILLO_CLI_XID_NO_XEMBED:
+ xembed_protocol = false;
+ // continue into DILLO_CLI_XID
case DILLO_CLI_XID:
{
char *end;
@@ -445,7 +455,7 @@
fl_message_title_default("Dillo: Message");
// Create a new UI/bw pair
- BrowserWindow *bw = a_UIcmd_browser_window_new(0, 0, xid, NULL);
+ BrowserWindow *bw = a_UIcmd_browser_window_new(0, 0, xid, xembed_protocol, NULL);
/* We need this so that fl_text_extents() in dw/fltkplatform.cc can
* work when FLTK is configured without XFT and Dillo is opening
diff -r 9195a2df5ca3 src/uicmd.cc
--- a/src/uicmd.cc Fri Jan 04 11:17:00 2013 +0100
+++ b/src/uicmd.cc Wed Jan 09 18:49:22 2013 +0100
@@ -530,7 +530,8 @@
* Use style from v_ui. If non-NULL it must be of type UI*.
*/
BrowserWindow *a_UIcmd_browser_window_new(int ww, int wh,
- uint32_t xid, const void *vbw)
+ uint32_t xid, bool_t xembedProtocol,
+ const void *vbw)
{
BrowserWindow *old_bw = (BrowserWindow*)vbw;
BrowserWindow *new_bw = NULL;
@@ -544,7 +545,7 @@
}
if (xid)
- win = new Xembed(xid, ww, wh);
+ win = new Xembed(xid, ww, wh, xembedProtocol);
else if (prefs.buffered_drawing != 2)
win = new Fl_Window(ww, wh);
else
@@ -730,7 +731,7 @@
BrowserWindow *new_bw;
a_UIcmd_get_wh(bw, &w, &h);
- new_bw = a_UIcmd_browser_window_new(w, h, 0, bw);
+ new_bw = a_UIcmd_browser_window_new(w, h, 0, false, bw);
UIcmd_open_url_nbw(new_bw, url);
}
diff -r 9195a2df5ca3 src/uicmd.hh
--- a/src/uicmd.hh Fri Jan 04 11:17:00 2013 +0100
+++ b/src/uicmd.hh Wed Jan 09 18:49:22 2013 +0100
@@ -9,7 +9,9 @@
BrowserWindow *a_UIcmd_browser_window_new(int ww, int wh,
- uint32_t xid, const void *v_bw);
+ uint32_t xid,
+ bool_t xembed_protocol,
+ const void *v_bw);
BrowserWindow *a_UIcmd_get_bw_by_widget(void *v_wid);
void a_UIcmd_send_event_to_tabs_by_wid(int e, void *v_wid);
void a_UIcmd_open_urlstr(void *vbw, const char *urlstr);
diff -r 9195a2df5ca3 src/xembed.cc
--- a/src/xembed.cc Fri Jan 04 11:17:00 2013 +0100
+++ b/src/xembed.cc Wed Jan 09 18:49:22 2013 +0100
@@ -47,7 +47,7 @@
buffer[1] = flags;
XChangeProperty (fl_display,
- xid,
+ xid_,
xembed_info_atom, xembed_info_atom, 32,
PropModeReplace,
(unsigned char *)buffer, 2);
@@ -58,14 +58,14 @@
XClientMessageEvent xclient;
memset (&xclient, 0, sizeof (xclient));
- xclient.window = xid;
+ xclient.window = xid_;
xclient.type = ClientMessage;
xclient.message_type = XInternAtom (fl_display, "_XEMBED", false);
xclient.format = 32;
xclient.data.l[0] = fl_event_time;
xclient.data.l[1] = message;
- XSendEvent(fl_display, xid, False, NoEventMask, (XEvent *)&xclient);
+ XSendEvent(fl_display, xid_, False, NoEventMask, (XEvent *)&xclient);
XSync(fl_display, False);
}
@@ -77,6 +77,24 @@
return Fl_Window::handle(e);
}
+void Xembed::updateSize() {
+ // Query X11 for the current dimensions of the embedder window
+ XWindowAttributes winAttributes;
+ XGetWindowAttributes(fl_display, xid_, &winAttributes);
+ int w = winAttributes.width;
+ int h = winAttributes.height;
+ updateSize(w, h);
+}
+
+void Xembed::updateSize(int _w, int _h) {
+ // Resize dillo window only if neccessary
+ if (w() != _w || h() != _h)
+ {
+ resize(x(), y(), _w, _h);
+ }
+}
+
+static Xembed *xembed = 0; // Needed to access class from within...
static int event_handler(int e, Fl_Window *w) {
Atom xembed_atom = XInternAtom (fl_display, "_XEMBED", false);
@@ -98,16 +116,35 @@
}
}
}
-
+ else if (xembed && fl_xevent->type == ConfigureNotify) {
+ // Not using xembed protocol:
+ // If we get a ConfigureNotify *for the embedder window*
+ // resize dillo window according to the size told.
+ const XConfigureEvent& xcfg = fl_xevent->xconfigure;
+ uint32_t xid = xcfg.window;
+ if (xembed->xid() == xid)
+ {
+ xembed->updateSize(xcfg.width, xcfg.height);
+ }
+ }
return Fl::handle_(e, w);
}
// TODO: Implement more XEMBED support;
void Xembed::show() {
- createInternal(xid);
+ createInternal(xid_);
setXembedInfo(1);
Fl::event_dispatch(event_handler);
+ if (!xembed_protocol_)
+ {
+ // We are *not* using the xembed protocol -> handle resize on our own
+ xembed = this;
+ long mask(StructureNotifyMask); // Listen to X11 ConfigureNotify events
+ XSelectInput(fl_display, xid_, mask); // to detect resize of embedder window
+ Fl_Window::show();
+ updateSize(); // initial resize to embedder window size
+ }
}
void Xembed::createInternal(uint32_t parent) {
diff -r 9195a2df5ca3 src/xembed.hh
--- a/src/xembed.hh Fri Jan 04 11:17:00 2013 +0100
+++ b/src/xembed.hh Wed Jan 09 18:49:22 2013 +0100
@@ -7,17 +7,23 @@
class Xembed : public Fl_Window {
private:
- uint32_t xid;
+ uint32_t xid_;
+ bool xembed_protocol_;
void createInternal(uint32_t parent);
void setXembedInfo(unsigned long flags);
void sendXembedEvent(uint32_t message);
public:
- Xembed(uint32_t xid, int _w, int _h) : Fl_Window(_w, _h) {
- this->xid = xid;
+ Xembed(uint32_t xid, int _w, int _h, bool xembed_protocol=true) :
+ Fl_Window(_w, _h),
+ xid_( xid),
+ xembed_protocol_(xembed_protocol) {
};
void show();
int handle(int event);
+ void updateSize();
+ void updateSize(int _w, int _h);
+ uint32_t xid() const { return xid_; }
};
#endif
dembed.cxx
(text/x-c++src, 524 B)
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/x.H>
#include <iostream>
#include <sstream>
using namespace std;
int main( int argc_, char *argv_[] )
{
Fl_Window dw( 800, 600, "dillo embedded" );
dw.resizable( &dw );
dw.end();
dw.show();
ostringstream cmd;
cmd << "dillo -f --Xid 0x" << hex << (unsigned long)fl_xid(&dw);
if ( argc_ > 1 )
cmd << " " << argv_[1];
cmd << " &";
cout << "system '" << cmd.str() << "'" << endl;
system( cmd.str().c_str() );
return Fl::run();
}