Control: tags -1 + patch

Please find attached a patch which I tested as much as I can.

There is one major problem with it -- the scroll text showing the song
title (if it's in Latin) is moving much faster than before.

I compared the pace of the loop in real_draw_scrolltext between the
current package in unstable and a locally built one with my patch;
it's much faster with GTK 3.  I couldn't find a way to solve it:
adding a timeout big enough makes text appear in batches, and other
tricks with nanosleep just slow down the whole program.

Let me know if there are problems, I'll do my best to fix them.
Description: Port to GTK 3.
Bug-Debian: https://bugs.debian.org/967805
Author: Yavor Doganov <[email protected]>
Forwarded: no
Last-Update: 2026-01-10
---

--- wmauda.orig/Makefile
+++ wmauda/Makefile
@@ -11,8 +11,8 @@
 CFLAGS 	+= $(shell $(PKG_CONFIG) dbus-glib-1 --cflags) -DPIXMAP_DIR="\"$(PIXMAP_DIR)\""
 LIBS 	:= $(shell $(PKG_CONFIG) audclient --libs)  $(shell $(PKG_CONFIG) dbus-glib-1 --libs)
 
-CFLAGS  += $(shell $(PKG_CONFIG) gtk+-2.0 --cflags)
-LIBS    += $(shell $(PKG_CONFIG) gtk+-2.0 --libs) -lX11
+CFLAGS  += $(shell $(PKG_CONFIG) gtk+-3.0 --cflags)
+LIBS    += $(shell $(PKG_CONFIG) gtk+-3.0 --libs) -lX11
 
 OBJS 	= wmauda.o
 HEADERS = dock-master.xpm
--- wmauda.orig/wmauda.c
+++ wmauda/wmauda.c
@@ -113,7 +113,7 @@
 #define SEEKSLIDER_KNOB_WIDTH	3
 #define SEEKSLIDER_MAX		(SEEKSLIDER_WIDTH - SEEKSLIDER_KNOB_WIDTH)
 
-#define SCROLLTEXT_X		5
+#define SCROLLTEXT_X		6
 #define SCROLLTEXT_Y		6
 #define SCROLLTEXT_WIDTH	40
 #define SCROLLTEXT_HEIGHT	9 
@@ -129,10 +129,9 @@
 void init(void);
 
 GtkWidget *icon_win;
-GdkPixmap *pixmap, *launch_pixmap;
-GdkBitmap *mask, *launch_mask;
-GdkGC *dock_gc;
-GtkTooltips *tooltips = NULL;
+GdkWindow *win;
+cairo_surface_t *pixmap, *launch_pixmap;
+cairo_t *cr;
 
 char *xmms_cmd = "audacious";
 gboolean xmms_running = FALSE;
@@ -187,24 +186,30 @@
 	return FALSE;
 }
 
-void real_draw_button(GdkWindow *w, Button *button)
+void draw_button(Button *button)
 {
 
 	if (button->pressed)
-		gdk_draw_pixmap(w, dock_gc, pixmap,
-				button->pressed_x, button->pressed_y,
-				button->x, button->y,
+	{
+		cairo_set_source_surface(cr, pixmap,
+					 button->x - button->pressed_x,
+					 button->y - button->pressed_y);
+		cairo_rectangle(cr, button->x, button->y,
 				button->width, button->height);
+		cairo_fill(cr);
+	}
 	else
-		gdk_draw_pixmap(w, dock_gc, pixmap,
-				button->normal_x, button->normal_y,
-				button->x, button->y,
+	{
+		cairo_set_source_surface(cr, pixmap,
+					 button->x - button->normal_x,
+					 button->y - button->normal_y);
+		cairo_rectangle(cr, button->x, button->y,
 				button->width, button->height);
-}
+		cairo_fill(cr);
+	}
 
-void draw_button(Button *button)
-{
-	real_draw_button(icon_win->window, button);
+	gtk_widget_queue_draw_area(icon_win, button->x, button->y,
+				   button->width, button->height);
 }
 
 void draw_buttons(GList *list)
@@ -213,51 +218,61 @@
 		draw_button(list->data);
 }
 
-void real_draw_volslider(GdkWindow *w)
+void draw_volslider(void)
 {
-	gdk_draw_pixmap(w, dock_gc, pixmap, 112, 1, VOLSLIDER_X, VOLSLIDER_Y,
+	cairo_set_source_surface(cr, pixmap, VOLSLIDER_X - 112,
+				 VOLSLIDER_Y - 1);
+	cairo_rectangle(cr, VOLSLIDER_X, VOLSLIDER_Y,
 			VOLSLIDER_WIDTH, VOLSLIDER_HEIGHT);
-	gdk_draw_pixmap(w, dock_gc, pixmap, 106,
-			1 + VOLSLIDER_HEIGHT - volslider_pos,
-			VOLSLIDER_X,
+	cairo_fill(cr);
+	cairo_set_source_surface(cr, pixmap, VOLSLIDER_X - 106,
+				 VOLSLIDER_Y - 1);
+	cairo_rectangle(cr, VOLSLIDER_X,
 			VOLSLIDER_Y + VOLSLIDER_HEIGHT - volslider_pos,
 			VOLSLIDER_WIDTH, volslider_pos);
-}
+	cairo_fill(cr);
 
-void draw_volslider(void)
-{
-	real_draw_volslider(icon_win->window);
+	gtk_widget_queue_draw_area(icon_win,
+				   VOLSLIDER_X, VOLSLIDER_Y,
+				   VOLSLIDER_WIDTH, VOLSLIDER_HEIGHT);
 }
 
-void real_draw_seekslider(GdkWindow *w)
+void draw_seekslider(void)
 {
 	int slider_x;
 
 	if (seekslider_visible)
 	{
-		gdk_draw_pixmap(w, dock_gc, pixmap, 66, 54,
-				SEEKSLIDER_X, SEEKSLIDER_Y, 35, 10);
+		cairo_set_source_surface(cr, pixmap, SEEKSLIDER_X - 66,
+					 SEEKSLIDER_Y - 54);
+		cairo_rectangle(cr, SEEKSLIDER_X, SEEKSLIDER_Y, 35, 10);
+		cairo_fill(cr);
 		if (seekslider_pos < SEEKSLIDER_MAX / 3)
 			slider_x = 108;
 		else if (seekslider_pos < (SEEKSLIDER_MAX * 2) / 3)
 			slider_x = 111;
 		else
 			slider_x = 114;
-		gdk_draw_pixmap(w, dock_gc, pixmap, slider_x, 48,
-				SEEKSLIDER_X + seekslider_pos,
+		cairo_set_source_surface(cr, pixmap,
+					 SEEKSLIDER_X + seekslider_pos - slider_x,
+					 SEEKSLIDER_Y - 48);
+		cairo_rectangle(cr, SEEKSLIDER_X + seekslider_pos,
 				SEEKSLIDER_Y, 3, SEEKSLIDER_HEIGHT);
+		cairo_fill(cr);
 	}
 	else
-		gdk_draw_pixmap(w, dock_gc, pixmap, 66, 39,
-				SEEKSLIDER_X, SEEKSLIDER_Y, 35, 10);
-}
+	{
+		cairo_set_source_surface(cr, pixmap, SEEKSLIDER_X - 66,
+					 SEEKSLIDER_Y - 39);
+		cairo_rectangle(cr, SEEKSLIDER_X, SEEKSLIDER_Y, 35, 10);
+		cairo_fill(cr);
+	}
 
-void draw_seekslider(void)
-{
-	real_draw_seekslider(icon_win->window);
+	gtk_widget_queue_draw_area(icon_win, SEEKSLIDER_X, SEEKSLIDER_Y,
+				   35, 10);
 }
 
-void real_draw_scrolltext(GdkWindow * w)
+void draw_scrolltext(void)
 {
         /* get titlestring */
 	gint pl_pos = audacious_remote_get_playlist_pos(dbus_proxy);
@@ -300,9 +315,11 @@
 					    break;
 					}
 				}
-				gdk_draw_pixmap(w, dock_gc, pixmap, x, y, 
-						dest, SCROLLTEXT_Y, 7, 9);
 
+				cairo_set_source_surface(cr, pixmap, dest - x,
+							 SCROLLTEXT_Y - y);
+				cairo_rectangle(cr, dest, SCROLLTEXT_Y, 7, 9);
+				cairo_fill(cr);
 			}
 			scrollpos++;
 			g_free(title);
@@ -310,17 +327,19 @@
 	}
 }
 
-void draw_scrolltext(void)
+void redraw_window(void)
 {
-	real_draw_scrolltext(icon_win->window);
+	gtk_widget_queue_draw(icon_win);
 }
 
-void redraw_window(void)
+void draw_cb(GtkWidget *w, cairo_t *draw_cr, gpointer data)
 {
+	cr = draw_cr;
+
 	if (xmms_running)
 	{
-		gdk_draw_pixmap(icon_win->window, dock_gc, pixmap,
-				0, 0, 0, 0, 64, 64);
+		cairo_set_source_surface(cr, pixmap, 0, 0);
+		cairo_paint(cr);
 		draw_buttons(button_list);
 		draw_volslider();
 		draw_seekslider();
@@ -328,16 +347,11 @@
 	}
 	else
 	{
-		gdk_draw_pixmap(icon_win->window, dock_gc, launch_pixmap,
-				0, 0, 0, 0, 64, 64);
+		cairo_set_source_surface(cr, launch_pixmap, 8, 8);
+		cairo_paint(cr);
 	}
 }
 
-void expose_cb(GtkWidget *w, GdkEventExpose *event, gpointer data)
-{
-	redraw_window();
-}
-
 void wheel_scroll_cb(GtkWidget *w, GdkEventScroll *event)
 {
 	if (xmms_running)
@@ -503,7 +517,7 @@
 
 void destroy_cb(GtkWidget *w, gpointer data)
 {
-	gtk_exit(0);
+	gtk_main_quit();
 }
 
 static void update_tooltip(void)
@@ -512,7 +526,7 @@
 	static char *filename;
 	int new_pos;
 	
-	if (!tooltips)
+	if (!song_title)
 		return;
 	
 	new_pos = audacious_remote_get_playlist_pos(dbus_proxy);
@@ -553,7 +567,7 @@
 			tip = g_strdup_printf("%d. %s", new_pos+1, title);
 			g_free(title);
 		}
-		gtk_tooltips_set_tip(tooltips, icon_win, tip, NULL);
+		gtk_widget_set_tooltip_text(icon_win, tip);
 		g_free(tip);
 		pl_pos = new_pos;
 	}
@@ -563,6 +577,7 @@
 {
 	int new_pos, pos;
 	gboolean playing, running;
+	cairo_region_t *rgn;
 
 	running = audacious_remote_is_running(dbus_proxy);
 
@@ -570,7 +585,9 @@
 	{
 		if (!xmms_running)
 		{
-			gtk_widget_shape_combine_mask(icon_win, mask, 0, 0);
+			rgn = gdk_cairo_region_create_from_surface(pixmap);
+			gdk_window_shape_combine_region(win, rgn, 0, 0);
+			cairo_region_destroy(rgn);
 			xmms_running = running;
 			redraw_window();
 		}
@@ -593,6 +610,11 @@
 		update_tooltip();
 		draw_scrolltext();
 
+		gtk_widget_queue_draw_area(icon_win, SCROLLTEXT_X,
+					   SCROLLTEXT_Y,
+					   SCROLLTEXT_WIDTH + 10,
+					   SCROLLTEXT_HEIGHT);
+
 		playing = audacious_remote_is_playing(dbus_proxy);
 		if (!playing && seekslider_visible)
 		{
@@ -636,9 +658,10 @@
 	{
 		if (xmms_running)
 		{
-			if (tooltips != NULL)
-				gtk_tooltips_set_tip(tooltips, icon_win, NULL, NULL);
-			gtk_widget_shape_combine_mask(icon_win, launch_mask, 0, 0);
+			gtk_widget_set_tooltip_text(icon_win, NULL);
+			rgn = gdk_cairo_region_create_from_surface(launch_pixmap);
+			gdk_window_shape_combine_region(win, rgn, 8, 8);
+			cairo_region_destroy(rgn);
 			xmms_running = FALSE;
 			redraw_window();
 		}
@@ -651,9 +674,9 @@
 			int x, int y, GtkSelectionData *selection_data,
 			guint info, guint time)
 {
-	if (selection_data->data)
+	if (gtk_selection_data_get_data(selection_data))
 	{
-		char *url = selection_data->data;
+		char *url = (char*)gtk_selection_data_get_data(selection_data);
 		audacious_remote_playlist_clear(dbus_proxy);
 		audacious_remote_playlist_add_url_string(dbus_proxy, url);
 		audacious_remote_play(dbus_proxy);
@@ -680,119 +703,100 @@
 void init(void)
 {
 	GdkWindowAttr attr;
-	GdkColor bg_color;
+	GdkPixbuf *pixbuf;
 	GdkWindow *leader;
+	GInputStream *stream;
+	GString *xpm;
 	XWMHints hints;
+	cairo_region_t *rgn;
 	int i, w, h;
-	GdkGC *mask_gc;
 
 	for (i = 0; i < NUM_BUTTONS; i++)
 		button_list = g_list_append(button_list, &buttons[i]);
 
-	if (song_title)
-	{
-		tooltips = gtk_tooltips_new();
-		gtk_tooltips_set_delay(tooltips, 1000);
-	}
-		
 	icon_win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
 	gtk_widget_set_app_paintable(icon_win, TRUE);
-	gtk_widget_set_uposition(icon_win, 0, 0);
-	gtk_widget_set_usize(icon_win, 64, 64);
+	gtk_widget_set_size_request(icon_win, 64, 64);
 	gtk_widget_set_events(icon_win,
 			      GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK |
 			      GDK_BUTTON_RELEASE_MASK | GDK_EXPOSURE_MASK);
-	gtk_signal_connect(GTK_OBJECT(icon_win), "expose_event",
-			   GTK_SIGNAL_FUNC(expose_cb), NULL);
-	gtk_signal_connect(GTK_OBJECT(icon_win), "button_press_event",
-			   GTK_SIGNAL_FUNC(button_press_cb), NULL);
-	gtk_signal_connect(GTK_OBJECT(icon_win), "scroll_event",
-			   GTK_SIGNAL_FUNC(wheel_scroll_cb), NULL);
-	gtk_signal_connect(GTK_OBJECT(icon_win), "button_release_event",
-			   GTK_SIGNAL_FUNC(button_release_cb), NULL);
-	gtk_signal_connect(GTK_OBJECT(icon_win), "motion_notify_event",
-			   GTK_SIGNAL_FUNC(motion_notify_cb), NULL);
-	gtk_signal_connect(GTK_OBJECT(icon_win), "destroy",
-			   GTK_SIGNAL_FUNC(destroy_cb), NULL);
+	g_signal_connect(icon_win, "draw",
+			 G_CALLBACK(draw_cb), NULL);
+	g_signal_connect(icon_win, "button_press_event",
+			 G_CALLBACK(button_press_cb), NULL);
+	g_signal_connect(icon_win, "scroll_event",
+			 G_CALLBACK(wheel_scroll_cb), NULL);
+	g_signal_connect(icon_win, "button_release_event",
+			 G_CALLBACK(button_release_cb), NULL);
+	g_signal_connect(icon_win, "motion_notify_event",
+			 G_CALLBACK(motion_notify_cb), NULL);
+	g_signal_connect(icon_win, "destroy",
+			 G_CALLBACK(destroy_cb), NULL);
 	gtk_drag_dest_set(icon_win, GTK_DEST_DEFAULT_ALL, drop_types, 1,
 			  GDK_ACTION_COPY);
-	gtk_signal_connect(GTK_OBJECT(icon_win), "drag_data_received",
-			   GTK_SIGNAL_FUNC(drag_data_received), NULL);
+	g_signal_connect(icon_win, "drag_data_received",
+			 G_CALLBACK(drag_data_received), NULL);
 	gtk_widget_realize(icon_win);
-	bg_color.red = 0;
-	bg_color.green = 0;
-	bg_color.blue = 0;
-	gdk_colormap_alloc_color(gdk_colormap_get_system(),
-				 &bg_color, FALSE, TRUE);
-	gdk_window_set_background(icon_win->window, &bg_color);
-	gdk_window_clear(icon_win->window);
-	dock_gc = gdk_gc_new(icon_win->window);
-
-	launch_pixmap = gdk_pixmap_new(icon_win->window, 64, 64, -1);
-
-	launch_mask = gdk_pixmap_new(icon_win->window, 64, 64, 1);
-	mask_gc = gdk_gc_new(launch_mask);
-	bg_color.pixel = 0;
-	gdk_gc_set_foreground(mask_gc, &bg_color);
-	gdk_draw_rectangle(launch_mask, mask_gc, TRUE, 0, 0, -1, -1);
 
 	if (!icon_name)
 		icon_name = g_strdup_printf("%s/wmauda.xpm", PIXMAP_DIR);
-	pixmap = gdk_pixmap_create_from_xpm(icon_win->window, &mask,
-					    NULL, icon_name);
-	if (!pixmap)
+	pixbuf = gdk_pixbuf_new_from_file(icon_name, NULL);
+	if (!pixbuf)
 	{
 		printf("ERROR: Couldn't find %s\n", icon_name);
 		g_free(icon_name);
-		gtk_exit(1);
+		exit(EXIT_FAILURE);
 	}
 	g_free(icon_name);
-	gdk_window_get_size(pixmap, &w, &h);
-	if (w > 64)
-		w = 64;
-	if (h > 64)
-		h = 64;
-	gdk_draw_pixmap(launch_pixmap, dock_gc, pixmap,
-			0, 0, 32 - (w / 2), 32 - (h / 2), w, h);
-	gdk_draw_pixmap(launch_mask, mask_gc, mask,
-			0, 0, 32 - (w / 2), 32 - (h / 2), w, h);
-	gdk_gc_unref(mask_gc);
-	gdk_pixmap_unref(pixmap);
-	gdk_bitmap_unref(mask);
 
-	gtk_widget_shape_combine_mask(icon_win, launch_mask, 0, 0);
+	win = gtk_widget_get_window(icon_win);
+	launch_pixmap = gdk_cairo_surface_create_from_pixbuf(pixbuf, 0, win);
+	g_object_unref(pixbuf);
+
+	rgn = gdk_cairo_region_create_from_surface(launch_pixmap);
+	gdk_window_shape_combine_region(win, rgn, 8, 8);
+	cairo_region_destroy(rgn);
+
+	xpm = g_string_new("/* XPM */\nstatic char *dock_master_xpm[] = {\n");
+	for (guint i = 0; i < g_strv_length(dock_master_xpm); i++)
+	{
+		g_string_append(xpm, "\"");
+		g_string_append(xpm, dock_master_xpm[i]);
+		g_string_append(xpm, "\",\n");
+	}
+	g_string_append(xpm, "};");
+	stream = g_memory_input_stream_new_from_data(xpm->str, -1, NULL);
+	pixbuf = gdk_pixbuf_new_from_stream(stream, NULL, NULL);
+	g_string_free(xpm, TRUE);
+	g_object_unref(stream);
 
-	pixmap = gdk_pixmap_create_from_xpm_d(icon_win->window,
-					      &mask, NULL, dock_master_xpm);
+	pixmap = gdk_cairo_surface_create_from_pixbuf(pixbuf, 0, win);
+	g_object_unref(pixbuf);
 
 	attr.width = 64;
 	attr.height = 64;
 	attr.title = "wmauda";
 	attr.event_mask = GDK_BUTTON_PRESS_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_POINTER_MOTION_HINT_MASK;
 	attr.wclass = GDK_INPUT_OUTPUT;
-	attr.visual = gdk_visual_get_system();
-	attr.colormap = gdk_colormap_get_system();
+	attr.visual = gdk_screen_get_system_visual(gdk_screen_get_default());
 	attr.wmclass_name = "wmauda";
 	attr.wmclass_class = "wmauda";
 	attr.window_type = GDK_WINDOW_TOPLEVEL;
 
-	leader = gdk_window_new(NULL, &attr, GDK_WA_TITLE | GDK_WA_WMCLASS | GDK_WA_VISUAL | GDK_WA_COLORMAP);
-
-	gdk_window_set_icon(leader, icon_win->window, NULL, NULL);
-	gdk_window_reparent(icon_win->window, leader, 0, 0);
+	leader = gdk_window_new(NULL, &attr, GDK_WA_TITLE | GDK_WA_WMCLASS | GDK_WA_VISUAL);
 	gdk_window_show(leader);
 	
 	hints.initial_state = WithdrawnState;
 	hints.flags = StateHint | IconWindowHint | IconPositionHint | WindowGroupHint;
-	hints.icon_window = GDK_WINDOW_XWINDOW(icon_win->window);
+	hints.icon_window = GDK_WINDOW_XID(win);
 	hints.icon_x = 0;
 	hints.icon_y = 0;
-	hints.window_group = GDK_WINDOW_XWINDOW(leader);
+	hints.window_group = GDK_WINDOW_XID(leader);
 		
-	XSetWMHints(GDK_DISPLAY(), GDK_WINDOW_XWINDOW(leader), &hints);
-			
+	XSetWMHints(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()),
+		    GDK_WINDOW_XID(leader), &hints);
 	gtk_widget_show(icon_win);
-	timeout_tag = gtk_timeout_add(100, timeout_func, NULL);
+	timeout_tag = g_timeout_add(100, timeout_func, NULL);
 
 }
 
@@ -828,8 +832,6 @@
 		{0, 0, 0, 0}
 	};
 
-	gtk_set_locale();
-
 	gtk_init(&argc, &argv);
 
 	while ((c = getopt_long(argc, argv, "hg:s:c:i:ntv", lopt, NULL)) != -1)
@@ -838,7 +840,7 @@
 		{
 			case 'h':
 				display_usage(argv[0]);
-				gtk_exit(0);
+				exit(EXIT_SUCCESS);
 				break;
 			case 'g':
 				XParseGeometry(optarg, &win_x, &win_y,
@@ -859,7 +861,7 @@
 				break;
 			case 'v':
 				printf("wmauda %s\n", VERSION);
-				gtk_exit(0);
+				exit(EXIT_SUCCESS);
 				break;
 		}
 	}

Reply via email to