aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJavier <dev.git@javispedro.com>2015-07-26 03:11:35 +0200
committerJavier <dev.git@javispedro.com>2015-07-26 03:11:35 +0200
commit2da9d48c9bcd1800f8a499b5e46c6ce04678acd5 (patch)
tree9c9fc6716b1ee4a098d49dcea3bbb0b778484491
parentbaef440d424640a6fc99edd8a12a6abcea80c5fc (diff)
downloadtopmenu-gtk-2da9d48c9bcd1800f8a499b5e46c6ce04678acd5.tar.gz
topmenu-gtk-2da9d48c9bcd1800f8a499b5e46c6ce04678acd5.zip
add gtk+3 support for transparent backgroundstransparency
-rw-r--r--README.md1
-rw-r--r--libtopmenu-client/topmenu-client.c1
-rw-r--r--libtopmenu-common/topmenu-background.c72
-rw-r--r--libtopmenu-common/topmenu-background.h1
4 files changed, 62 insertions, 13 deletions
diff --git a/README.md b/README.md
index 22ced6f..f22c606 100644
--- a/README.md
+++ b/README.md
@@ -35,7 +35,6 @@ please send questions or problem reports to dev.bugs at javispedro com. Alternat
* Multi-monitor support. Currently only one applet instance is supported. Ideally, IF there are multiple panel applets, they should synchronize to only embed menubars from the same display.
* Allow Qt programs to render the menubars using Qt itself instead of using Gtk+.
-* Transparent panels without XComposite (relative X11 background pixmaps, maybe?)
* Add some toggables for some commonely requested options: hide/show the application menu, "menu button" instead of menu bar.
# Design
diff --git a/libtopmenu-client/topmenu-client.c b/libtopmenu-client/topmenu-client.c
index ae9eac3..266ba54 100644
--- a/libtopmenu-client/topmenu-client.c
+++ b/libtopmenu-client/topmenu-client.c
@@ -95,7 +95,6 @@ static GdkFilterReturn handle_plug_window_event(GdkXEvent *xevent, GdkEvent *eve
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);
diff --git a/libtopmenu-common/topmenu-background.c b/libtopmenu-common/topmenu-background.c
index 99d36e9..04ea20d 100644
--- a/libtopmenu-common/topmenu-background.c
+++ b/libtopmenu-common/topmenu-background.c
@@ -40,6 +40,11 @@ G_DEFINE_TYPE(TopMenuBackground, topmenu_background, G_TYPE_OBJECT)
static guint signals[N_SIGNALS];
+#if GTK_MAJOR_VERSION == 3
+#define TOPMENU_BACKGROUND_CSS_STYLE_CLASS "topmenu-background"
+static GtkCssProvider *topmenu_provider;
+#endif
+
static inline GdkDisplay * topmenu_background_get_display(TopMenuBackground *self)
{
return gdk_display_get_default();
@@ -94,12 +99,6 @@ TopMenuBackground *topmenu_background_new(void)
void topmenu_background_set_from_color(TopMenuBackground *self, double red, double green, double blue, double alpha)
{
- if (self->priv->has_color
- && self->priv->red == red && self->priv->green == green
- && self->priv->blue == blue && self->priv->alpha == alpha) {
- return; // Nothing to do
- }
-
topmenu_background_reset(self);
self->priv->has_color = TRUE;
@@ -150,6 +149,7 @@ void topmenu_background_set_from_drawable(TopMenuBackground *self, Drawable draw
width, height);
if (!new_surface) {
g_debug("could not create new surface");
+ XFreePixmap(xdpy, self->priv->pixmap);
goto err_out;
}
@@ -283,13 +283,10 @@ void topmenu_background_set_from_client_message(TopMenuBackground *self, XClient
green = ((rgba >> 16) & 0xFF) / 255.0,
blue = ((rgba >> 8) & 0xFF) / 255.0,
alpha = ((rgba >> 0) & 0xFF) / 255.0;
- g_debug("received color %.2f,%.2f,%.2f,%.2f", red, green, blue, alpha);
topmenu_background_set_from_color(self, red, green, blue, alpha);
} else if (event->data.l[2] != None) {
- g_debug("received pixmap 0x%lx", event->data.l[2]);
topmenu_background_set_from_drawable(self, event->data.l[2]);
} else {
- g_debug("received nothing");
topmenu_background_clear(self);
}
}
@@ -310,7 +307,41 @@ static GdkPixmap * get_pixmap(GdkDisplay *display, Pixmap pixmap)
void topmenu_background_apply(TopMenuBackground *self, GtkWidget *widget)
{
#if GTK_MAJOR_VERSION == 3
- g_debug("background set not yet supported on Gtk+ 3");
+ if (!topmenu_provider) {
+ topmenu_provider = gtk_css_provider_new();
+ gtk_css_provider_load_from_data(topmenu_provider,
+ "." TOPMENU_BACKGROUND_CSS_STYLE_CLASS " {\n"
+ " background-color: rgba (0, 0, 0, 0);\n"
+ " background-image: none;\n"
+ "}", -1, NULL);
+ }
+
+ GtkStyleContext *context = gtk_widget_get_style_context(widget);
+
+ GdkWindow *widget_window = gtk_widget_get_window(widget);
+ double red, green, blue, alpha;
+ Pixmap pixmap;
+ if (topmenu_background_get_color(self, &red, &green, &blue, &alpha)) {
+ gtk_style_context_add_class(context, TOPMENU_BACKGROUND_CSS_STYLE_CLASS);
+ if (widget_window) {
+ GdkRGBA color = {red, green, blue, alpha};
+ gdk_window_set_background_rgba(widget_window, &color);
+ g_debug("do color");
+
+ }
+ } else if (topmenu_background_get_pixmap(self, &pixmap)) {
+ gtk_style_context_add_class(context, TOPMENU_BACKGROUND_CSS_STYLE_CLASS);
+ if (widget_window) {
+ cairo_pattern_t * pattern = topmenu_background_get_cairo_pattern(self);
+ gdk_window_set_background_pattern(widget_window, pattern);
+ cairo_pattern_destroy(pattern);
+ }
+ } else {
+ gtk_style_context_remove_class(context, TOPMENU_BACKGROUND_CSS_STYLE_CLASS);
+ }
+
+ gtk_style_context_add_provider(context, GTK_STYLE_PROVIDER(topmenu_provider),
+ GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
#elif GTK_MAJOR_VERSION == 2
// Clear current background
GtkRcStyle *rc_style;
@@ -347,15 +378,34 @@ void topmenu_background_apply(TopMenuBackground *self, GtkWidget *widget)
g_object_unref(style);
}
}
-
+#endif
gtk_widget_queue_draw(widget);
+}
+
+void topmenu_background_unapply(TopMenuBackground *self, GtkWidget *widget)
+{
+#if GTK_MAJOR_VERSION == 3
+ GtkStyleContext *context = gtk_widget_get_style_context(widget);
+ gtk_style_context_remove_class(context, TOPMENU_BACKGROUND_CSS_STYLE_CLASS);
+ gtk_style_context_remove_provider(context, GTK_STYLE_PROVIDER(topmenu_provider));
+#elif GTK_MAJOR_VERSION == 2
+ // Clear current background
+ GtkRcStyle *rc_style;
+ gtk_widget_set_style(widget, NULL);
+ rc_style = gtk_rc_style_new();
+ gtk_widget_modify_style(widget, rc_style);
+ g_object_unref(rc_style);
#endif
+ gtk_widget_queue_draw(widget);
}
void topmenu_background_connect(TopMenuBackground *self, GtkWidget *widget)
{
g_signal_connect(self, "changed",
G_CALLBACK(topmenu_background_apply), widget);
+ if (gtk_widget_get_realized(widget)) {
+ topmenu_background_apply(self, widget);
+ }
}
void topmenu_background_disconnect(TopMenuBackground *self, GtkWidget *widget)
diff --git a/libtopmenu-common/topmenu-background.h b/libtopmenu-common/topmenu-background.h
index aca72f8..76c9f6d 100644
--- a/libtopmenu-common/topmenu-background.h
+++ b/libtopmenu-common/topmenu-background.h
@@ -65,6 +65,7 @@ void topmenu_background_fill_client_message(TopMenuBackground *self, XClientMess
void topmenu_background_set_from_client_message(TopMenuBackground *self, XClientMessageEvent *event);
void topmenu_background_apply(TopMenuBackground *self, GtkWidget *widget);
+void topmenu_background_unapply(TopMenuBackground *self, GtkWidget *widget);
void topmenu_background_connect(TopMenuBackground *self, GtkWidget *widget);
void topmenu_background_disconnect(TopMenuBackground *self, GtkWidget *widget);