[Xfce4-commits] <xfce4-embed-plugin:master> Added label clicking and improved GtkSocket+GtkPlug handling.
David Schneider
noreply at xfce.org
Sun Jan 1 21:44:39 CET 2012
Updating branch refs/heads/master
to 2503179feb1162d6b23ecda344aac2719bd2a4d6 (commit)
from cc9fae3e09f877f470a5131329f240cb38603f77 (commit)
commit 2503179feb1162d6b23ecda344aac2719bd2a4d6
Author: David Schneider <dnschneid at gmail.com>
Date: Sat Dec 31 03:27:10 2011 -0500
Added label clicking and improved GtkSocket+GtkPlug handling.
Bug fix: prevented referencing a window that has destroyed itself.
TODO | 8 ----
panel-plugin/embed.c | 93 ++++++++++++++++++++++++++++++++++++-------------
panel-plugin/embed.h | 1 +
3 files changed, 69 insertions(+), 33 deletions(-)
diff --git a/TODO b/TODO
index 02654fc..e69de29 100644
--- a/TODO
+++ b/TODO
@@ -1,8 +0,0 @@
-Fake socket no longer necessary?
- * Doesn't require manual plug size updates
- * Can create a socket at the start and don't need to replace it until the
- plug goes away
- * Still destroys the window on plugin destruction, but normal pop out seems
- to work.
- * Might be worth doing for simplicity, but not high priority
-Option to enable click-to-activate keyboard input
diff --git a/panel-plugin/embed.c b/panel-plugin/embed.c
index 8b23a20..506f2c8 100644
--- a/panel-plugin/embed.c
+++ b/panel-plugin/embed.c
@@ -291,11 +291,12 @@ embed_free (XfcePanelPlugin *plugin, EmbedPlugin *embed)
static void
embed_focus_menu (GtkMenuItem *focus_menu, EmbedPlugin *embed)
{
- if (embed->plug_is_gtkplug) {
- if (embed->socket)
+ if (embed->has_plug) {
+ if (embed->plug) {
+ focus_window (embed->disp, embed->plug);
+ } else {
xfce_panel_plugin_focus_widget (embed->plugin, embed->socket);
- } else if (embed->plug) {
- focus_window (embed->disp, embed->plug);
+ }
}
}
@@ -337,7 +338,7 @@ embed_size_changed (XfcePanelPlugin *plugin, gint size, EmbedPlugin *embed)
if (orientation == GTK_ORIENTATION_HORIZONTAL) {
/* If requested, use the window size detected earlier. This will be -1 for
* true GtkPlugs, which will pass through the window size request. */
- if (embed->min_size == EMBED_MIN_SIZE_MATCH_WINDOW && embed->plug)
+ if (embed->min_size == EMBED_MIN_SIZE_MATCH_WINDOW && embed->has_plug)
altsize = embed->plug_width;
gtk_widget_set_size_request (GTK_WIDGET (embed->socket), altsize, size);
/* Widget altsize should just adapt, since it might include a label and/or
@@ -345,7 +346,7 @@ embed_size_changed (XfcePanelPlugin *plugin, gint size, EmbedPlugin *embed)
gtk_widget_set_size_request (GTK_WIDGET (plugin), -1, size);
} else {
/* Same for vertical orientation. */
- if (embed->min_size == EMBED_MIN_SIZE_MATCH_WINDOW && embed->plug)
+ if (embed->min_size == EMBED_MIN_SIZE_MATCH_WINDOW && embed->has_plug)
altsize = embed->plug_height;
gtk_widget_set_size_request (GTK_WIDGET (embed->socket), size, altsize);
gtk_widget_set_size_request (GTK_WIDGET (plugin), size, -1);
@@ -630,6 +631,7 @@ embed_plug_added (GtkWidget *socket, EmbedPlugin *embed)
gtk_widget_hide (embed->embed_menu);
gtk_widget_show (embed->popout_menu);
gtk_widget_show (embed->focus_menu);
+ embed->has_plug = TRUE;
/* Stop any searching that is going on */
embed_stop_search (embed);
@@ -642,27 +644,33 @@ embed_plug_added (GtkWidget *socket, EmbedPlugin *embed)
/* Monitor the plug for destruction, along with title changes if we need it
* for the label. */
- if (embed->plug) {
+ if (!embed->plug_is_gtkplug) {
/* Construct a GdkWindow wrapper around the plug window.
* Throughout here we must use GDK's Display reference, not our own, since
* GDK uses this to determine whether to pass on events or not. */
embed->plug_window = gdk_x11_window_foreign_new_for_display (
gdk_display_get_default (), embed->plug);
- if (embed->plug_window) {
- /* Monitor for unmap/destroy events. If the label is based on the title,
- * also monitor property change events. */
- glong monitor_mask = StructureNotifyMask;
- if (embed->label_fmt && strstr (embed->label_fmt, EMBED_LABEL_FMT_TITLE))
- monitor_mask |= PropertyChangeMask;
- /* Reset the _NET_WM_NAME detector. */
- embed->monitor_saw_net_wm_name = FALSE;
- /* Set up the callback function, and start monitoring for the specified X
- * events. */
- gdk_window_add_filter (embed->plug_window,
- (GdkFilterFunc)embed_plug_filter, embed);
- XSelectInput (gdk_x11_get_default_xdisplay (),
- embed->plug, monitor_mask);
- }
+ } else {
+ /* Grab the GtkPlug's window. */
+ embed->plug_window = gtk_socket_get_plug_window (GTK_SOCKET (embed->socket));
+ if (embed->plug_window)
+ embed->plug = gdk_x11_drawable_get_xid (GDK_DRAWABLE (embed->plug_window));
+ }
+ if (embed->plug_window && embed->plug) {
+ /* Monitor for unmap/destroy events if it is not a standard GtkPlug. If the
+ * label is based on the title, also monitor property change events. */
+ glong monitor_mask = 0;
+ if (!embed->plug_is_gtkplug)
+ monitor_mask |= StructureNotifyMask;
+ if (embed->label_fmt && strstr (embed->label_fmt, EMBED_LABEL_FMT_TITLE))
+ monitor_mask |= PropertyChangeMask;
+ /* Reset the _NET_WM_NAME detector. */
+ embed->monitor_saw_net_wm_name = FALSE;
+ /* Set up the callback function, and start monitoring for the specified X
+ * events. */
+ gdk_window_add_filter (embed->plug_window,
+ (GdkFilterFunc)embed_plug_filter, embed);
+ XSelectInput (gdk_x11_get_default_xdisplay (), embed->plug, monitor_mask);
}
/* Update the label */
@@ -701,16 +709,19 @@ embed_plug_removed (GtkWidget *socket, EmbedPlugin *embed)
gtk_widget_hide (embed->popout_menu);
gtk_widget_hide (embed->focus_menu);
gtk_widget_show (embed->embed_menu);
+ embed->has_plug = FALSE;
/* Assume the socket will be destroyed after this returns, so get rid of our
* reference. */
embed->socket = NULL;
/* Stop monitoring the plug window for changes */
if (embed->plug_window) {
- XSelectInput (gdk_x11_get_default_xdisplay (), embed->plug, 0);
+ if (embed->plug)
+ XSelectInput (gdk_x11_get_default_xdisplay (), embed->plug, 0);
gdk_window_remove_filter (embed->plug_window,
(GdkFilterFunc)embed_plug_filter, embed);
- g_object_unref (embed->plug_window);
+ if (!embed->plug_is_gtkplug)
+ g_object_unref (embed->plug_window);
embed->plug_window = NULL;
}
/* Reset info */
@@ -841,6 +852,31 @@ embed_popout (GtkMenuItem *popout_menu, EmbedPlugin *embed)
}
+
+/* Callback for when the plugin is single/double/triple-clicked.
+ * Single-clicks focus the embedded window.
+ * Double-clicks and triple-clicks toggle embed/popout. */
+static gboolean
+embed_click (GtkWidget *label, GdkEvent *event, EmbedPlugin *embed)
+{
+ /* Only react to left mouse button */
+ if (event->button.button == 1) {
+ if (event->type == GDK_BUTTON_PRESS) {
+ embed_focus_menu (GTK_MENU_ITEM (embed->focus_menu), embed);
+ } else if (event->type == GDK_2BUTTON_PRESS ||
+ event->type == GDK_3BUTTON_PRESS) {
+ if (embed->has_plug)
+ embed_popout (GTK_MENU_ITEM (embed->popout_menu), embed);
+ else
+ embed_embed_menu (GTK_MENU_ITEM (embed->embed_menu), embed);
+ }
+ }
+ /* Do not eat the event */
+ return FALSE;
+}
+
+
+
/* Callback for when the embedded plug window is ungracefully destroyed, not by
* our doing, and not as part of XEmbed.
* Calls the removed callback and destroys the socket. */
@@ -850,11 +886,14 @@ embed_destroyed (EmbedPlugin *embed)
GtkWidget *socket;
if ((socket = embed->socket) == NULL)
return;
+ /* The window has been destroyed, so don't try to reference it. */
+ embed->plug = 0;
embed_plug_removed (embed->socket, embed);
gtk_widget_destroy (socket);
}
+
/* Callback for when the plugin is unrealized, usually right before being
* destroyed. We use the opportunity to ditch any normal windows we may have
* embedded. */
@@ -867,6 +906,7 @@ embed_unrealize (GtkWidget *plugin, EmbedPlugin *embed)
}
+
/* Pop out whatever is embedded and start a new search.
* Called when the window criteria have been updated. */
void
@@ -883,7 +923,7 @@ embed_search_again (EmbedPlugin *embed)
static GdkFilterReturn
embed_root_filter (XPropertyEvent *xevent, GdkEvent *_, EmbedPlugin *embed)
{
- if (!embed->plug && xevent->type == PropertyNotify) {
+ if (!embed->has_plug && xevent->type == PropertyNotify) {
/* To avoid double-handling window list changes, if we see a
* _NET_CLIENT_LIST we will stop responding to _WIN_CLIENT_LIST events.
* This is reset every time a new search is started, in case the window
@@ -937,6 +977,9 @@ embed_construct (XfcePanelPlugin *plugin)
g_signal_connect (G_OBJECT (plugin), "unrealize",
G_CALLBACK (embed_unrealize), embed);
+ g_signal_connect (G_OBJECT (plugin), "button-press-event",
+ G_CALLBACK (embed_click), embed);
+
/* Add the "pop out" menu item */
xfce_panel_plugin_menu_insert_item (plugin,
GTK_MENU_ITEM (embed->popout_menu));
diff --git a/panel-plugin/embed.h b/panel-plugin/embed.h
index 3d2d462..d08a6d8 100644
--- a/panel-plugin/embed.h
+++ b/panel-plugin/embed.h
@@ -36,6 +36,7 @@ typedef struct
GtkWidget *focus_menu;
/* panel data */
+ gboolean has_plug;
GdkNativeWindow plug;
GdkWindow *plug_window;
gint plug_width;
More information about the Xfce4-commits
mailing list