summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColomban Wendling <[email protected]>2017-01-20 15:49:00 +0100
committerlukefromdc <[email protected]>2017-01-23 13:49:34 -0500
commitbd25c5b4c173bb3541f204c60ffb9450a0d010cd (patch)
treead2eb9960265614140dd46bee9131ea27603fbb8
parent5349369f93fa6900e5bf2733fd2a56108dffcbb6 (diff)
downloadmate-panel-bd25c5b4c173bb3541f204c60ffb9450a0d010cd.tar.bz2
mate-panel-bd25c5b4c173bb3541f204c60ffb9450a0d010cd.tar.xz
status-notifier: Fix elements display on GTK < 3.20
On GTK 3.20 onwards, themes are expected to use CSS names rather than widget class names, and apparently CSS names are not inherited. So, a derived widget altering its CSS name won't be styled as its parent classes. Thus, SnItem setting the CSS name "sn-item" avoids being styled as a "button". But on older GTK versions, the widget class being used makes this change ineffective. Fix that by introducing a custom derived button that doesn't draw the unwanted parts.
-rw-r--r--applets/notification_area/status-notifier/Makefile.am2
-rw-r--r--applets/notification_area/status-notifier/sn-flat-button.c174
-rw-r--r--applets/notification_area/status-notifier/sn-flat-button.h60
-rw-r--r--applets/notification_area/status-notifier/sn-item.c2
-rw-r--r--applets/notification_area/status-notifier/sn-item.h6
5 files changed, 241 insertions, 3 deletions
diff --git a/applets/notification_area/status-notifier/Makefile.am b/applets/notification_area/status-notifier/Makefile.am
index 9bbb4134..6eab62ee 100644
--- a/applets/notification_area/status-notifier/Makefile.am
+++ b/applets/notification_area/status-notifier/Makefile.am
@@ -22,6 +22,8 @@ libstatus_notifier_la_SOURCES = \
sn-dbus-menu.h \
sn-dbus-menu-item.c \
sn-dbus-menu-item.h \
+ sn-flat-button.c \
+ sn-flat-button.h \
sn-host-v0.c \
sn-host-v0.h \
sn-image-menu-item.c \
diff --git a/applets/notification_area/status-notifier/sn-flat-button.c b/applets/notification_area/status-notifier/sn-flat-button.c
new file mode 100644
index 00000000..d920dadf
--- /dev/null
+++ b/applets/notification_area/status-notifier/sn-flat-button.c
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2017 Colomban Wendling <[email protected]>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * A GtkButton that doesn't draw anything specific but the focus, and pass
+ * all drawing and sizing requests to its child.
+ */
+
+#define SN_FLAT_BUTTON_C
+
+#include <gtk/gtk.h>
+
+#include "sn-flat-button.h"
+
+G_DEFINE_TYPE (SnFlatButton,
+ sn_flat_button,
+ GTK_TYPE_BUTTON)
+
+static gboolean
+sn_flat_button_draw (GtkWidget *widget,
+ cairo_t *cr)
+{
+ GtkWidget *child = gtk_bin_get_child (GTK_BIN (widget));
+
+ if (child)
+ gtk_container_propagate_draw (GTK_CONTAINER (widget), child, cr);
+
+ if (gtk_widget_is_drawable (widget) && gtk_widget_has_focus (widget))
+ {
+ GtkStyleContext *context = gtk_widget_get_style_context (widget);
+ gdouble x1, y1, x2, y2;
+
+ cairo_clip_extents (cr, &x1, &y1, &x2, &y2);
+ gtk_render_focus (context, cr, x1, y1, x2 - x1, y2 - y1);
+ }
+
+ return child != NULL;
+}
+
+static void
+sn_flat_button_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation)
+{
+ GtkWidget *child;
+
+ GTK_WIDGET_CLASS (sn_flat_button_parent_class)->size_allocate (widget,
+ allocation);
+
+ child = gtk_bin_get_child (GTK_BIN (widget));
+
+ if (child && gtk_widget_get_visible (child))
+ gtk_widget_size_allocate (child, allocation);
+}
+
+static GtkSizeRequestMode
+sn_flat_button_get_request_mode (GtkWidget *widget)
+{
+ GtkWidget *child = gtk_bin_get_child (GTK_BIN (widget));
+
+ if (child)
+ return gtk_widget_get_request_mode (child);
+ else
+ return GTK_WIDGET_CLASS (sn_flat_button_parent_class)->get_request_mode (widget);
+}
+
+static void
+sn_flat_button_get_preferred_height (GtkWidget *widget,
+ gint *min,
+ gint *nat)
+{
+ GtkWidget *child = gtk_bin_get_child (GTK_BIN (widget));
+
+ if (child)
+ gtk_widget_get_preferred_height (child, min, nat);
+ else
+ GTK_WIDGET_CLASS (sn_flat_button_parent_class)->get_preferred_height (widget, min, nat);
+}
+
+static void
+sn_flat_button_get_preferred_width (GtkWidget *widget,
+ gint *min,
+ gint *nat)
+{
+ GtkWidget *child = gtk_bin_get_child (GTK_BIN (widget));
+
+ if (child)
+ gtk_widget_get_preferred_width (child, min, nat);
+ else
+ GTK_WIDGET_CLASS (sn_flat_button_parent_class)->get_preferred_width (widget, min, nat);
+}
+
+static void
+sn_flat_button_get_preferred_height_for_width (GtkWidget *widget,
+ gint width,
+ gint *min,
+ gint *nat)
+{
+ GtkWidget *child = gtk_bin_get_child (GTK_BIN (widget));
+
+ if (child)
+ gtk_widget_get_preferred_height_for_width (child, width, min, nat);
+ else
+ GTK_WIDGET_CLASS (sn_flat_button_parent_class)->get_preferred_height_for_width (widget, width, min, nat);
+}
+
+static void
+sn_flat_button_get_preferred_width_for_height (GtkWidget *widget,
+ gint height,
+ gint *min,
+ gint *nat)
+{
+ GtkWidget *child = gtk_bin_get_child (GTK_BIN (widget));
+
+ if (child)
+ gtk_widget_get_preferred_width_for_height (child, height, min, nat);
+ else
+ GTK_WIDGET_CLASS (sn_flat_button_parent_class)->get_preferred_width_for_height (widget, height, min, nat);
+}
+
+static void
+sn_flat_button_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
+ gint width,
+ gint *min,
+ gint *nat,
+ gint *min_baseline,
+ gint *nat_baseline)
+{
+ GtkWidget *child = gtk_bin_get_child (GTK_BIN (widget));
+
+ if (child)
+ gtk_widget_get_preferred_height_and_baseline_for_width (child, width, min, nat,
+ min_baseline, nat_baseline);
+ else
+ GTK_WIDGET_CLASS (sn_flat_button_parent_class)->get_preferred_height_and_baseline_for_width (widget, width,
+ min, nat,
+ min_baseline, nat_baseline);
+}
+
+static void
+sn_flat_button_class_init (SnFlatButtonClass *klass)
+{
+ GtkWidgetClass *widget_class;
+
+ widget_class = GTK_WIDGET_CLASS (klass);
+
+ widget_class->draw = sn_flat_button_draw;
+ widget_class->size_allocate = sn_flat_button_size_allocate;
+ widget_class->get_request_mode = sn_flat_button_get_request_mode;
+ widget_class->get_preferred_height = sn_flat_button_get_preferred_height;
+ widget_class->get_preferred_height_for_width = sn_flat_button_get_preferred_height_for_width;
+ widget_class->get_preferred_height_and_baseline_for_width = sn_flat_button_get_preferred_height_and_baseline_for_width;
+ widget_class->get_preferred_width = sn_flat_button_get_preferred_width;
+ widget_class->get_preferred_width_for_height = sn_flat_button_get_preferred_width_for_height;
+}
+
+static void
+sn_flat_button_init (SnFlatButton *self)
+{
+ gtk_button_set_relief (GTK_BUTTON (self), GTK_RELIEF_NONE);
+}
diff --git a/applets/notification_area/status-notifier/sn-flat-button.h b/applets/notification_area/status-notifier/sn-flat-button.h
new file mode 100644
index 00000000..1a93d30f
--- /dev/null
+++ b/applets/notification_area/status-notifier/sn-flat-button.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2017 Colomban Wendling <[email protected]>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SN_FLAT_BUTTON_H
+#define SN_FLAT_BUTTON_H
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define SN_TYPE_FLAT_BUTTON (sn_flat_button_get_type ())
+#define SN_FLAT_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SN_TYPE_FLAT_BUTTON, SnFlatButton))
+#define SN_FLAT_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SN_TYPE_FLAT_BUTTON, SnFlatButtonClass))
+#define SN_IS_FLAT_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SN_TYPE_FLAT_BUTTON))
+#define SN_IS_FLAT_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SN_TYPE_FLAT_BUTTON))
+#define SN_FLAT_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SN_TYPE_FLAT_BUTTON, SnFlatButtonClass))
+
+typedef struct _SnFlatButton SnFlatButton;
+typedef struct _SnFlatButtonPrivate SnFlatButtonPrivate;
+typedef struct _SnFlatButtonClass SnFlatButtonClass;
+
+struct _SnFlatButton
+{
+ GtkButton parent_instance;
+
+ SnFlatButtonPrivate *priv;
+};
+
+struct _SnFlatButtonClass
+{
+ GtkButtonClass parent_class;
+};
+
+GType sn_flat_button_get_type (void);
+GtkWidget *sn_flat_button_new (void);
+
+#if 0
+#ifndef SN_COMPAT_BUTTON_NODRAW_C
+/* replace GtkButton */
+# define gtk_button_get_type sn_compat_button_nodraw_get_type
+#endif
+#endif
+
+G_END_DECLS
+
+#endif
diff --git a/applets/notification_area/status-notifier/sn-item.c b/applets/notification_area/status-notifier/sn-item.c
index fc0401b6..d102a6cc 100644
--- a/applets/notification_area/status-notifier/sn-item.c
+++ b/applets/notification_area/status-notifier/sn-item.c
@@ -57,7 +57,7 @@ static guint signals[LAST_SIGNAL] = { 0 };
static void na_item_init (NaItemInterface *iface);
-G_DEFINE_ABSTRACT_TYPE_WITH_CODE (SnItem, sn_item, GTK_TYPE_BUTTON,
+G_DEFINE_ABSTRACT_TYPE_WITH_CODE (SnItem, sn_item, SN_TYPE_FLAT_BUTTON,
G_IMPLEMENT_INTERFACE (GTK_TYPE_ORIENTABLE,
NULL)
G_IMPLEMENT_INTERFACE (NA_TYPE_ITEM,
diff --git a/applets/notification_area/status-notifier/sn-item.h b/applets/notification_area/status-notifier/sn-item.h
index de7de892..3736c1d8 100644
--- a/applets/notification_area/status-notifier/sn-item.h
+++ b/applets/notification_area/status-notifier/sn-item.h
@@ -20,6 +20,8 @@
#include <gtk/gtk.h>
+#include "sn-flat-button.h"
+
G_BEGIN_DECLS
#define SN_TYPE_ITEM (sn_item_get_type ())
@@ -41,14 +43,14 @@ typedef struct _SnItemClass SnItemClass;
struct _SnItem
{
- GtkButtonClass parent_instance;
+ SnFlatButtonClass parent_instance;
SnItemPrivate *priv;
};
struct _SnItemClass
{
- GtkButtonClass parent_class;
+ SnFlatButtonClass parent_class;
void (* ready) (SnItem *item);