--- a/meson.build Thu Jul 23 20:13:47 2020 -0500
+++ b/meson.build Fri Jul 24 04:43:46 2020 -0500
@@ -331,11 +331,6 @@
conf.set('HAVE_X11', x11.found())
-enable_gestures = get_option('gestures')
-if not get_option('gtkui') or not x11.found()
- enable_gestures = false
#######################################################################
# Check for LibXML2 (required)
#######################################################################
@@ -793,7 +788,6 @@
message('Build console UI.............. : ' + enable_consoleui.to_string())
message('Build for X11................. : ' + x11.found().to_string())
-message('Enable Gestures............... : ' + enable_gestures.to_string())
message('Protocols to build dynamically : @0@'.format(DYNAMIC_PRPLS))
message('Build with GStreamer support.. : ' + gstreamer.found().to_string())
--- a/meson_options.txt Thu Jul 23 20:13:47 2020 -0500
+++ b/meson_options.txt Fri Jul 24 04:43:46 2020 -0500
@@ -79,9 +79,6 @@
option('console-logging', type : 'boolean', value : false,
description : 'compile with console logging support')
-option('gestures', type : 'boolean', value : true,
- description : 'compile with the gestures plugin')
option('gevolution', type : 'feature', value : 'disabled',
description : 'compile with the Evolution plugin')
--- a/pidgin/plugins/gestures/gestures.c Thu Jul 23 20:13:47 2020 -0500
+++ b/pidgin/plugins/gestures/gestures.c Fri Jul 24 04:43:46 2020 -0500
@@ -18,13 +18,12 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+#include <glib/gi18n-lib.h>
@@ -45,7 +44,7 @@
gtkconv = PIDGIN_CONVERSATION(conv);
- gstroke_cleanup(gtkconv->webview);
+ gstroke_cleanup(gtkconv->history); @@ -123,15 +122,15 @@
gtkconv = PIDGIN_CONVERSATION(conv);
- gstroke_enable(gtkconv->webview);
- gstroke_signal_connect(gtkconv->webview, "14789", stroke_close, conv);
- gstroke_signal_connect(gtkconv->webview, "1456", stroke_close, conv);
- gstroke_signal_connect(gtkconv->webview, "1489", stroke_close, conv);
- gstroke_signal_connect(gtkconv->webview, "74123", stroke_next_tab, conv);
- gstroke_signal_connect(gtkconv->webview, "7456", stroke_next_tab, conv);
- gstroke_signal_connect(gtkconv->webview, "96321", stroke_prev_tab, conv);
- gstroke_signal_connect(gtkconv->webview, "9654", stroke_prev_tab, conv);
- gstroke_signal_connect(gtkconv->webview, "25852", stroke_new_win, conv);
+ gstroke_enable(gtkconv->history); + gstroke_signal_connect(gtkconv->history, "14789", stroke_close, conv); + gstroke_signal_connect(gtkconv->history, "1456", stroke_close, conv); + gstroke_signal_connect(gtkconv->history, "1489", stroke_close, conv); + gstroke_signal_connect(gtkconv->history, "74123", stroke_next_tab, conv); + gstroke_signal_connect(gtkconv->history, "7456", stroke_next_tab, conv); + gstroke_signal_connect(gtkconv->history, "96321", stroke_prev_tab, conv); + gstroke_signal_connect(gtkconv->history, "9654", stroke_prev_tab, conv); + gstroke_signal_connect(gtkconv->history, "25852", stroke_new_win, conv); @@ -209,7 +208,7 @@
-static PidginPluginInfo *
+static GPluginPluginInfo * plugin_query(GError **error)
const gchar * const authors[] = {
@@ -217,7 +216,7 @@
- return pidgin_plugin_info_new(
+ return gplugin_plugin_info_new( "id", GESTURES_PLUGIN_ID,
"name", N_("Mouse Gestures"),
"version", DISPLAY_VERSION,
@@ -288,8 +287,8 @@
gtkconv = PIDGIN_CONVERSATION(conv);
- gstroke_cleanup(gtkconv->webview);
- gstroke_disable(gtkconv->webview);
+ gstroke_cleanup(gtkconv->history); + gstroke_disable(gtkconv->history); --- a/pidgin/plugins/gestures/gstroke.h Thu Jul 23 20:13:47 2020 -0500
+++ b/pidgin/plugins/gestures/gstroke.h Fri Jul 24 04:43:46 2020 -0500
@@ -36,10 +36,9 @@
/* disable strokes for the widget */
void gstroke_disable(GtkWidget *widget);
-guint gstroke_signal_connect (GtkWidget *widget,
- void (*func)(GtkWidget *widget, void *data),
+void gstroke_signal_connect(GtkWidget *widget, const gchar *name, + void (*func)(GtkWidget *widget, void *data), /* frees all the memory allocated for stroke, should be called when
the widget is destroyed*/
--- a/pidgin/plugins/gestures/meson.build Thu Jul 23 20:13:47 2020 -0500
+++ b/pidgin/plugins/gestures/meson.build Fri Jul 24 04:43:46 2020 -0500
@@ -8,8 +8,7 @@
gestures = library('gestures', gestures_SOURCES,
- build_by_default: false,
- dependencies : [x11, libpurple_dep, libpidgin_dep, glib],
+ dependencies : [libpurple_dep, libpidgin_dep, glib], - install : false, install_dir : PIDGIN_PLUGINDIR)
+ install : true, install_dir : PIDGIN_PLUGINDIR) --- a/pidgin/plugins/gestures/stroke-draw.c Thu Jul 23 20:13:47 2020 -0500
+++ b/pidgin/plugins/gestures/stroke-draw.c Fri Jul 24 04:43:46 2020 -0500
@@ -11,19 +11,14 @@
#include "gstroke-internal.h"
-static void gstroke_invisible_window_init (GtkWidget *widget);
+static gboolean gstroke_draw_cb(GtkWidget *widget, cairo_t *cr, /*FIXME: Maybe these should be put in a structure, and not static...*/
-static Display * gstroke_disp = NULL;
-static Window gstroke_window;
static int mouse_button = 2;
static gboolean draw_strokes = FALSE;
@@ -65,24 +60,7 @@
gdk_window_get_device_position(gtk_widget_get_window(widget),
- if (last_mouse_position.invalid)
- last_mouse_position.invalid = FALSE;
- else if (gstroke_draw_strokes()) {
- XDrawLine(gstroke_disp, gstroke_window, gstroke_gc,
- last_mouse_position.last_point.x,
- last_mouse_position.last_point.y, x, y);
- /* XFlush (gstroke_disp); */
- /* FIXME: this does not work. It will only work if we create
- * a corresponding GDK window for stroke_window and draw on
- gdk_draw_line(gtk_widget_get_window(widget),
- widget->style->fg_gc[GTK_STATE_NORMAL],
- last_mouse_position.last_point.x,
- last_mouse_position.last_point.y, x, y);
+ last_mouse_position.invalid = FALSE; if (last_mouse_position.last_point.x != x ||
last_mouse_position.last_point.y != y)
@@ -92,6 +70,10 @@
metrics = g_object_get_data(G_OBJECT(widget), GSTROKE_METRICS);
_gstroke_record (x, y, metrics);
+ if (gstroke_draw_strokes()) { + gtk_widget_queue_draw(widget); @@ -107,7 +89,8 @@
-static void gstroke_cancel(GdkEvent *event)
+gstroke_cancel(GtkWidget *widget, GdkEvent *event) last_mouse_position.invalid = TRUE;
@@ -120,16 +103,13 @@
gdk_seat_ungrab(gdk_event_get_seat(event));
- if (gstroke_draw_strokes() && gstroke_disp != NULL) {
- /* get rid of the invisible stroke window */
- XUnmapWindow (gstroke_disp, gstroke_window);
+ if (gstroke_draw_strokes()) { + gtk_widget_queue_draw(widget);
-process_event (GtkWidget *widget, GdkEvent *event, gpointer data G_GNUC_UNUSED)
+process_event(GtkWidget *widget, GdkEvent *event, gpointer data) static GtkWidget *original_widget = NULL;
static GdkCursor *cursor = NULL;
@@ -141,7 +121,7 @@
* clicked after the middle button is clicked (but possibly
+ gstroke_cancel(widget, event); @@ -149,8 +129,6 @@
original_widget = widget; /* remeber the widget where
- gstroke_invisible_window_init (widget);
record_stroke_segment (widget);
@@ -171,7 +149,7 @@
/* Nice bug when you hold down one button and press another. */
/* We'll just cancel the gesture instead. */
+ gstroke_cancel(widget, event); @@ -182,21 +160,20 @@
gdk_seat_ungrab(gdk_event_get_seat(event));
+ GtkWidget *history = data; char result[GSTROKE_MAX_SEQUENCE];
struct gstroke_metrics *metrics;
metrics = (struct gstroke_metrics *)g_object_get_data(G_OBJECT (widget),
if (gstroke_draw_strokes()) {
- /* get rid of the invisible stroke window */
- XUnmapWindow (gstroke_disp, gstroke_window);
+ gtk_widget_queue_draw(widget); - _gstroke_canonical (result, metrics);
- gstroke_execute (widget, result);
+ _gstroke_canonical(result, metrics); + gstroke_execute(history, result); @@ -233,58 +210,85 @@
gstroke_enable (GtkWidget *widget)
- struct gstroke_metrics*
- metrics = (struct gstroke_metrics *)g_object_get_data(G_OBJECT(widget),
- metrics = (struct gstroke_metrics *)g_malloc (sizeof
- (struct gstroke_metrics));
- metrics->pointList = NULL;
- metrics->min_x = 10000;
- metrics->min_y = 10000;
- metrics->point_count = 0;
+ GtkWidget *event = gtk_widget_get_parent(widget); + struct gstroke_metrics *metrics = NULL; + if (GTK_IS_EVENT_BOX(event)) { + metrics = (struct gstroke_metrics *)g_object_get_data(G_OBJECT(event), + metrics = g_new0(struct gstroke_metrics, 1); + metrics->pointList = NULL; + metrics->min_x = 10000; + metrics->min_y = 10000; + metrics->point_count = 0; - g_object_set_data(G_OBJECT(widget), GSTROKE_METRICS, metrics);
+ event = gtk_event_box_new(); + gtk_event_box_set_above_child(GTK_EVENT_BOX(event), TRUE); + gtk_widget_set_events(event, GDK_BUTTON_PRESS_MASK | + GDK_BUTTON_RELEASE_MASK | + GDK_BUTTON2_MOTION_MASK); + gtk_widget_set_app_paintable(event, TRUE); + gtk_widget_show(event); - g_signal_connect(G_OBJECT(widget), "event",
- G_CALLBACK(process_event), NULL);
- _gstroke_init (metrics);
+ parent = gtk_widget_get_parent(widget); + gtk_container_remove(GTK_CONTAINER(parent), widget); + gtk_container_add(GTK_CONTAINER(event), widget); + g_object_unref(widget); + gtk_container_add(GTK_CONTAINER(parent), event); + g_object_set_data(G_OBJECT(event), GSTROKE_METRICS, metrics); - last_mouse_position.invalid = TRUE;
+ g_signal_connect(G_OBJECT(event), "event", G_CALLBACK(process_event), + g_signal_connect_after(G_OBJECT(event), "draw", + G_CALLBACK(gstroke_draw_cb), NULL); + _gstroke_init(metrics); + last_mouse_position.invalid = TRUE; gstroke_disable(GtkWidget *widget)
- g_signal_handlers_disconnect_by_func(G_OBJECT(widget), G_CALLBACK(process_event), NULL);
+ GtkWidget *event = gtk_widget_get_parent(widget); + g_return_if_fail(GTK_IS_EVENT_BOX(event)); + g_signal_handlers_disconnect_by_func(G_OBJECT(event), + G_CALLBACK(process_event), widget); + g_signal_handlers_disconnect_by_func(G_OBJECT(event), + G_CALLBACK(gstroke_draw_cb), NULL);
-gstroke_signal_connect (GtkWidget *widget,
- void (*func)(GtkWidget *widget, void *data),
+gstroke_signal_connect(GtkWidget *widget, const gchar *name, + void (*func)(GtkWidget *widget, void *data), - struct gstroke_func_and_data *func_and_data;
- GHashTable *hash_table =
- (GHashTable*)g_object_get_data(G_OBJECT(widget), GSTROKE_SIGNALS);
+ struct gstroke_func_and_data *func_and_data; + GHashTable *hash_table = + (GHashTable *)g_object_get_data(G_OBJECT(widget), GSTROKE_SIGNALS);
- hash_table = g_hash_table_new (g_str_hash, g_str_equal);
- g_object_set_data(G_OBJECT(widget), GSTROKE_SIGNALS,
- func_and_data = g_new (struct gstroke_func_and_data, 1);
- func_and_data->func = func;
- func_and_data->data = data;
- g_hash_table_insert (hash_table, (gpointer)name, (gpointer)func_and_data);
+ g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); + g_object_set_data(G_OBJECT(widget), GSTROKE_SIGNALS, hash_table); + func_and_data = g_new0(struct gstroke_func_and_data, 1); + func_and_data->func = func; + func_and_data->data = data; + g_hash_table_insert(hash_table, g_strdup(name), func_and_data); @@ -310,100 +314,62 @@
gstroke_cleanup (GtkWidget *widget)
- struct gstroke_metrics *metrics;
- GHashTable *hash_table =
- (GHashTable*)g_object_get_data(G_OBJECT(widget), GSTROKE_SIGNALS);
- /* FIXME: does this delete the elements too? */
- g_hash_table_destroy (hash_table);
+ struct gstroke_metrics *metrics; + GHashTable *hash_table = (GHashTable *)g_object_steal_data(G_OBJECT(widget), + g_hash_table_destroy(hash_table); - g_object_steal_data(G_OBJECT(widget), GSTROKE_SIGNALS);
- metrics = (struct gstroke_metrics*)g_object_get_data(G_OBJECT(widget),
- g_object_steal_data(G_OBJECT(widget), GSTROKE_METRICS);
+ metrics = (struct gstroke_metrics *)g_object_steal_data(G_OBJECT(widget),
-/* This function should be written using GTK+ primitives*/
-gstroke_invisible_window_init (GtkWidget *widget)
+gstroke_draw_cb(GtkWidget *widget, cairo_t *cr, + G_GNUC_UNUSED gpointer user_data) - XSetWindowAttributes w_attr;
- XWindowAttributes orig_w_attr;
- unsigned long mask, col_border, col_background;
- unsigned int border_width;
- Display *disp = GDK_WINDOW_XDISPLAY(gtk_widget_get_window(widget));
- Window wind = gdk_x11_window_get_xid(gtk_widget_get_window(widget));
- int screen = DefaultScreen (disp);
- if (!gstroke_draw_strokes())
+ struct gstroke_metrics *metrics = + (struct gstroke_metrics *)g_object_get_data(G_OBJECT(widget), - /* X server should save what's underneath */
- XGetWindowAttributes (gstroke_disp, wind, &orig_w_attr);
- hints.x = orig_w_attr.x;
- hints.y = orig_w_attr.y;
- hints.width = orig_w_attr.width;
- hints.height = orig_w_attr.height;
- w_attr.save_under = True;
+ if (last_mouse_position.invalid) { - /* inhibit all the decorations */
- mask |= CWOverrideRedirect;
- w_attr.override_redirect = True;
- /* Don't set a background, transparent window */
- w_attr.background_pixmap = None;
- /* Default input window look */
- col_background = WhitePixel (gstroke_disp, screen);
+ iter = metrics->pointList; - /* no border for the window */
- col_border = BlackPixel (gstroke_disp, screen);
- gstroke_window = XCreateSimpleWindow (gstroke_disp, wind,
- hints.width - 2 * border_width,
- hints.height - 2 * border_width,
- col_border, col_background);
+ cairo_set_line_width(cr, 2.0); + cairo_set_dash(cr, NULL, 0, 0.0); + cairo_set_line_cap(cr, CAIRO_LINE_CAP_BUTT); + cairo_set_line_join(cr, CAIRO_LINE_JOIN_MITER); - gstroke_gc = XCreateGC (gstroke_disp, gstroke_window, 0, NULL);
- XSetFunction (gstroke_disp, gstroke_gc, GXinvert);
- XChangeWindowAttributes (gstroke_disp, gstroke_window, mask, &w_attr);
+ point = (p_point)iter->data; + cairo_move_to(cr, point->x, point->y); - XSetLineAttributes (gstroke_disp, gstroke_gc, 2, LineSolid,
- XMapRaised (gstroke_disp, gstroke_window);
+ point = (p_point)iter->data;
- /*FIXME: is this call really needed? If yes, does it need the real
- hints.flags = PPosition | PSize;
- XSetStandardProperties (gstroke_disp, gstroke_window, "gstroke_test", NULL,
- (Pixmap)NULL, NULL, 0, &hints);
+ cairo_line_to(cr, point->x, point->y); - /* Receive the close window client message */
- /* FIXME: is this really needed? If yes, something should be done
- Atom wmdelete = XInternAtom (gstroke_disp, "WM_DELETE_WINDOW",
- XSetWMProtocols (gstroke_disp, gstroke_window, &wmdelete, True);
--- a/pidgin/plugins/gestures/stroke.c Thu Jul 23 20:13:47 2020 -0500
+++ b/pidgin/plugins/gestures/stroke.c Fri Jul 24 04:43:46 2020 -0500
@@ -147,11 +147,11 @@
- /* move to next point, freeing current point from list */
- crt_elem = g_slist_next (crt_elem);
+ /* move to next point, freeing current point from list */ + g_free(crt_elem->data); + crt_elem = g_slist_next(crt_elem); + metrics->pointList = NULL; /* add the last run of points to the sequence */
sequence[sequence_count++] = '0' + current_bin;
/* printf ("DEBUG:: adding final sequence: %d\n", current_bin); */
--- a/pidgin/plugins/meson.build Thu Jul 23 20:13:47 2020 -0500
+++ b/pidgin/plugins/meson.build Fri Jul 24 04:43:46 2020 -0500
@@ -4,11 +4,8 @@