aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJavier <dev.git@javispedro.com>2014-05-17 19:53:53 +0200
committerJavier <dev.git@javispedro.com>2014-05-17 19:53:53 +0200
commit14d288511323d4f384d4764ab25a42693ff19f4a (patch)
treed69907ed23d9df328459b598c0c8f914782013cd
parentfae72947043ae3b1627dac77b3c42bf2e1dbbd09 (diff)
downloadtopmenu-gtk-14d288511323d4f384d4764ab25a42693ff19f4a.tar.gz
topmenu-gtk-14d288511323d4f384d4764ab25a42693ff19f4a.zip
gtk3 client library + module now hackishly working
-rw-r--r--configure.ac63
-rw-r--r--libtopmenu-client/Makefile.am21
-rw-r--r--libtopmenu-client/topmenu-appmenubar.c32
-rw-r--r--libtopmenu-client/topmenu-client.c6
-rw-r--r--libtopmenu-client/topmenu-monitor.c2
-rw-r--r--libtopmenu-server/Makefile.am19
-rw-r--r--libtopmenu-server/topmenu-widget.c2
-rw-r--r--libtopmenu-server/topmenu-widget.h2
-rw-r--r--module/Makefile.am2
-rw-r--r--module/data.c8
-rw-r--r--module/main.c10
-rw-r--r--module/menuitem-proxy.c338
-rw-r--r--test/Makefile.am4
-rw-r--r--test/client.c22
-rw-r--r--test/server.c1
15 files changed, 455 insertions, 77 deletions
diff --git a/configure.ac b/configure.ac
index c9623ce..6383e9d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -31,6 +31,7 @@ AC_ARG_ENABLE([mate-applet],
[],
[enable_mate_applet=check])
+AM_CONDITIONAL([GTK3], [test GTK$with_gtk = GTK3])
AC_SUBST([GTK_VERSION], [$with_gtk])
AC_DEFINE_UNQUOTED([GTK_VERSION], [$with_gtk], [Define to GTK major version used])
AC_SUBST([GTK_MODULE_DIR], [$with_gtk_module_dir])
@@ -43,37 +44,39 @@ AC_PROG_LIBTOOL
# Checks for libraries.
PKG_CHECK_MODULES([GTK], [gtk+-x11-$with_gtk.0])
-AS_IF([test "x$with_wnck" = xwnck1 -o "x$with_wnck" = xcheck],
- [PKG_CHECK_MODULES([WNCK], [libwnck-1.0],
- [
- AC_DEFINE([HAVE_WNCK1], [1], [Define if you have libwnck-1.0])
- with_wnck=libwnck1
- ],
- [if test "x$with_wnck" = xwnck1; then
- AC_MSG_FAILURE([--with-wnck=wnck1 was given, but test for libwnck-1.0 failed])
- fi]
- )])
-AS_IF([test "x$with_wnck" = xmatewnck -o "x$with_wnck" = xcheck],
- [PKG_CHECK_MODULES([MATEWNCK], [libmatewnck],
- [
- AC_DEFINE([HAVE_MATEWNCK], [1], [Define if you have libmatewnck])
- with_wnck=libmatewnck
- ],
- [if test "x$with_wnck" = xmatewnck; then
- AC_MSG_FAILURE([--with-wnck=matewnck was given, but test for libmatewnck failed])
- fi]
- )])
+AS_IF([test "x$with_gtk" = x3],
+ [],
+ [AS_IF([test "x$with_wnck" = xwnck1 -o "x$with_wnck" = xcheck],
+ [PKG_CHECK_MODULES([WNCK], [libwnck-1.0],
+ [
+ AC_DEFINE([HAVE_WNCK1], [1], [Define if you have libwnck-1.0])
+ with_wnck=libwnck1
+ ],
+ [if test "x$with_wnck" = xwnck1; then
+ AC_MSG_FAILURE([--with-wnck=wnck1 was given, but test for libwnck-1.0 failed])
+ fi]
+ )])
+ AS_IF([test "x$with_wnck" = xmatewnck -o "x$with_wnck" = xcheck],
+ [PKG_CHECK_MODULES([MATEWNCK], [libmatewnck],
+ [
+ AC_DEFINE([HAVE_MATEWNCK], [1], [Define if you have libmatewnck])
+ with_wnck=libmatewnck
+ ],
+ [if test "x$with_wnck" = xmatewnck; then
+ AC_MSG_FAILURE([--with-wnck=matewnck was given, but test for libmatewnck failed])
+ fi]
+ )])
-AS_IF([test "x$enable_mate_applet" != xno],
- [PKG_CHECK_MODULES([MATEPANELAPPLET], [libmatepanelapplet-4.0],
- [
- AC_DEFINE([HAVE_MATEPANELAPPLET], [1], [Define if you have libmatepanelapplet])
- enable_mate_applet=yes
- ],
- [if test "x$enable_mate_applet" = xyes; then
- AC_MSG_FAILURE([--enable-mate-applet was given, but test for libmatepanelapplet failed])
- fi]
- )])
+ AS_IF([test "x$enable_mate_applet" != xno],
+ [PKG_CHECK_MODULES([MATEPANELAPPLET], [libmatepanelapplet-4.0],
+ [
+ AC_DEFINE([HAVE_MATEPANELAPPLET], [1], [Define if you have libmatepanelapplet])
+ enable_mate_applet=yes
+ ],
+ [if test "x$enable_mate_applet" = xyes; then
+ AC_MSG_FAILURE([--enable-mate-applet was given, but test for libmatepanelapplet failed])
+ fi]
+ )])])
AM_CONDITIONAL([WANT_MATE_APPLET], [test x$enable_mate_applet = xyes])
diff --git a/libtopmenu-client/Makefile.am b/libtopmenu-client/Makefile.am
index b57343b..f4f8b6f 100644
--- a/libtopmenu-client/Makefile.am
+++ b/libtopmenu-client/Makefile.am
@@ -1,8 +1,21 @@
-lib_LTLIBRARIES = libtopmenu-client.la
-libtopmenu_client_la_SOURCES = topmenu-client.c topmenu-client.h \
+if GTK3
+
+lib_LTLIBRARIES = libtopmenu-client-gtk3.la
+libtopmenu_client_gtk3_la_SOURCES = topmenu-client.c topmenu-client.h \
+ topmenu-monitor.c topmenu-monitor.h \
+ topmenu-appmenubar.c topmenu-appmenubar.h
+libtopmenu_client_gtk3_la_CPPFLAGS = $(GTK_CFLAGS) -DG_LOG_DOMAIN=\"topmenu-client\"
+libtopmenu_client_gtk3_la_LIBADD = $(GTK_LIBS)
+
+else
+
+lib_LTLIBRARIES = libtopmenu-client-gtk2.la
+libtopmenu_client_gtk2_la_SOURCES = topmenu-client.c topmenu-client.h \
topmenu-monitor.c topmenu-monitor.h \
topmenu-appmenubar.c topmenu-appmenubar.h
-libtopmenu_client_la_CPPFLAGS = $(GTK_CFLAGS) -DG_LOG_DOMAIN=\"topmenu-client\"
-libtopmenu_client_la_LIBADD = $(GTK_LIBS)
+libtopmenu_client_gtk2_la_CPPFLAGS = $(GTK_CFLAGS) -DG_LOG_DOMAIN=\"topmenu-client\"
+libtopmenu_client_gtk2_la_LIBADD = $(GTK_LIBS)
+
+endif
include_HEADERS = topmenu-client.h topmenu-monitor.h topmenu-appmenubar.h
diff --git a/libtopmenu-client/topmenu-appmenubar.c b/libtopmenu-client/topmenu-appmenubar.c
index 7d94cf5..5c66d91 100644
--- a/libtopmenu-client/topmenu-appmenubar.c
+++ b/libtopmenu-client/topmenu-appmenubar.c
@@ -48,6 +48,7 @@ static void topmenu_app_menu_bar_class_init(TopMenuAppMenuBarClass *klass)
g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
+#if GTK_MAJOR_VERSION == 2
gtk_rc_parse_string (
"style \"app-menubar-style\"\n"
"{\n"
@@ -55,10 +56,41 @@ static void topmenu_app_menu_bar_class_init(TopMenuAppMenuBarClass *klass)
" GtkMenuBar::internal-padding = 0\n"
"}\n"
"class \"TopMenuAppMenuBar\" style \"app-menubar-style\"");
+#endif
}
static void topmenu_app_menu_bar_init(TopMenuAppMenuBar *self)
{
+#if GTK_MAJOR_VERSION == 3
+ GError *error = NULL;
+ GtkCssProvider *provider = gtk_css_provider_new();
+ GtkStyleContext *style_context = gtk_widget_get_style_context(GTK_WIDGET(self));
+ static const char *css =
+ "TopMenuAppMenuBar {\n"
+ " box-shadow: none;\n"
+ " padding: 0;\n"
+ " background-color: @os_chrome_bg_color;\n"
+ " background-image: none;\n"
+ " color: @os_chrome_fg_color;\n"
+ "}\n"
+ "\n"
+ "TopMenuAppMenuBar .menu .menuitem *:active {\n"
+ " color: @theme_text_color;\n"
+ "}\n"
+ "\n"
+ "TopMenuAppMenuBar .menu .menuitem *:selected {\n"
+ " color: @theme_selected_fg_color;\n"
+ "}\n";
+ if (gtk_css_provider_load_from_data(provider, css, -1, &error)) {
+ gtk_style_context_add_provider(style_context,
+ GTK_STYLE_PROVIDER(provider),
+ GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
+ } else {
+ g_warning("Error while loading CSS: %s", error->message);
+ g_error_free(error);
+ }
+#endif
+
self->app_menu_item = GTK_MENU_ITEM(gtk_menu_item_new_with_label(g_get_application_name()));
GtkLabel *app_label = GTK_LABEL(gtk_bin_get_child(GTK_BIN(self->app_menu_item)));
PangoAttrList *app_label_attr = pango_attr_list_new();
diff --git a/libtopmenu-client/topmenu-client.c b/libtopmenu-client/topmenu-client.c
index f7d3e58..cbc2d20 100644
--- a/libtopmenu-client/topmenu-client.c
+++ b/libtopmenu-client/topmenu-client.c
@@ -43,7 +43,7 @@ static gboolean handle_widget_button_event(GtkWidget *widget, GdkEvent *event, G
e.type = event->type == GDK_BUTTON_PRESS ? ButtonPress : ButtonRelease;
e.xbutton.window = xwin;
e.xbutton.display = dpy;
- e.xbutton.root = GDK_WINDOW_XWINDOW(root);
+ e.xbutton.root = gdk_x11_window_get_xid(root);
e.xbutton.time = event->button.time;
e.xbutton.button = event->button.button;
e.xbutton.state = event->button.state;
@@ -76,7 +76,7 @@ void topmenu_client_connect_window_widget(GdkWindow *window, GtkWidget *widget)
topmenu_client_disconnect_window(window);
}
- Window xwin = GDK_WINDOW_XID(window);
+ Window xwin = gdk_x11_window_get_xid(window);
GtkPlug *plug = GTK_PLUG(gtk_plug_new(0));
gtk_container_add(GTK_CONTAINER(plug), widget);
g_signal_connect_object(plug, "delete-event",
@@ -110,7 +110,7 @@ void topmenu_client_disconnect_window(GdkWindow *window)
gpointer window_data = g_object_steal_data(G_OBJECT(window), OBJECT_DATA_KEY_PLUG);
g_return_if_fail(window_data);
- Window xwin = GDK_WINDOW_XID(window);
+ Window xwin = gdk_x11_window_get_xid(window);
GtkPlug *plug = GTK_PLUG(window_data);
g_return_if_fail(plug);
diff --git a/libtopmenu-client/topmenu-monitor.c b/libtopmenu-client/topmenu-monitor.c
index 2f63e9b..94302ef 100644
--- a/libtopmenu-client/topmenu-monitor.c
+++ b/libtopmenu-client/topmenu-monitor.c
@@ -110,7 +110,7 @@ static void topmenu_monitor_dispose(GObject *obj)
if (self->priv->cur_server) {
gdk_window_remove_filter(self->priv->cur_server,
handle_cur_server_event, self);
- gdk_window_unref(self->priv->cur_server);
+ g_object_unref(self->priv->cur_server);
self->priv->cur_server = 0;
}
self->priv->selection = NULL;
diff --git a/libtopmenu-server/Makefile.am b/libtopmenu-server/Makefile.am
index 8a17f5f..98de595 100644
--- a/libtopmenu-server/Makefile.am
+++ b/libtopmenu-server/Makefile.am
@@ -1,7 +1,18 @@
-lib_LTLIBRARIES = libtopmenu-server.la
-libtopmenu_server_la_SOURCES = topmenu-server.c topmenu-server.h topmenu-widget.c topmenu-widget.h
-libtopmenu_server_la_CPPFLAGS = $(GTK_CFLAGS) $(WNCK_CFLAGS) $(MATEWNCK_CFLAGS) -DG_LOG_DOMAIN=\"topmenu-server\"
-libtopmenu_server_la_LIBADD = $(GTK_LIBS) $(WNCK_LIBS) $(MATEWNCK_LIBS)
+if GTK3
+
+lib_LTLIBRARIES = libtopmenu-server-gtk3.la
+libtopmenu_server_gtk3_la_SOURCES = topmenu-server.c topmenu-server.h topmenu-widget.c topmenu-widget.h
+libtopmenu_server_gtk3_la_CPPFLAGS = $(GTK_CFLAGS) $(WNCK_CFLAGS) $(MATEWNCK_CFLAGS) -DG_LOG_DOMAIN=\"topmenu-server\"
+libtopmenu_server_gtk3_la_LIBADD = $(GTK_LIBS) $(WNCK_LIBS) $(MATEWNCK_LIBS)
+
+else
+
+lib_LTLIBRARIES = libtopmenu-server-gtk2.la
+libtopmenu_server_gtk2_la_SOURCES = topmenu-server.c topmenu-server.h topmenu-widget.c topmenu-widget.h
+libtopmenu_server_gtk2_la_CPPFLAGS = $(GTK_CFLAGS) $(WNCK_CFLAGS) $(MATEWNCK_CFLAGS) -DG_LOG_DOMAIN=\"topmenu-server\"
+libtopmenu_server_gtk2_la_LIBADD = $(GTK_LIBS) $(WNCK_LIBS) $(MATEWNCK_LIBS)
+
+endif
include_HEADERS = topmenu-server.h topmenu-widget.h
diff --git a/libtopmenu-server/topmenu-widget.c b/libtopmenu-server/topmenu-widget.c
index 8121fc5..e4c51de 100644
--- a/libtopmenu-server/topmenu-widget.c
+++ b/libtopmenu-server/topmenu-widget.c
@@ -123,7 +123,7 @@ static void topmenu_widget_embed_topmenu_window(TopMenuWidget *self, Window wind
GdkWindow *cur = gtk_socket_get_plug_window(self->socket);
if (cur) {
- if (gdk_x11_window_get_xid(cur) == window) {
+ if (GDK_WINDOW_XID(cur) == window) {
// Trying to embed the same client again
return; // Nothing to do
}
diff --git a/libtopmenu-server/topmenu-widget.h b/libtopmenu-server/topmenu-widget.h
index 19d9784..1634bcc 100644
--- a/libtopmenu-server/topmenu-widget.h
+++ b/libtopmenu-server/topmenu-widget.h
@@ -3,7 +3,7 @@
#include <gtk/gtk.h>
-#if GTK_VERSION == 3
+#if GTK_MAJOR_VERSION == 3
#include <gtk/gtkx.h>
#endif
diff --git a/module/Makefile.am b/module/Makefile.am
index ac75b74..169d304 100644
--- a/module/Makefile.am
+++ b/module/Makefile.am
@@ -5,5 +5,5 @@ gtk_module_LTLIBRARIES = libtopmenu-gtk-module.la
libtopmenu_gtk_module_la_SOURCES = main.c data.c data.h \
menuitem-proxy.c menuitem-proxy.h appmenu.c appmenu.h
libtopmenu_gtk_module_la_CPPFLAGS = $(GTK_CFLAGS) -DG_LOG_DOMAIN=\"topmenu-module\"
-libtopmenu_gtk_module_la_LIBADD = $(GTK_LIBS) ../libtopmenu-client/libtopmenu-client.la
+libtopmenu_gtk_module_la_LIBADD = $(GTK_LIBS) ../libtopmenu-client/libtopmenu-client-gtk$(GTK_VERSION).la
libtopmenu_gtk_module_la_LDFLAGS = -avoid-version -module -shared
diff --git a/module/data.c b/module/data.c
index 9225d01..7af7e81 100644
--- a/module/data.c
+++ b/module/data.c
@@ -1,3 +1,11 @@
+#include <gtk/gtk.h>
+
+#include "../global.h"
+
+#if GTK_MAJOR_VERSION == 3
+#include <gtk/gtkx.h>
+#endif
+
#include "../libtopmenu-client/topmenu-monitor.h"
#include "data.h"
diff --git a/module/main.c b/module/main.c
index 42ea332..3672fd5 100644
--- a/module/main.c
+++ b/module/main.c
@@ -441,7 +441,7 @@ hijacked_application_window_realize (GtkWidget *widget)
if (pre_hijacked_application_window_realize != NULL)
(* pre_hijacked_application_window_realize) (widget);
- gtk_window_get_window_data (GTK_WINDOW (widget));
+ topmenu_get_window_data (GTK_WINDOW (widget));
}
#endif
@@ -536,7 +536,7 @@ hijacked_menu_bar_get_preferred_width (GtkWidget *widget,
if (pre_hijacked_menu_bar_get_preferred_width != NULL)
(* pre_hijacked_menu_bar_get_preferred_width) (widget, minimum_width, natural_width);
- if (gtk_widget_shell_shows_menubar (widget))
+ if (topmenu_should_hide_menubar(widget))
{
*minimum_width = 0;
*natural_width = 0;
@@ -553,7 +553,7 @@ hijacked_menu_bar_get_preferred_height (GtkWidget *widget,
if (pre_hijacked_menu_bar_get_preferred_height != NULL)
(* pre_hijacked_menu_bar_get_preferred_height) (widget, minimum_height, natural_height);
- if (gtk_widget_shell_shows_menubar (widget))
+ if (topmenu_should_hide_menubar(widget))
{
*minimum_height = 0;
*natural_height = 0;
@@ -571,7 +571,7 @@ hijacked_menu_bar_get_preferred_width_for_height (GtkWidget *widget,
if (pre_hijacked_menu_bar_get_preferred_width_for_height != NULL)
(* pre_hijacked_menu_bar_get_preferred_width_for_height) (widget, height, minimum_width, natural_width);
- if (gtk_widget_shell_shows_menubar (widget))
+ if (topmenu_should_hide_menubar(widget))
{
*minimum_width = 0;
*natural_width = 0;
@@ -589,7 +589,7 @@ hijacked_menu_bar_get_preferred_height_for_width (GtkWidget *widget,
if (pre_hijacked_menu_bar_get_preferred_height_for_width != NULL)
(* pre_hijacked_menu_bar_get_preferred_height_for_width) (widget, width, minimum_height, natural_height);
- if (gtk_widget_shell_shows_menubar (widget))
+ if (topmenu_should_hide_menubar(widget))
{
*minimum_height = 0;
*natural_height = 0;
diff --git a/module/menuitem-proxy.c b/module/menuitem-proxy.c
index 6a3e555..fbab6f1 100644
--- a/module/menuitem-proxy.c
+++ b/module/menuitem-proxy.c
@@ -39,6 +39,152 @@ static void init_static_data()
}
}
+#if GTK_MAJOR_VERSION == 3
+/* What could possibly go wrong? */
+typedef enum
+{
+ GTK_DIRECTION_LEFT,
+ GTK_DIRECTION_RIGHT
+} GtkSubmenuDirection;
+
+typedef enum
+{
+ GTK_TOP_BOTTOM,
+ GTK_LEFT_RIGHT
+} GtkSubmenuPlacement;
+
+struct _GtkMenuPrivate
+{
+ GtkWidget *parent_menu_item;
+ GtkWidget *old_active_menu_item;
+
+ GtkAccelGroup *accel_group;
+ gchar *accel_path;
+
+ GtkMenuPositionFunc position_func;
+ gpointer position_func_data;
+ GDestroyNotify position_func_data_destroy;
+ gint position_x;
+ gint position_y;
+
+ guint toggle_size;
+ guint accel_size;
+
+ GtkWidget *toplevel;
+
+ GtkWidget *tearoff_window;
+ GtkWidget *tearoff_hbox;
+ GtkWidget *tearoff_scrollbar;
+ GtkAdjustment *tearoff_adjustment;
+
+ GdkWindow *view_window;
+ GdkWindow *bin_window;
+
+ gint scroll_offset;
+ gint saved_scroll_offset;
+ gint scroll_step;
+
+ guint scroll_timeout;
+
+ guint needs_destruction_ref : 1;
+ guint torn_off : 1;
+ /* The tearoff is active when it is torn off and the not-torn-off
+ * menu is not popped up.
+ */
+ guint tearoff_active : 1;
+ guint scroll_fast : 1;
+
+ guint upper_arrow_visible : 1;
+ guint lower_arrow_visible : 1;
+ guint upper_arrow_prelight : 1;
+ guint lower_arrow_prelight : 1;
+
+ guint have_position : 1;
+ guint have_layout : 1;
+ guint seen_item_enter : 1;
+ guint ignore_button_release : 1;
+ guint no_toggle_size : 1;
+ guint drag_already_pressed : 1;
+ guint drag_scroll_started : 1;
+
+ /* info used for the table */
+ guint *heights;
+ gint heights_length;
+ gint requested_height;
+
+ gboolean initially_pushed_in;
+ gint monitor_num;
+
+ /* Cached layout information */
+ gint n_rows;
+ gint n_columns;
+
+ gchar *title;
+
+ /* Arrow states */
+ GtkStateFlags lower_arrow_state;
+ GtkStateFlags upper_arrow_state;
+
+ /* navigation region */
+ gint navigation_x;
+ gint navigation_y;
+ gint navigation_width;
+ gint navigation_height;
+
+ guint navigation_timeout;
+
+ gdouble drag_start_y;
+ gint initial_drag_offset;
+};
+
+struct _GtkMenuShellPrivate
+{
+ GList *children;
+
+ GtkWidget *active_menu_item;
+ GtkWidget *parent_menu_shell;
+ void *tracker;
+
+ guint button;
+ guint32 activate_time;
+
+ guint active : 1;
+ guint have_grab : 1;
+ guint have_xgrab : 1;
+ guint ignore_enter : 1;
+ guint keyboard_mode : 1;
+
+ guint take_focus : 1;
+ guint activated_submenu : 1;
+ guint in_unselectable_item : 1;
+};
+
+struct _GtkMenuItemPrivate
+{
+ GtkWidget *submenu;
+ GdkWindow *event_window;
+
+ guint16 toggle_size;
+ guint16 accelerator_width;
+
+ guint timer;
+
+ gchar *accel_path;
+
+ GtkAction *action;
+ void *action_helper;
+
+ guint show_submenu_indicator : 1;
+ guint submenu_placement : 1;
+ guint submenu_direction : 1;
+ guint right_justify : 1;
+ guint timer_from_keypress : 1;
+ guint from_menubar : 1;
+ guint use_action_appearance : 1;
+ guint reserve_indicator : 1;
+};
+#endif
+
static void
free_timeval (GTimeVal *val)
{
@@ -50,6 +196,23 @@ get_offsets (GtkMenu *menu,
gint *horizontal_offset,
gint *vertical_offset)
{
+#if GTK_MAJOR_VERSION == 3
+ GtkStyleContext *context;
+ GtkStateFlags state;
+ GtkBorder padding;
+
+ gtk_widget_style_get (GTK_WIDGET (menu),
+ "horizontal-offset", horizontal_offset,
+ "vertical-offset", vertical_offset,
+ NULL);
+
+ context = gtk_widget_get_style_context (GTK_WIDGET (menu));
+ state = gtk_widget_get_state_flags (GTK_WIDGET (menu));
+ gtk_style_context_get_padding (context, state, &padding);
+
+ *vertical_offset -= padding.top;
+ *horizontal_offset += padding.left;
+#else
gint vertical_padding;
gint horizontal_padding;
@@ -63,6 +226,7 @@ get_offsets (GtkMenu *menu,
*vertical_offset -= GTK_WIDGET (menu)->style->ythickness;
*vertical_offset -= vertical_padding;
*horizontal_offset += horizontal_padding;
+#endif
}
static void
@@ -72,6 +236,153 @@ menu_item_position_menu (GtkMenu *menu,
gboolean *push_in,
gpointer user_data)
{
+#if GTK_MAJOR_VERSION == 3
+ GtkMenuItem *menu_item = GTK_MENU_ITEM (user_data);
+ GtkMenuItemPrivate *priv = menu_item->priv;
+ GtkAllocation allocation;
+ GtkWidget *widget;
+ GtkMenuItem *parent_menu_item;
+ GtkWidget *parent;
+ GdkScreen *screen;
+ gint twidth, theight;
+ gint tx, ty;
+ GtkTextDirection direction;
+ GdkRectangle monitor;
+ gint monitor_num;
+ gint horizontal_offset;
+ gint vertical_offset;
+ gint available_left, available_right;
+ GtkStyleContext *context;
+ GtkStateFlags state;
+ GtkBorder parent_padding;
+
+ g_return_if_fail (menu != NULL);
+ g_return_if_fail (x != NULL);
+ g_return_if_fail (y != NULL);
+
+ widget = GTK_WIDGET (user_data);
+
+ if (push_in)
+ *push_in = FALSE;
+
+ direction = gtk_widget_get_direction (widget);
+
+ twidth = gtk_widget_get_allocated_width (GTK_WIDGET (menu));
+ theight = gtk_widget_get_allocated_height (GTK_WIDGET (menu));
+
+ screen = gtk_widget_get_screen (GTK_WIDGET (menu));
+ monitor_num = gdk_screen_get_monitor_at_window (screen, priv->event_window);
+ if (monitor_num < 0)
+ monitor_num = 0;
+ gdk_screen_get_monitor_workarea (screen, monitor_num, &monitor);
+
+ if (!gdk_window_get_origin (gtk_widget_get_window (widget), &tx, &ty))
+ {
+ g_warning ("Menu not on screen");
+ return;
+ }
+
+ gtk_widget_get_allocation (widget, &allocation);
+
+ tx += allocation.x;
+ ty += allocation.y;
+
+ get_offsets (menu, &horizontal_offset, &vertical_offset);
+
+ available_left = tx - monitor.x;
+ available_right = monitor.x + monitor.width - (tx + allocation.width);
+
+ parent = gtk_widget_get_parent (widget);
+ priv->from_menubar = GTK_IS_MENU_BAR (parent);
+
+ switch (priv->submenu_placement)
+ {
+ case GTK_TOP_BOTTOM:
+ if (direction == GTK_TEXT_DIR_LTR)
+ priv->submenu_direction = GTK_DIRECTION_RIGHT;
+ else
+ {
+ priv->submenu_direction = GTK_DIRECTION_LEFT;
+ tx += allocation.width - twidth;
+ }
+ if ((ty + allocation.height + theight) <= monitor.y + monitor.height)
+ ty += allocation.height;
+ else if ((ty - theight) >= monitor.y)
+ ty -= theight;
+ else if (monitor.y + monitor.height - (ty + allocation.height) > ty)
+ ty += allocation.height;
+ else
+ ty -= theight;
+ break;
+
+ case GTK_LEFT_RIGHT:
+ if (GTK_IS_MENU (parent))
+ parent_menu_item = GTK_MENU_ITEM (GTK_MENU (parent)->priv->parent_menu_item);
+ else
+ parent_menu_item = NULL;
+
+ context = gtk_widget_get_style_context (parent);
+ state = gtk_widget_get_state_flags (parent);
+ gtk_style_context_get_padding (context, state, &parent_padding);
+
+ if (parent_menu_item && !GTK_MENU (parent)->priv->torn_off)
+ {
+ priv->submenu_direction = parent_menu_item->priv->submenu_direction;
+ }
+ else
+ {
+ if (direction == GTK_TEXT_DIR_LTR)
+ priv->submenu_direction = GTK_DIRECTION_RIGHT;
+ else
+ priv->submenu_direction = GTK_DIRECTION_LEFT;
+ }
+
+ switch (priv->submenu_direction)
+ {
+ case GTK_DIRECTION_LEFT:
+ if (tx - twidth - parent_padding.left - horizontal_offset >= monitor.x ||
+ available_left >= available_right)
+ tx -= twidth + parent_padding.left + horizontal_offset;
+ else
+ {
+ priv->submenu_direction = GTK_DIRECTION_RIGHT;
+ tx += allocation.width + parent_padding.right + horizontal_offset;
+ }
+ break;
+
+ case GTK_DIRECTION_RIGHT:
+ if (tx + allocation.width + parent_padding.right + horizontal_offset + twidth <= monitor.x + monitor.width ||
+ available_right >= available_left)
+ tx += allocation.width + parent_padding.right + horizontal_offset;
+ else
+ {
+ priv->submenu_direction = GTK_DIRECTION_LEFT;
+ tx -= twidth + parent_padding.left + horizontal_offset;
+ }
+ break;
+ }
+
+ ty += vertical_offset;
+
+ /* If the height of the menu doesn't fit we move it upward. */
+ ty = CLAMP (ty, monitor.y, MAX (monitor.y, monitor.y + monitor.height - theight));
+ break;
+ }
+
+ /* If we have negative, tx, here it is because we can't get
+ * the menu all the way on screen. Favor the left portion.
+ */
+ *x = CLAMP (tx, monitor.x, MAX (monitor.x, monitor.x + monitor.width - twidth));
+ *y = ty;
+
+ gtk_menu_set_monitor (menu, monitor_num);
+
+ if (!gtk_widget_get_visible (menu->priv->toplevel))
+ {
+ gtk_window_set_type_hint (GTK_WINDOW (menu->priv->toplevel), priv->from_menubar?
+ GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU : GDK_WINDOW_TYPE_HINT_POPUP_MENU);
+ }
+#else
GtkMenuItem *menu_item;
GtkWidget *widget;
GtkMenuItem *parent_menu_item;
@@ -222,6 +533,7 @@ menu_item_position_menu (GtkMenu *menu,
gtk_window_set_type_hint (GTK_WINDOW (menu->toplevel), menu_item->from_menubar?
GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU : GDK_WINDOW_TYPE_HINT_POPUP_MENU);
}
+#endif
}
static void handle_menuitem_notify(GtkMenuItem *item, GParamSpec *pspec, GtkMenuItem *proxy)
@@ -251,7 +563,7 @@ static gboolean handle_menuitem_mnemonic_activate(GtkMenuItem *item, gboolean cy
if (parent && monitor->available) {
GtkMenuShell *parent_shell = GTK_MENU_SHELL(parent);
- if (GTK_IS_MENU_BAR(parent_shell) || parent_shell->active) {
+ if (GTK_IS_MENU_BAR(parent_shell) || parent_shell->priv->active) {
gtk_widget_mnemonic_activate(GTK_WIDGET(proxy), cycling);
return TRUE;
}
@@ -278,12 +590,13 @@ static void handle_parent_move_current(GtkMenuShell *shell, GtkMenuDirectionType
static void handle_proxy_select(GtkMenuItem *proxy, GtkMenuItem *item)
{
GtkWidget *submenu = gtk_menu_item_get_submenu(item);
+ GtkWidget *parent = gtk_widget_get_parent(GTK_WIDGET(proxy));
- if (submenu) {
+ if (submenu && parent) {
if (!gtk_widget_is_sensitive(GTK_WIDGET(submenu)))
return;
- GtkMenuShell *parent_shell = GTK_MENU_SHELL(GTK_WIDGET(proxy)->parent);
+ GtkMenuShell *parent_shell = GTK_MENU_SHELL(parent);
GTimeVal *popup_time = g_slice_new0(GTimeVal);
g_get_current_time(popup_time);
@@ -302,7 +615,7 @@ static void handle_proxy_select(GtkMenuItem *proxy, GtkMenuItem *item)
GTK_WIDGET(proxy),
menu_item_position_menu,
proxy,
- parent_shell->button,
+ parent_shell->priv->button,
0);
}
}
@@ -337,11 +650,8 @@ static void handle_proxy_activate_item(GtkMenuItem *proxy, GtkMenuItem *item)
if (submenu) {
GtkMenuShell *parent = GTK_MENU_SHELL(gtk_widget_get_parent(GTK_WIDGET(proxy)));
if (parent) {
- if (!parent->active) {
- //gtk_grab_add(GTK_WIDGET(parent));
- //parent->have_grab = TRUE;
- parent->active = TRUE;
- }
+ parent->priv->active = TRUE;
+ // We do not add grabs here, like Gtk+ does, because they are already done.
gtk_menu_shell_select_item(parent, GTK_WIDGET(proxy));
gtk_menu_shell_select_first(GTK_MENU_SHELL(submenu), TRUE);
}
@@ -358,9 +668,9 @@ static GtkWidget *construct_image_widget_proxy(GtkImage *widget)
gtk_image_get_stock(widget, &icon_name, &icon_size);
return gtk_image_new_from_stock(icon_name, icon_size);
case GTK_IMAGE_EMPTY:
- return gtk_image_new();
+ return NULL;
default:
- return gtk_image_new();
+ return NULL;
}
}
@@ -382,15 +692,15 @@ GtkMenuItem *topmenu_create_proxy_menu_item(GtkMenuItem *item)
if (iwidget) {
// Let's suppport some common widget types
if (GTK_IS_IMAGE(iwidget)) {
+ GtkImage *iwidgetimg = GTK_IMAGE(iwidget);
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(proxy),
- construct_image_widget_proxy(GTK_IMAGE(iwidget)));
+ construct_image_widget_proxy(iwidgetimg));
}
}
}
gtk_image_menu_item_set_always_show_image(GTK_IMAGE_MENU_ITEM(proxy),
gtk_image_menu_item_get_always_show_image(iitem));
- }
- else if (GTK_IS_SEPARATOR_MENU_ITEM(item)) {
+ } else if (GTK_IS_SEPARATOR_MENU_ITEM(item)) {
proxy = GTK_MENU_ITEM(gtk_separator_menu_item_new());
} else {
proxy = GTK_MENU_ITEM(gtk_menu_item_new_with_mnemonic(label));
diff --git a/test/Makefile.am b/test/Makefile.am
index 4455221..5a06736 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -5,8 +5,8 @@ AM_LDFLAGS = $(GTK_LIBS)
client_SOURCES = client.c
client_CPPFLAGS = $(GTK_CFLAGS)
-client_LDADD = $(GTK_LIBS) ../libtopmenu-client/libtopmenu-client.la
+client_LDADD = $(GTK_LIBS) ../libtopmenu-client/libtopmenu-client-gtk$(GTK_VERSION).la
server_SOURCES = server.c
server_CPPFLAGS = $(GTK_CFLAGS)
-server_LDADD = $(GTK_LIBS) ../libtopmenu-server/libtopmenu-server.la
+server_LDADD = $(GTK_LIBS) ../libtopmenu-server/libtopmenu-server-gtk$(GTK_VERSION).la
diff --git a/test/client.c b/test/client.c
index 08312e6..8aff036 100644
--- a/test/client.c
+++ b/test/client.c
@@ -19,25 +19,27 @@ static GtkWidget * create_menu_bar(void)
GtkLabel *app_label = GTK_LABEL(gtk_bin_get_child(GTK_BIN(app)));
gtk_label_set_markup(app_label, "<b>Client</b>");
- gtk_menu_bar_append(bar, GTK_WIDGET(app));
- gtk_menu_bar_append(bar, GTK_WIDGET(file));
- gtk_menu_bar_append(bar, GTK_WIDGET(edit));
- gtk_menu_bar_append(bar, GTK_WIDGET(help));
+ gtk_menu_shell_append(GTK_MENU_SHELL(bar), GTK_WIDGET(app));
+ gtk_menu_shell_append(GTK_MENU_SHELL(bar), GTK_WIDGET(file));
+ gtk_menu_shell_append(GTK_MENU_SHELL(bar), GTK_WIDGET(edit));
+ gtk_menu_shell_append(GTK_MENU_SHELL(bar), GTK_WIDGET(help));
GtkMenu *app_menu = GTK_MENU(gtk_menu_new());
GtkMenuItem *quit = GTK_MENU_ITEM(gtk_image_menu_item_new_from_stock(GTK_STOCK_QUIT, NULL));
- gtk_menu_append(app_menu, GTK_WIDGET(quit));
+ gtk_menu_shell_append(GTK_MENU_SHELL(app_menu), GTK_WIDGET(quit));
gtk_menu_item_set_submenu(app, GTK_WIDGET(app_menu));
GtkMenu *file_menu = GTK_MENU(gtk_menu_new());
GtkMenuItem *new = GTK_MENU_ITEM(gtk_image_menu_item_new_from_stock(GTK_STOCK_NEW, NULL));
- gtk_menu_append(file_menu, GTK_WIDGET(new));
+ gtk_menu_shell_append(GTK_MENU_SHELL(file_menu), GTK_WIDGET(new));
GtkMenuItem *open = GTK_MENU_ITEM(gtk_image_menu_item_new_from_stock(GTK_STOCK_OPEN, NULL));
- gtk_menu_append(file_menu, GTK_WIDGET(open));
+ gtk_menu_shell_append(GTK_MENU_SHELL(file_menu), GTK_WIDGET(open));
GtkMenuItem *close = GTK_MENU_ITEM(gtk_image_menu_item_new_from_stock(GTK_STOCK_CLOSE, NULL));
- gtk_menu_append(file_menu, GTK_WIDGET(close));
+ gtk_menu_shell_append(GTK_MENU_SHELL(file_menu), GTK_WIDGET(close));
gtk_menu_item_set_submenu(file, GTK_WIDGET(file_menu));
+ gtk_widget_show_all(GTK_WIDGET(bar));
+
return GTK_WIDGET(bar);
}
@@ -58,18 +60,18 @@ GtkWindow * create_main_window()
int main(int argc, char **argv)
{
- gtk_set_locale();
gtk_init(&argc, &argv);
mainwin = create_main_window();
- topmenu_monitor_get_instance();
g_signal_connect(mainwin, "destroy", G_CALLBACK(gtk_main_quit), NULL);
gtk_widget_realize(GTK_WIDGET(mainwin));
+#if 0
topmenu_client_connect_window_widget(gtk_widget_get_window(GTK_WIDGET(mainwin)),
create_menu_bar());
+#endif
gtk_widget_show_all(GTK_WIDGET(mainwin));
diff --git a/test/server.c b/test/server.c
index d0b9135..031ce61 100644
--- a/test/server.c
+++ b/test/server.c
@@ -22,7 +22,6 @@ static void construct_main_window()
int main(int argc, char **argv)
{
- gtk_set_locale();
gtk_init(&argc, &argv);
construct_main_window();