From: Hugo Villeneuve Date: Sat, 28 Feb 2015 22:06:58 +0000 (-0500) Subject: Add Gtk+-3 support X-Git-Url: http://gitweb.hugovil.com/?a=commitdiff_plain;h=dff722429ccd5c8a5fb5c6707fc01bdd527d8b31;p=dockapps%2Fdockbatmon.git Add Gtk+-3 support --- diff --git a/configure.ac b/configure.ac index 592d971..9482b8b 100644 --- a/configure.ac +++ b/configure.ac @@ -33,8 +33,67 @@ dnl Checking for X11 library. AC_CHECK_LIB(X11, XOpenDisplay, LIBS="${LIBS} -lX11", echo "Can't find X11 library" ; exit 1, "${X_LIBS}") -dnl Checks for Gtk+-2.0 -PKG_CHECK_MODULES(GTK, gtk+-2.0 >= 2.8, CFLAGS="${CFLAGS} -DGDK_PIXBUF_DISABLE_DEPRECATED -DGDK_DISABLE_DEPRECATED -DGTK_DISABLE_DEPRECATED") +dnl --with-gtk3 option +with_gtk3=no + +dnl Checks for Gtk+ (version 3 or 2) +GTK_TOOLKIT= +check_gtk2=no +gtk3_pkg_errors= + +dnl First test if Gtk+-3 is available +GLIB_REQUIRED=2.28 +GTK_REQUIRED=3.10 +GTK_MODULES="gtk+-3.0 >= $GTK_REQUIRED glib-2.0 >= $GLIB_REQUIRED" +PKG_CHECK_MODULES(GTK3, $GTK_MODULES, pkg_check_gtk=yes, pkg_check_gtk=no) + +if test "$pkg_check_gtk" = "no" && test "$with_gtk3" = "yes"; then + dnl Error if Gtk+-3 was explicitely requested, but is not found + AC_MSG_ERROR($GTK3_PKG_ERRORS) +fi +if test "$pkg_check_gtk" = "yes"; then + AC_DEFINE(HAVE_GTK3, 1, [Define to 1 if using GTK 3 or later.]) + GTK_TOOLKIT="GTK3" + if test "x$ac_enable_gtk_deprecation_warnings" = x; then + AC_DEFINE([GDK_DISABLE_DEPRECATION_WARNINGS], [1], + [Define to 1 to disable GTK+/GDK deprecation warnings.]) + AC_DEFINE([GLIB_DISABLE_DEPRECATION_WARNINGS], [1], + [Define to 1 to disable Glib deprecation warnings.]) + fi +else + dnl Gtk+-3 was not found, try to find Gtk+-2 + check_gtk2=yes + gtk3_pkg_errors="$GTK3_PKG_ERRORS " +fi + +if test "${with_gtk2}" = "yes" || test "$check_gtk2" = "yes"; then + dnl Test if Gtk+-2 is available + GLIB_REQUIRED=2.10 + GTK_REQUIRED=2.8 + GTK_MODULES="gtk+-2.0 >= $GTK_REQUIRED glib-2.0 >= $GLIB_REQUIRED" + PKG_CHECK_MODULES(GTK2, $GTK_MODULES, pkg_check_gtk=yes, pkg_check_gtk=no) + if test "$pkg_check_gtk" = "no" && test "$with_gtk2" = "yes"; then + AC_MSG_ERROR($gtk3_pkg_errors$GTK2_PKG_ERRORS) + fi + if test "$pkg_check_gtk" = "yes"; then + AC_DEFINE(HAVE_GTK2, 1, [Define to 1 if using GTK 2.]) + GTK_TOOLKIT="GTK2" + fi +fi + +if test "${GTK_TOOLKIT}" = "GTK3"; then + GTK_CFLAGS=$GTK3_CFLAGS + GTK_LIBS=$GTK3_LIBS +else +if test "${GTK_TOOLKIT}" = "GTK2"; then + GTK_CFLAGS=$GTK2_CFLAGS + GTK_LIBS=$GTK2_LIBS +else + dnl Error, no Gtk+-3 or Gtk+-2 was found + AC_MSG_ERROR([No suitable Gtk+ version found]) +fi +fi + AC_SUBST(GTK_CFLAGS) AC_SUBST(GTK_LIBS) diff --git a/src/batmon.c b/src/batmon.c index e8b3d73..c8781e1 100644 --- a/src/batmon.c +++ b/src/batmon.c @@ -221,7 +221,7 @@ display_capacity(cairo_t *cr) } static void -draw_background(GtkWidget *clock, cairo_t *cr) +draw_background(cairo_t *cr) { int y_start; int height; @@ -284,20 +284,34 @@ draw_background(GtkWidget *clock, cairo_t *cr) } static gboolean -batmon_expose(GtkWidget *clock, GdkEventExpose *event) +#if defined (HAVE_GTK2) +batmon_expose(GtkWidget *w, GdkEventExpose *event) +#elif defined (HAVE_GTK3) +batmon_handler(GtkWidget *w, cairo_t *cr, gpointer d G_GNUC_UNUSED) +#endif { +#if defined (HAVE_GTK2) cairo_t *cr; +#elif defined (HAVE_GTK3) + GdkRectangle rect; +#endif +#if defined (HAVE_GTK2) /* Get a cairo_t */ - cr = gdk_cairo_create(clock->window); + cr = gdk_cairo_create(gtk_widget_get_window(w)); cairo_rectangle(cr, event->area.x, event->area.y, - event->area.width, event->area.height); - cairo_clip(cr); + event->area.width, event->area.height); +#elif defined (HAVE_GTK3) + gdk_cairo_get_clip_rectangle(cr, &rect); + printf("Redrawing (%d,%d+%d+%d)\n", rect.x, rect.y, + rect.width, rect.height); - draw_background(clock, cr); + cairo_rectangle(cr, rect.x, rect.y, rect.width, rect.height); + cairo_clip(cr); +#endif - cairo_destroy(cr); + draw_background(cr); return TRUE; } @@ -319,8 +333,11 @@ batmon_redraw_canvas(GtkWidget *widget) } static gboolean -batmon_button_release(GtkWidget *clock, GdkEventButton *event) +batmon_button_release(GtkWidget *w, GdkEventButton *event) { + (void) event; /* Unused parameter. */ + (void) w; /* Unused parameter. */ + if (batmon_infos.debug) printf("%s: button released\n", PACKAGE_NAME); @@ -330,41 +347,36 @@ batmon_button_release(GtkWidget *clock, GdkEventButton *event) static gboolean dockapp_update(gpointer data) { - GtkWidget *clock = GTK_WIDGET(data); + GtkWidget *w = GTK_WIDGET(data); - batmon_redraw_canvas(clock); + batmon_redraw_canvas(w); return TRUE; /* keep running this event */ } void -batmon_init(GtkWidget *dockwin, GtkWidget *iconwin) +batmon_init(GtkWidget *win) { - gtk_widget_add_events(dockwin, GDK_BUTTON_PRESS_MASK | - GDK_BUTTON_RELEASE_MASK | - GDK_POINTER_MOTION_MASK); - gtk_widget_add_events(iconwin, GDK_BUTTON_PRESS_MASK | + gtk_widget_add_events(win, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK); - g_signal_connect(G_OBJECT(dockwin), "expose-event", - G_CALLBACK(batmon_expose), NULL); - g_signal_connect(G_OBJECT(iconwin), "expose-event", +#if defined (HAVE_GTK2) + g_signal_connect(G_OBJECT(win), "expose-event", G_CALLBACK(batmon_expose), NULL); - - g_signal_connect(G_OBJECT(dockwin), "button-press-event", - G_CALLBACK(batmon_button_release), NULL); - g_signal_connect(G_OBJECT(iconwin), "button-press-event", - G_CALLBACK(batmon_button_release), NULL); - g_signal_connect(G_OBJECT(dockwin), "button-release-event", +#elif defined (HAVE_GTK3) + g_signal_connect(G_OBJECT(win), "draw", + G_CALLBACK(draw_handler), NULL); +#endif + g_signal_connect(G_OBJECT(win), "button-press-event", G_CALLBACK(batmon_button_release), NULL); - g_signal_connect(G_OBJECT(iconwin), "button-release-event", + g_signal_connect(G_OBJECT(win), "button-release-event", G_CALLBACK(batmon_button_release), NULL); - dockapp_set_mask(iconwin, dockapp_mask_xpm); + dockapp_set_mask(win, dockapp_mask_xpm); /* update the battery status once per second */ - g_timeout_add(1000, dockapp_update, iconwin); + g_timeout_add(1000, dockapp_update, win); - batmon_redraw_canvas(iconwin); + batmon_redraw_canvas(win); } diff --git a/src/batmon.h b/src/batmon.h index 0bc56ec..aa4734d 100644 --- a/src/batmon.h +++ b/src/batmon.h @@ -12,6 +12,6 @@ #include void -batmon_init(GtkWidget *dockwin, GtkWidget *iconwin); +batmon_init(GtkWidget *win); #endif /* BATMON_H */ diff --git a/src/dockapp.c b/src/dockapp.c index 98450d3..0ab272b 100644 --- a/src/dockapp.c +++ b/src/dockapp.c @@ -35,15 +35,20 @@ /* Width and height in pixels of Window Maker icons. */ #define ICON_SIZE 64 +#ifdef GTK_WITHDRAWN_HACK + static void -dockapp_set_withdrawn_state(Display *d, Window w) +dockapp_set_withdrawn_state(Display *d, Window mw, Window iw) { XWMHints *hints; - hints = XGetWMHints(d, w); - hints->flags |= StateHint; - hints->initial_state = WithdrawnState; - XSetWMHints(d, w, hints); + hints = XGetWMHints(d, mw); + if (!hints) { + hints = XAllocWMHints(); + } + hints->flags |= IconWindowHint; + hints->icon_window = iw; + XSetWMHints(d, mw, hints); XFree(hints); } @@ -66,44 +71,79 @@ dockapp_gtk_withdrawn_hack(GtkWidget *dockwin, GtkWidget *iconwin) unsigned int nchildren; Window win_temp; Window win_orig; + Window iw; d = GDK_DISPLAY_XDISPLAY(gdk_display_get_default()); - win_orig = GDK_WINDOW_XID(dockwin->window); + win_orig = GDK_WINDOW_XID(gtk_widget_get_window(dockwin)); + iw = GDK_WINDOW_XID(gtk_widget_get_window(iconwin)); XQueryTree(d, win_orig, &root, &p, &children, &nchildren); - if (children) XFree(children); win_temp = XCreateSimpleWindow(d, p, 0, 0, 1, 1, 0, 0, 0); XReparentWindow(d, win_orig, win_temp, 0, 0); gtk_widget_show(dockwin); + gtk_widget_show(iconwin); - dockapp_set_withdrawn_state(d, win_orig); + dockapp_set_withdrawn_state(d, win_orig, iw); XReparentWindow(d, win_orig, p, 0, 0); XDestroyWindow(d, win_temp); } +#endif /* GTK_WITHDRAWN_HACK */ + void dockapp_set_mask(GtkWidget *iconwin, char **xpm) { GdkPixbuf *pixbuf; +#if defined (HAVE_GTK2) GdkPixmap *pixmap; GdkBitmap *mask; +#elif defined (HAVE_GTK3) + cairo_surface_t *surface; + cairo_region_t *shape; +#endif pixbuf = gdk_pixbuf_new_from_xpm_data((const char **)xpm); + if (!pixbuf) { + fprintf(stderr, "Could not load pixbuf\n"); + exit(1); + } +#if defined (HAVE_GTK2) gdk_pixbuf_render_pixmap_and_mask(pixbuf, &pixmap, &mask, 127); - - g_object_unref(pixbuf); - if (!pixmap) { - printf("Could not load pixmap\n"); + fprintf(stderr, "Could not load pixmap\n"); exit(1); } gtk_widget_shape_combine_mask(iconwin, mask, 0, 0); +#elif defined (HAVE_GTK3) + surface = gdk_cairo_surface_create_from_pixbuf( + pixbuf, 0, + gtk_widget_get_window(iconwin)); + shape = gdk_cairo_region_create_from_surface(surface); + cairo_surface_destroy(surface); + gtk_widget_shape_combine_region(iconwin, shape); + cairo_region_destroy(shape); +#endif + g_object_unref(pixbuf); +} + +static GtkWidget * +dockapp_win_init(GtkWindowType window_type) +{ + GtkWidget *win; + + win = gtk_window_new(window_type); + gtk_window_set_wmclass(GTK_WINDOW(win), g_get_prgname(), "DockApp"); + gtk_widget_set_size_request(win, ICON_SIZE, ICON_SIZE); + gtk_widget_set_app_paintable(win, true); + gtk_widget_realize(win); + + return win; } /******************************************************************************* @@ -117,33 +157,25 @@ dockapp_init(int argc, char *argv[]) gtk_init(&argc, &argv); - dockwin = gtk_window_new(GTK_WINDOW_TOPLEVEL); - iconwin = gtk_window_new(GTK_WINDOW_POPUP); - - gtk_window_set_wmclass(GTK_WINDOW(dockwin), g_get_prgname(), "DockApp"); - gtk_window_set_wmclass(GTK_WINDOW(iconwin), g_get_prgname(), "DockApp"); - - gtk_widget_set_size_request(dockwin, ICON_SIZE, ICON_SIZE); - gtk_widget_set_size_request(iconwin, ICON_SIZE, ICON_SIZE); - gtk_widget_set_app_paintable(dockwin, TRUE); - gtk_widget_set_app_paintable(iconwin, TRUE); + dockwin = dockapp_win_init(GTK_WINDOW_TOPLEVEL); + iconwin = dockapp_win_init(GTK_WINDOW_POPUP); gtk_window_set_default_size(GTK_WINDOW(dockwin), ICON_SIZE, ICON_SIZE); - g_signal_connect(dockwin, "destroy", G_CALLBACK(gtk_main_quit), NULL); - gtk_widget_realize(dockwin); - gtk_widget_realize(iconwin); - gdk_window_set_icon(dockwin->window, iconwin->window, NULL, NULL); - - batmon_init(dockwin, iconwin); + /* Sets the icon of dockwin as iconwin. */ +#if defined (HAVE_GTK2) + gdk_window_set_icon(gtk_widget_get_window(dockwin), + gtk_widget_get_window(iconwin), NULL, NULL); +#endif + batmon_init(iconwin); gtk_widget_show(iconwin); #ifdef GTK_WITHDRAWN_HACK dockapp_gtk_withdrawn_hack(dockwin, iconwin); #else gtk_widget_show(dockwin); - gdk_window_withdraw(dockwin->window); + gdk_window_withdraw(gtk_widget_get_window(dockwin)); #endif }