From: Hugo Villeneuve Date: Sun, 21 Dec 2014 23:32:35 +0000 (-0500) Subject: Add Gtk+-3 support X-Git-Url: http://gitweb.hugovil.com/?a=commitdiff_plain;h=c2ef7661a6d0173668e30bf43f2270ca897faddf;p=dockapps%2Fhvclock.git Add Gtk+-3 support --- diff --git a/configure.ac b/configure.ac index 28892cc..85b50b0 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/clock.c b/src/clock.c index 05964b5..3fa1d36 100644 --- a/src/clock.c +++ b/src/clock.c @@ -82,9 +82,11 @@ /* Starting mode is clock mode */ static int hvclock_mode = CLOCK_MODE; +#if defined (HAVE_GTK2) /* In preparation for Gtk+-3 support. */ #define gtk_widget_get_allocated_width(_widget_) _widget_->allocation.width #define gtk_widget_get_allocated_height(_widget_) _widget_->allocation.height +#endif static double get_clock_face_radius(GtkWidget *clock) @@ -377,16 +379,32 @@ draw_calendar(GtkWidget *clock, cairo_t *cr) } static gboolean +#if defined (HAVE_GTK2) hvclock_expose(GtkWidget *clock, GdkEventExpose *event) +#elif defined (HAVE_GTK3) +draw_handler(GtkWidget *clock, 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(gtk_widget_get_window(clock)); cairo_rectangle(cr, event->area.x, event->area.y, - event->area.width, event->area.height); + 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); + + cairo_rectangle(cr, rect.x, rect.y, rect.width, rect.height); cairo_clip(cr); +#endif if (hvclock_mode == CLOCK_MODE) { dockapp_set_mask(clock, clock_mask_xpm); @@ -397,25 +415,36 @@ hvclock_expose(GtkWidget *clock, GdkEventExpose *event) draw_calendar(clock, cr); } - cairo_destroy(cr); - return TRUE; } static void hvclock_redraw_canvas(GtkWidget *widget) { +#if defined (HAVE_GTK2) GdkRegion *region; +#elif defined (HAVE_GTK3) + cairo_region_t *region; +#endif if (!gtk_widget_get_window(widget)) return; +#if defined (HAVE_GTK2) region = gdk_drawable_get_clip_region(gtk_widget_get_window(widget)); +#elif defined (HAVE_GTK3) + region = gdk_window_get_clip_region(gtk_widget_get_window(widget)); +#endif + /* redraw the cairo canvas completely by exposing it */ gdk_window_invalidate_region(gtk_widget_get_window(widget), region, TRUE); gdk_window_process_updates(gtk_widget_get_window(widget), TRUE); +#if defined (HAVE_GTK2) gdk_region_destroy(region); +#elif defined (HAVE_GTK3) + cairo_region_destroy(region); +#endif } static gboolean @@ -481,9 +510,13 @@ hvclock_init(GtkWidget *win) GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK); +#if defined (HAVE_GTK2) g_signal_connect(G_OBJECT(win), "expose-event", G_CALLBACK(hvclock_expose), NULL); - +#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(hvclock_button_release), NULL); g_signal_connect(G_OBJECT(win), "button-release-event", diff --git a/src/dockapp.c b/src/dockapp.c index 8ded719..f01c9f9 100644 --- a/src/dockapp.c +++ b/src/dockapp.c @@ -38,14 +38,17 @@ #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); } @@ -68,22 +71,22 @@ dockapp_gtk_withdrawn_hack(GtkWidget *dockwin, GtkWidget *iconwin) unsigned int nchildren; Window win_temp; Window win_orig; - - (void) iconwin; /* Unused parameter. */ + Window iw; d = GDK_DISPLAY_XDISPLAY(gdk_display_get_default()); 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); @@ -95,15 +98,22 @@ 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) { fprintf(stderr, "Could not load pixmap\n"); exit(1); @@ -112,6 +122,16 @@ dockapp_set_mask(GtkWidget *iconwin, char **xpm) gtk_widget_shape_combine_mask(iconwin, mask, 0, 0); g_object_unref(mask); g_object_unref(pixmap); +#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 * @@ -146,7 +166,10 @@ dockapp_init(int argc, char *argv[]) g_signal_connect(dockwin, "destroy", G_CALLBACK(gtk_main_quit), NULL); /* Sets the icon of dockwin as iconwin. */ - gdk_window_set_icon(gtk_widget_get_window(dockwin), gtk_widget_get_window(iconwin), NULL, NULL); +#if defined (HAVE_GTK2) + gdk_window_set_icon(gtk_widget_get_window(dockwin), + gtk_widget_get_window(iconwin), NULL, NULL); +#endif hvclock_init(iconwin); gtk_widget_show(iconwin);