After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 58541 - GtkPlug/GtkSocket should be cross-platform
GtkPlug/GtkSocket should be cross-platform
Status: RESOLVED OBSOLETE
Product: gtk+
Classification: Platform
Component: Widget: Other
1.3.x
Other Windows
: Normal enhancement
: Small fix
Assigned To: gtk-bugs
gtk-bugs
Depends on:
Blocks:
 
 
Reported: 2001-08-04 13:29 UTC by Hans Breuer
Modified: 2011-09-05 04:18 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
PATCH: first revision of Plug/Socket for win32 (4.24 KB, patch)
2001-08-04 13:35 UTC, Hans Breuer
none Details | Review
updated (and unzipped) patch (16.98 KB, patch)
2001-10-26 16:47 UTC, Hans Breuer
needs-work Details | Review
Screenshot (51.98 KB, image/gif)
2005-03-15 23:04 UTC, Tor Lillqvist
  Details
Current diff (117.02 KB, patch)
2005-03-17 00:42 UTC, Tor Lillqvist
none Details | Review
Current diff (110.79 KB, patch)
2005-03-20 10:35 UTC, Tor Lillqvist
none Details | Review
Current diff (110.83 KB, patch)
2005-03-26 11:55 UTC, Tor Lillqvist
none Details | Review
Current diff (107.37 KB, patch)
2005-04-23 11:40 UTC, Tor Lillqvist
needs-work Details | Review
Current diff (114.80 KB, patch)
2005-07-08 15:00 UTC, Tor Lillqvist
committed Details | Review

Description Hans Breuer 2001-08-04 13:29:49 UTC
Hi Owen,
attached you'll find the updated version of my Plug-Socket patch.
It would be nice if you could re-think your policy about applying it.

Pros:
- it almost works at least for the testsocket.c case
- including Gtk<Plug|Socket> for all major platforms instead of
  making it optional gives a platform independent API. Otherwise
  other ports (i.e. PyGtk) need to special case platform dependencies
  for no good
- the win32 Plugs/Sockets won't get much better or at least get review from 
  interested parties if they are only available on my local hard disk.
- If someone finds a real use case for Plugs/Sockets on win32
  it is a good starting point
- you would get more testing for them, even patches (there is a bug in
  tests/testsocket.c) :

--- from-cvs/gtk+/tests/testsocket.c	Fri Jul 20 12:35:34 2001
+++ my-gtk/gtk+/tests/testsocket.c	Fri Jul 20 21:29:20 2001
@@ -3,7 +3,9 @@
 #include <string.h>
 #include <stdlib.h>
 #include <stdio.h>
+#ifdef HAVE_UNISTS_H
 #include <unistd.h>
+#endif
 
 int n_children = 0;
 
@@ -131,7 +133,7 @@
   gtk_box_pack_start (GTK_BOX (vbox), socket->box, TRUE, TRUE, 0);
   gtk_widget_show (socket->box);
 
-  gtk_socket_steal (GTK_SOCKET (socket), xid);
+  gtk_socket_steal (GTK_SOCKET (socket->socket), xid);
 }
 
 void
Comment 1 Hans Breuer 2001-08-04 13:35:00 UTC
Created attachment 845 [details] [review]
PATCH: first revision of Plug/Socket for win32
Comment 2 Owen Taylor 2001-10-19 17:39:22 UTC
[ Please attach patches unzipped. We still have 25gig or
  so of disk space free on bugzilla.gnome.org. A few 
  patches won't kill us. :-) ]

My objection here has never been to having Plug/Socket
implementations on other platforms.

My object has always been that making the details of the
XEMBED implementation cross platform makes no sense,
and I still believe this is the case.

An organization of:

#ifdef GDK_WINDOWING_X11
  XSendEvent()
#elif GDK_WINDOWING_Win32
  PostMessage()
#endif

Makes the code awfully ugly and unmaintainable, and is
just wrong. 

I understand that you want to reuse the XEMBED protocol
on Windows, and that sharing the "driver" code for this
would make maintainence of the Windows PLug/Socket code
easier, but I think long term entangling the 
windows/unix code in this way won't help us, and certainly
won't help people adding additional platforms.

What I'd suggest for code organization is that we have:

 gtkplug-private.h
 gtkplug.c
 gtkplug-local.c
 gtkplug-x11.c
 gtkplug-win32.c

 gtksocket-private.h
 gtksocket.c 
 gtksocket-local.c
 gtksocket-x11.c
 gtksocket-win32.c

Where gtkplug/socket-local.c is a stubbed implementation that
can be used whe only inprocess plug/socket embedding.

What the split is between gtkplug.c and gtkplug-x11.c is obviously
the tricky part. One guideline should be that all the code
for handling the local case should be in gtkplug.c, and 
x11/gdkx.h should only be included by gtkplug-x11.c.
Comment 3 Hans Breuer 2001-10-26 16:45:03 UTC
IMO the simpliest way to detect the cross platform needs
is to first do an almost working #ifdefed version.

My current patch (not much different to the previous one)
appears to suggest some additional Gdk API, like:

void
gdk_event_send (GdkWindow *destination,
                GdkEvent  *event,
                guint      timeout, /* ?? */
                gboolean   synchron);

GdkNativeWindow
gdk_window_get_native (GdkWindow *window);


and suddendly most of the platform specific code
from gtk<plug|socket>.c could vanish. The biggest
remaining part would be the filter_funcs, which could
live in gtkxembed-<x11|win32>.c. Splitting the code
in many independent files seems to be a little overkill ...

But I'm not sure if I understand enough of the XWindows
protocol and obviously this would only solve part of
the 'cross-platform-ness' because only two platforms
get served :)

(updated, un-zipped patch - without the above 
 suggestions implemented - follows)
 
Comment 4 Hans Breuer 2001-10-26 16:47:27 UTC
Created attachment 5917 [details] [review]
updated (and unzipped) patch
Comment 5 Owen Taylor 2002-02-21 17:44:23 UTC
Not going to get to doing anything on this until after 2.0.0.
Comment 6 Owen Taylor 2002-03-25 23:27:48 UTC
Moving non-critical or hard to fix bugs to 2.0.2
Comment 7 Matthias Clasen 2002-04-05 13:33:32 UTC
Move open bugs from milestones 2.0.[012] -- > 2.0.3, since 2.0.2 is already out.
Comment 8 Hans Breuer 2004-08-06 19:03:25 UTC
Does the recent setting of "2.6 API freeze" mean an updated patch would be
reconsidered - or would it be again just wasting time ?
Comment 9 Matthias Clasen 2004-11-10 03:49:55 UTC
Milestones generally indicate the earliest version we could include the fix.
No guarantees, in particular for Xembed related bugs, where owen would be the
only available reviewer...
Comment 10 Tor Lillqvist 2005-03-02 15:33:32 UTC
Owen and Hans, do you have any new ideas regarding this? In the evolution
porting process, I am currently looking at libbonoboui. It uses gtkplug/socket,
and I am wondering whether to just leave out those parts of libbonoboui on Win32
(with unknown consequences), or add Hans's implementation to gtk and see what
happens.
Comment 11 Tor Lillqvist 2005-03-02 16:22:22 UTC
I was told that the gtkplug/socket stuff is essential to libbonoboui and the
apps that use it, so I guess I'll start working on this soonish. I'll do
something like Owen describes in comment #2. This would be for HEAD only, right?
Comment 12 Hans Breuer 2005-03-02 21:01:21 UTC
Last time I looked it appeared much simpler to have the platform 
specific stuff in platform specific file. I didn't continue on
this for two reasons :

1) None of the programs I'm interested in did make use of GtkPlug/Socket
2) I don't follow Owen's argument of implementing based on platforms
common embedding API (which would probably mean ActiveX for win32)
cause to me the only use for GtkPlug/Socket will be between two 
programs depending on Gtk. Most ActiveX Controls I'm aware of depend 
on the MFC. Having two huge toolkits in one "application" does not 
look like anyone would be interested ;)

BTW: is there any particular reason for this bug to be visible only 
for GNOME Hackers - or was this changed by accident?
Comment 13 Tor Lillqvist 2005-03-02 21:08:28 UTC
1) Ditto, until now ;-)

I'll see what I can do.

GNOME Hackers only, eh, must have been by accident.
Comment 14 Owen Taylor 2005-03-02 21:43:15 UTC
One thing you might want to investigate, Tor, is whether Evolution actually
is using *interprocess* embedding at this point. If not, then you might
only need to implement the -local files described in my comment #2.

XEMBED really does depend upon various concepts that are, to my knowledge,
X specific, like:

 - Reparenting
 - Redirection of mapping/resizing. (The embedder in XEMBED receives
   the XResizeWindow requests from the client and can choose whether
   it obeys them or not. In fact, the embedder and client interact
   just like window manager and application.)

So, while just copying XEMBED may give you a partially working initial
solution, I don't think it is going to hold up long term. The Win32
protocol needs the freedom to evolve on its own. That's why I don't
think we can just implement the XEMBED protocol and hide the X calls
as Hans suggests in comment #3.
Comment 15 Tor Lillqvist 2005-03-15 22:59:47 UTC
Actually, reparenting seems to work fine on Win32. (The docs for SetParent()
claim that "The new parent window and the child window must belong to the same
application", but that doesn't seem to be true. Sheesh.)

After more or less intense hacking for some time, testsocket basically works...
Some rough edges still, for instance the "Passive Child" plug retains its window
management decorations (and its size is thus miscalculated). And the "Local
Passive Child" plug has its geometry miscalculated or something. See attached
screenshot...

I don't even do anything special for redirection of mapping/resizing, still
things mostly seems to work, at least in testsocket. Odd.

I rearranged the source code as follows, following Owen's ideas above:

- gtk{socket,plug}.c: backend-independent code
- gtk{socket,plug}-{x11,win32}.c: backend code
- gtk{socket,plug}private.h: declarations of backend functions, and of private
functions for backend's use located in the backend-independent files.
- gtkwin32embed.{ch} - minimal Windows message -based "protocol"

How does that seem, are the file names well chosen? Would it be OK to commit
something like this to HEAD? What about 2.6? 

Will attach a diff, too, in a moment.
Comment 16 Tor Lillqvist 2005-03-15 23:04:27 UTC
Created attachment 38770 [details]
Screenshot

Four embedded plugs (left to right): Passive, Local Active, Active, Local
Passive.
Comment 17 Tor Lillqvist 2005-03-17 00:42:32 UTC
Created attachment 38819 [details] [review]
Current diff

For your amusement, here are my current diffs related to this. Please ignore
the debugging printouts...
Comment 18 Tor Lillqvist 2005-03-20 10:35:31 UTC
Created attachment 38954 [details] [review]
Current diff

Current diff after latest changes to gtk. No extra debugging output any longer.
Comment 19 Tor Lillqvist 2005-03-26 11:55:02 UTC
Created attachment 39276 [details] [review]
Current diff
Comment 20 Hans Breuer 2005-03-26 12:40:01 UTC
Hi Owen,
at least I'd like to get this applied to HEAD instead of letting 
it rot a few years ;) What's holding it now?
Remaining issues like using __FUNCTION__ unconditionally can be
resolved from cvs than ...

Thanks,
    Hans
Comment 21 Tor Lillqvist 2005-03-26 17:21:12 UTC
(About __FUNCTION__) Those are obviously just temporary debugging printouts,
didn't bother to remove before running the diff.
Comment 22 Owen Taylor 2005-04-12 16:57:40 UTC
In general, the approach taken here looks good.

(I really find that debugging printfs left-over in a patch make it
a lot harder to review... if you have printfs you want to leave 
in permanently you can use GTK_NOTE(PLUGSOCKET, ... that at least
has the benefit of being able to skip it quickly visually)

General comments:

 - I think it would be cleaner if *all* public functions went
   into gtkplug/socket.[ch], so make gtk_socket_get_id() a wrapper.

 - I'd like to see a naming convention for the backend-specific
   plug/socket functions. Perhaps _gtk_plug_windowing_<blah>
   in analogy to _gtk_windowing_window_get_offsets, and so forth.
   Right now it's hard to guess what file something lives in
   by reading the code.

 - We need doc comments for all the _gtk_plug_* in gtkplug.c.
   If you write them to the best of your understanding, I can
   fix up.
   
 - Having doc comments for the _gtk_plug_windowing_* would also be
   nice. I'd suggest putting the doc comments for them in
   gtkplugprivate.h. 

 - 

Specific comments:

 - I'd rather not see scanf() usage in testsocket.c even in 
   getenv() block. In general, I dont' really understand the testsocket.c
   changes.

 - Have we thought about win64? Do window handles stay 32-bits there?
  
 - These changes look to break the linux-fb/direct-fb backends. 
   How hard would a stubbed out gtkplugstub.c be? Would it work
   for local-only?

 - I don't think the translation of XEMBED_MAPPED into an event is
   going to work ... the point of making it a property is that it
   can be set at any point, before or after the embedding starts.
 
 - Don't export _gtk_plug_symbols, just emit events by name

 - Why did GrabbedKey moeve to gtkplugprivate.h? (If it does
   move, it would need to be renamed to GtkGrabbedKey)

 - The implementation of _gtk_socket_size_request for Win32 
   looks wrong. What we want is the plug's minimum size,
   not it's current size. If you can't get that information 
   from the Win32 API, you'll have to pass it via the protocol.

 - _gtk_socket_active_change() is misnamed. I'd probably prefer
   it just as a pair of functions, though if you keep the
   current signature, I'd say _gtk_socket_change_activity().

 - gtk_socket_send_configure_notify() is used to implement particular
   requirements of the ICCCM for window-manager/client interaction.
   It's strange to me to use the same logic on Windows.

 - The push_message/pop_message stuff is just crying out for 
   documentation. 
Comment 23 Tor Lillqvist 2005-04-21 08:14:23 UTC
I am now working on this again. Expect a new version modified according to your
comments today or tomorrow. I assume you mean signals when you talk about
"_gtk_plug_symbols" and "emit events"?
Comment 24 Tor Lillqvist 2005-04-23 11:40:51 UTC
Created attachment 45579 [details] [review]
Current diff

Here is my current diff. It should address most of your issues. I didn't
include any patch to testsocket, will have to look more closely at it. I
commented out the  _gtk_socket_windowing_send_configure_event in
gtksocket-win32.c, and indeed it didn't seem to make any difference. Will
remove altogether.

I removed the debugging output, but will probably regret that as soon as I try
to solve the remaining issues... (for instance, the "blink" test in testsocket
behaves oddly sometimes).

I did not yet:
- consider Win64.
- try to implement the XEMBED_MAPPED X11 property some other way than messages.
Windows windows don't have X11-like properties, or at least not anything
comparable that one could receive change notification from. In what cases would
the property be set before the embedding starts?
- document the push/pop message stuff as I don't understand it at all.
- implement local-only stubs for the linux-fb or direct-db backends. Probably
would be trivial.
Comment 25 Owen Taylor 2005-05-05 19:09:41 UTC
 * The main large-scale change I'd like to see now, is to see all
   the gtk_{plug,socket}_windowing functions changed to take a
   GtkPlug or GtkSocket as their first parameter rather than a
   random collection of functions. In most cases, this would allow
   getting rid of one or more of the current parameters.

 * I would also really like to see documentation of the protoocl
   you are using and how it differs from XEMBED. (You could put
   a text file into gtk+/docs/ or put it in a source code comment.)
   It's not clear, for example, to me what 
   GTK_WIN32_REQUEST_EVENTS does.

 * I would suggest that stripping out the version number part of the
   XEMBED protocol is probably not the best idea. Obviously it
   has to be done a little differently without the XEMBED_INFO
   property, but an initial version number handshake likely isn't
   hard.

 * The documentation and names of the inter-file private functions
   need a lot of work from my perspective, but it's probably easier
   to just do that myself once this lands rather than explaining
   it here.

 * A very simple way to handle map state is to say that if the 
   client (plug) is mapped when embedding begins, the client must send 
   a map message to the embedder.

 * There's reasonable documentation of the push/pop message stuff 
   in gtkxembed.c that you could just copy. 

   XEMBED_FOCUS_WRAPAROUND is explained in:

   http://lists.freedesktop.org/archives/xdg/2003-August/002216.html

   (Apparently never committed to CVS)

 * Could you revert plug_signals (socket_signals) => _gtk_plug_signals
   name change and the gtk_plug_set_is_child() ... set_is_child() 
   name change?

 * Instead of exporting _gtk_plug_add_grabbed_key_always() across
   file boundaries, you should put the g_hash_table_foreach() call
   into gtkplug.c

 * The handling of getting the minimum size looks better, though
   I don't see the point in calling GetClientRect(). But what you 
   aren't handling is changes in the minimum size. You may have
   to add a new virtual function to GtkWindow to allow a subclass
   to hoook in when it calls gdk_window_set_geometry_hints()
   [ There is padding in the class structure ]
Comment 26 Tor Lillqvist 2005-05-13 10:27:14 UTC
> all the gtk_{plug,socket}_windowing functions changed to take a
> GtkPlug or GtkSocket as their first parameter rather than a
> random collection of functions.

OK, done.

> documentation of the protoocl you are using and how it differs from XEMBED.

This is the hard part ;-)

> It's not clear, for example, to me what GTK_WIN32_REQUEST_EVENTS does.

Hmm, looking at it again now, not to me either. I guess I must have confused myself.

That message is sent in _gtk_socket_windowing_select_plug_window_input(), which
on X11 calls XSelectInput() on the *plug* window to get StructureNotify and
PropertyChange events of the socket window. Nothing like that is possible on
Windows, and I guess my idea was that that message would request the socket's
code to send information about such events explicitly  to the plug code. But
then I lost my train of thought and what the handler for that message actually
does in gtkplug-win32.c is a reworked copy of the ReparentNotify handler in
gtkplug-x11.c. I.e. some confusing mixup here.

> stripping out the version number part of the XEMBED protocol is probably
> not the best idea.

OK, will add a version negotiation.

> revert plug_signals (socket_signals) => _gtk_plug_signals name change

OK, done.

> Instead of exporting _gtk_plug_add_grabbed_key_always()

OK, done.

Will continue to look at the other points. I won't attach fresh diffs yet, I
wrote this comment mostly so that I keep track myself of that remains to be done
in case I get sidetracked to other stuff inbetween ;-)

BTW, once this in good shape, do you think it can go into the stable branch,
too, or just HEAD?
Comment 27 Tor Lillqvist 2005-07-08 15:00:55 UTC
Created attachment 48832 [details] [review]
Current diff

So, after some intense debugging and headscratching, I now have it working much
better on Win32. Now the resizing of embedded windows (the "Add" button in
testsocket) is noticed by the socket, and it resizes accordingly. Some
superfluous GTK_NOTE() calls are still present in this patch, will remove
before committing.
Comment 28 Owen Taylor 2005-07-20 15:47:32 UTC
Why don't you go ahead and commit what you have. I think a lot of my
comments above still stand; e.g:

 - I don't think the current patch will even compile for non-Win32,
   non-X11 backends. A stubbed local-only version would be a nice
   addition.

 - It doesn't look like changes in the minimum size are handled

 - I'd really like to see some attempt at documenting the Win32 
   protocol

 - There are places where the win32 protocol should probably 
   deviate more from the X11 protocol ... if win32 doesn't have
   a ReparentNotify, then it would be simpler to use a client
   message rather than guessing from WM_WINDOWPOSCHANGED

 - You still dont' have a "version handshake", just a debug check
   for matching versions.

But let's get it into CVS. I think it's unlikely to regress the
X11 code, and then I can go ahead and fix up the docs for the
inter-file functions.
Comment 29 Tor Lillqvist 2005-07-21 14:55:48 UTC
Committed now. I also added stub implementations for the non-X11, non-Win32
case. I'll have a look at your other points later.
Comment 30 Matthias Clasen 2005-08-01 05:48:30 UTC
Is more work on this required for 2.8 ?
Comment 31 Tor Lillqvist 2006-07-21 22:14:25 UTC
What needs to be done is handling Owen's points in comment #28. 
Comment 32 Christian Dywan 2008-10-31 09:20:09 UTC
Is there still work remainging to be done or should this bug be closed?