[Xfce4-commits] <xfce4-embed-plugin:master> Added a "fake socket" to avoid destruction of the embedded window.

David Schneider noreply at xfce.org
Sun Jan 1 21:44:24 CET 2012


Updating branch refs/heads/master
         to b6a2527384b8ef0b3f28734065d1e7c4da5f3a20 (commit)
       from 4f185dd6f50c56c98abc7d22613287982ae61b90 (commit)

commit b6a2527384b8ef0b3f28734065d1e7c4da5f3a20
Author: David Schneider <dnschneid at gmail.com>
Date:   Thu Dec 29 04:07:32 2011 -0500

    Added a "fake socket" to avoid destruction of the embedded window.
    
    The "fake socket" can be used to host non-XEmbed windows, while the GtkSocket
    functionality is still there for when we implement launching plug apps directly.

 panel-plugin/embed.c |   54 +++++++++++++++++++++++++++++++++++++++++--------
 panel-plugin/ewmh.c  |   19 ++++++++++++++--
 panel-plugin/ewmh.h  |    5 +++-
 3 files changed, 65 insertions(+), 13 deletions(-)

diff --git a/panel-plugin/embed.c b/panel-plugin/embed.c
index cbad6d2..f6f5af3 100644
--- a/panel-plugin/embed.c
+++ b/panel-plugin/embed.c
@@ -53,6 +53,8 @@ static void
 embed_popout (GtkMenuItem *popout_menu, EmbedPlugin *embed);
 static void
 embed_add_socket (EmbedPlugin *embed, gboolean update_size);
+static void
+embed_add_fake_socket (EmbedPlugin *embed);
 
 
 /* register the plugin */
@@ -91,6 +93,7 @@ embed_save (XfcePanelPlugin *plugin, EmbedPlugin *embed)
       xfce_rc_write_entry   (rc, "label_fmt",   embed->label_fmt);
     xfce_rc_write_int_entry (rc, "poll_delay",  embed->poll_delay);
     xfce_rc_write_int_entry (rc, "min_size",    embed->min_size);
+    xfce_rc_write_bool_entry(rc, "expand",      embed->expand);
 
     /* close the rc file */
     xfce_rc_close (rc);
@@ -129,6 +132,8 @@ embed_read (EmbedPlugin *embed)
                               "poll_delay", DEFAULT_POLL_DELAY);
       embed->min_size = xfce_rc_read_int_entry (rc,
                               "min_size", DEFAULT_MIN_SIZE);
+      embed->expand = xfce_rc_read_bool_entry (rc,
+                              "expand", DEFAULT_EXPAND);
 
       /* cleanup */
       xfce_rc_close (rc);
@@ -147,6 +152,7 @@ embed_read (EmbedPlugin *embed)
   embed->label_fmt   = g_strdup (DEFAULT_LABEL_FMT);
   embed->poll_delay  = DEFAULT_POLL_DELAY;
   embed->min_size    = DEFAULT_MIN_SIZE;
+  embed->expand      = DEFAULT_EXPAND;
 }
 
 
@@ -177,6 +183,9 @@ embed_new (XfcePanelPlugin *plugin)
   /* read the user settings */
   embed_read (embed);
 
+  /* set expand */
+  xfce_panel_plugin_set_expand (plugin, embed->expand);
+
   /* Compile the window name regex */
   if (embed->window_regex)
     embed->window_regex_comp = g_regex_new (embed->window_regex,
@@ -317,6 +326,7 @@ embed_update_label (EmbedPlugin *embed)
 }
 
 
+
 static gboolean
 embed_search (EmbedPlugin *embed)
 {
@@ -350,15 +360,14 @@ embed_search (EmbedPlugin *embed)
       }
 
       if (match) {
+        gtk_widget_destroy (embed->socket);
         embed->plug_is_gtkplug = FALSE;
         embed->plug = client_list[i];
         get_window_size (embed->disp, client_list[i],
                          &embed->plug_width, &embed->plug_height);
         DBG ("found window 0x%X of geometry %dx%d",
              embed->plug, embed->plug_width, embed->plug_height);
-        embed_update_label (embed);
-        embed_size_changed_simple (embed);
-        gtk_socket_steal (GTK_SOCKET (embed->socket), embed->plug);
+        embed_add_fake_socket (embed);
         break;
       }
     }
@@ -405,7 +414,7 @@ embed_embed_menu (GtkMenuItem *embed_menu, EmbedPlugin *embed)
 
 
 static void
-embed_plug_added (GtkSocket *socket, EmbedPlugin *embed)
+embed_plug_added (GtkWidget *socket, EmbedPlugin *embed)
 {
   DBG(".");
 
@@ -444,7 +453,7 @@ embed_add_socket_and_resize (EmbedPlugin *embed)
 
 
 static gboolean
-embed_plug_removed (GtkSocket *socket, EmbedPlugin *embed)
+embed_plug_removed (GtkWidget *socket, EmbedPlugin *embed)
 {
   DBG(".");
 
@@ -464,6 +473,19 @@ embed_plug_removed (GtkSocket *socket, EmbedPlugin *embed)
 
 
 static void
+embed_size_allocate (GtkSocket *socket, GdkRectangle *allocation,
+                     EmbedPlugin *embed)
+{
+  if (!embed->plug || embed->plug_is_gtkplug)
+    return;
+  DBG (".");
+  resize_window (embed->disp, embed->plug,
+                 allocation->width, allocation->height);
+}
+
+
+
+static void
 embed_add_socket (EmbedPlugin *embed, gboolean update_size)
 {
   if (embed->socket)
@@ -487,6 +509,21 @@ embed_add_socket (EmbedPlugin *embed, gboolean update_size)
 
 
 static void
+embed_add_fake_socket (EmbedPlugin *embed)
+{
+  embed->socket = gtk_drawing_area_new ();
+  gtk_widget_show (embed->socket);
+  gtk_box_pack_start (GTK_BOX (embed->hvbox), embed->socket, TRUE, TRUE, 0);
+  g_signal_connect (G_OBJECT (embed->socket), "size-allocate",
+                    G_CALLBACK (embed_size_allocate), embed);
+  reparent_window (embed->disp, embed->plug,
+                   gdk_x11_drawable_get_xid (gtk_widget_get_window (embed->socket)), 0, 0);
+  embed_plug_added (embed->socket, embed);
+}
+
+
+
+static void
 embed_popout (GtkMenuItem *popout_menu, EmbedPlugin *embed)
 {
   GtkWidget *socket;
@@ -496,15 +533,14 @@ embed_popout (GtkMenuItem *popout_menu, EmbedPlugin *embed)
   if (!embed->plug_is_gtkplug) {
     /* Since we're not hosting a gtkplug, we should reparent the window so we
      * don't break the program we were hosting. */
-    /* Unfortunately, gtksocket auto-destroys its plugs, and just reparenting
-     * doesn't prevent that. More drastic measures will be needed. */
-    /* make_window_toplevel (embed->disp, embed->plug); */
+    make_window_toplevel (embed->disp, embed->plug,
+                          embed->plug_width, embed->plug_height);
   }
   /* Don't enable searching for a new window. */
   embed->disable_search = TRUE;
   /* destroy socket and make a new one. destroy does not trigger plug_removed */
   socket = embed->socket;
-  embed_plug_removed (GTK_SOCKET (embed->socket), embed);
+  embed_plug_removed (embed->socket, embed);
   gtk_widget_destroy (socket);
 }
 
diff --git a/panel-plugin/ewmh.c b/panel-plugin/ewmh.c
index 68a236c..84a54aa 100644
--- a/panel-plugin/ewmh.c
+++ b/panel-plugin/ewmh.c
@@ -211,8 +211,21 @@ void get_window_size (Display *disp, Window win, gint *width, gint *height)
 }
 
 
-void make_window_toplevel (Display *disp, Window win)
+void make_window_toplevel (Display *disp, Window win, gint width, gint height)
 {
-    XReparentWindow (disp, win, DefaultRootWindow (disp), 0, 0);
-    XFlush (disp);
+    reparent_window (disp, win, DefaultRootWindow (disp), width, height);
+}
+
+void reparent_window (Display *disp, Window win, Window parent,
+                      gint width, gint height)
+{
+    XReparentWindow (disp, win, parent, 0, 0);
+    resize_window (disp, win, width, height);
+}
+
+void resize_window (Display *disp, Window win, gint width, gint height)
+{
+    if (width > 0 && height > 0)
+        XResizeWindow (disp, win, (guint)width, (guint)height);
+    XSync (disp, False);
 }
diff --git a/panel-plugin/ewmh.h b/panel-plugin/ewmh.h
index fb2e697..302a298 100644
--- a/panel-plugin/ewmh.h
+++ b/panel-plugin/ewmh.h
@@ -28,7 +28,10 @@ gchar  *get_window_title (Display *disp, Window win);
 gchar  *get_window_class (Display *disp, Window win);
 void    get_window_size  (Display *disp, Window win, gint *width, gint *height);
 
-void    make_window_toplevel (Display *disp, Window win);
+void make_window_toplevel (Display *disp, Window win, gint width, gint height);
+void reparent_window (Display *disp, Window win, Window parent,
+		      gint width, gint height);
+void resize_window (Display *disp, Window win, gint width, gint height);
 
 G_END_DECLS
 


More information about the Xfce4-commits mailing list