aboutsummaryrefslogtreecommitdiff
path: root/libtopmenu-client/topmenu-client.c
diff options
context:
space:
mode:
Diffstat (limited to 'libtopmenu-client/topmenu-client.c')
-rw-r--r--libtopmenu-client/topmenu-client.c48
1 files changed, 45 insertions, 3 deletions
diff --git a/libtopmenu-client/topmenu-client.c b/libtopmenu-client/topmenu-client.c
index e62104e..ae9eac3 100644
--- a/libtopmenu-client/topmenu-client.c
+++ b/libtopmenu-client/topmenu-client.c
@@ -28,6 +28,10 @@
#include "topmenu-client.h"
+static G_DEFINE_QUARK(topmenu-plug, plug)
+static G_DEFINE_QUARK(topmenu-background, background)
+static Atom atom_change_background = None;
+
static gboolean handle_plug_delete(GtkPlug *plug, GdkEvent *event, GdkWindow *window)
{
return TRUE; // Prevent deletion of plug window
@@ -85,14 +89,39 @@ static gboolean handle_widget_button_event(GtkWidget *widget, GdkEvent *event, G
return FALSE;
}
+static GdkFilterReturn handle_plug_window_event(GdkXEvent *xevent, GdkEvent *event, gpointer data)
+{
+ GdkWindow *window = GDK_WINDOW(data);
+ if (((XEvent*)xevent)->type == ClientMessage) {
+ XClientMessageEvent *msg = (XClientMessageEvent*) xevent;
+ if (msg->message_type == atom_change_background) {
+ g_debug("received change background message");
+ TopMenuBackground *bg = g_object_get_qdata(G_OBJECT(window), background_quark());
+ g_return_val_if_fail(bg, GDK_FILTER_REMOVE);
+
+ topmenu_background_set_from_client_message(bg, msg);
+
+ return GDK_FILTER_REMOVE;
+ }
+ }
+
+ return GDK_FILTER_CONTINUE;
+}
+
void topmenu_client_connect_window_widget(GdkWindow *window, GtkWidget *widget)
{
Display *display = GDK_WINDOW_XDISPLAY(window);
- if (g_object_get_data(G_OBJECT(window), OBJECT_DATA_KEY_PLUG)) {
+ // Disconnect any pre-existing widget
+ if (g_object_get_qdata(G_OBJECT(window), plug_quark())) {
topmenu_client_disconnect_window(window);
}
+ // Initialize atoms now
+ if (atom_change_background == None) {
+ atom_change_background = XInternAtom(display, ATOM_TOPMENU_BACKGROUND_CHANGE, False);
+ }
+
Window xwin = GDK_WINDOW_XID(window);
GtkPlug *plug = GTK_PLUG(gtk_plug_new(0));
gtk_container_add(GTK_CONTAINER(plug), widget);
@@ -102,6 +131,9 @@ void topmenu_client_connect_window_widget(GdkWindow *window, GtkWidget *widget)
G_CALLBACK(handle_widget_button_event), plug, 0);
g_signal_connect_object(widget, "button-release-event",
G_CALLBACK(handle_widget_button_event), plug, 0);
+ gtk_widget_realize(GTK_WIDGET(plug));
+ gdk_window_add_filter(gtk_widget_get_window(GTK_WIDGET(plug)),
+ handle_plug_window_event, window);
gtk_widget_show(GTK_WIDGET(plug));
Window plug_xwin = gtk_plug_get_id(plug);
@@ -112,17 +144,27 @@ void topmenu_client_connect_window_widget(GdkWindow *window, GtkWidget *widget)
XA_WINDOW, 32, PropModeReplace,
(unsigned char*)&plug_xwin, 1);
- g_object_set_data_full(G_OBJECT(window), OBJECT_DATA_KEY_PLUG, plug,
+ g_object_set_qdata_full(G_OBJECT(window), plug_quark(), plug,
(GDestroyNotify) &gtk_widget_destroy);
+
+ // Connect the background
+ TopMenuBackground *bg = topmenu_background_new();
+ topmenu_background_connect(bg, widget);
+
+ // Destroy the background when the window is destroyed
+ g_object_set_qdata_full(G_OBJECT(window), background_quark(),
+ bg, g_object_unref);
}
void topmenu_client_disconnect_window(GdkWindow *window)
{
Display *display = GDK_WINDOW_XDISPLAY(window);
- gpointer window_data = g_object_steal_data(G_OBJECT(window), OBJECT_DATA_KEY_PLUG);
+ gpointer window_data = g_object_steal_qdata(G_OBJECT(window), plug_quark());
g_return_if_fail(window_data);
+ g_object_set_qdata(G_OBJECT(window), background_quark(), NULL);
+
Window xwin = GDK_WINDOW_XID(window);
GtkPlug *plug = GTK_PLUG(window_data);