# HG changeset patch # User Jan Dj¸«£rv # Date 1260711095 0 # Node ID bac7488df5035439e6ab391b7429cb6b21bcdf69 # Parent 3d091f151696f540c2627596823d1fa2df45192e Bug 5177: Scroll bar thumb did not move when scrolling with mouse wheel. * xterm.c (xg_scroll_callback): Parameter list changed, use parameter GtkScrollType to determine scroll/line/page. Only allow dragging if a button < 4 is grabbed (bug #5177). (xg_end_scroll_callback): New function. (x_create_toolkit_scroll_bar): Pass xg_end_scroll_callback to xg_create_scroll_bar. * gtkutil.c (xg_gtk_scroll_destroy): Remove XG_LAST_SB_DATA handling. (scroll_end_callback): Remove. (xg_create_scroll_bar): Add parameter end_callback, bind it to button-release-event. Replace value-changed event with change-value, bug #5177, (xg_event_is_for_scrollbar): Only return true if button is less than 4, bug #5177. * gtkutil.h (XG_LAST_SB_DATA): Remove. (xg_create_scroll_bar): Add GCallback end_callback. diff -r 3d091f151696 -r bac7488df503 src/ChangeLog --- a/src/ChangeLog Sun Dec 13 13:16:17 2009 +0000 +++ b/src/ChangeLog Sun Dec 13 13:31:35 2009 +0000 @@ -1,5 +1,23 @@ 2009-12-13 Jan DjƤrv + * xterm.c (xg_scroll_callback): Parameter list changed, + use parameter GtkScrollType to determine scroll/line/page. + Only allow dragging if a button < 4 is grabbed (bug #5177). + (xg_end_scroll_callback): New function. + (x_create_toolkit_scroll_bar): Pass xg_end_scroll_callback to + xg_create_scroll_bar. + + * gtkutil.c (xg_gtk_scroll_destroy): Remove XG_LAST_SB_DATA handling. + (scroll_end_callback): Remove. + (xg_create_scroll_bar): Add parameter end_callback, bind it to + button-release-event. Replace value-changed event with change-value, + bug #5177, + (xg_event_is_for_scrollbar): Only return true if button is less than 4, + bug #5177. + + * gtkutil.h (XG_LAST_SB_DATA): Remove. + (xg_create_scroll_bar): Add GCallback end_callback. + * xftfont.c (QClcdfilter): New variable. (xftfont_open): Parse constant names for RGBA, HINT_STYLE and LCDFILTER. (syms_of_xftfont): Initialize QClcdfilter. diff -r 3d091f151696 -r bac7488df503 src/gtkutil.c --- a/src/gtkutil.c Sun Dec 13 13:16:17 2009 +0000 +++ b/src/gtkutil.c Sun Dec 13 13:31:35 2009 +0000 @@ -3085,38 +3085,23 @@ GtkWidget *widget; gpointer data; { - gpointer p; int id = (int) (EMACS_INT) data; /* The EMACS_INT cast avoids a warning. */ - - p = g_object_get_data (G_OBJECT (widget), XG_LAST_SB_DATA); - xfree (p); xg_remove_widget_from_map (id); } -/* Callback for button release. Sets dragging to Qnil when dragging is done. */ - -static gboolean -scroll_end_callback (GtkWidget *widget, - GdkEventButton *event, - gpointer user_data) -{ - struct scroll_bar *bar = (struct scroll_bar *) user_data; - bar->dragging = Qnil; - return FALSE; -} - /* Create a scroll bar widget for frame F. Store the scroll bar in BAR. SCROLL_CALLBACK is the callback to invoke when the value of the bar changes. + END_CALLBACK is the callback to invoke when scrolling ends. SCROLL_BAR_NAME is the name we use for the scroll bar. Can be used to set resources for the widget. */ void -xg_create_scroll_bar (f, bar, scroll_callback, scroll_bar_name) +xg_create_scroll_bar (f, bar, scroll_callback, end_callback, scroll_bar_name) FRAME_PTR f; struct scroll_bar *bar; - GCallback scroll_callback; + GCallback scroll_callback, end_callback; char *scroll_bar_name; { GtkWidget *wscroll; @@ -3133,22 +3118,22 @@ webox = gtk_event_box_new (); gtk_widget_set_name (wscroll, scroll_bar_name); gtk_range_set_update_policy (GTK_RANGE (wscroll), GTK_UPDATE_CONTINUOUS); + g_object_set_data (G_OBJECT (wscroll), XG_FRAME_DATA, (gpointer)f); scroll_id = xg_store_widget_in_map (wscroll); - g_signal_connect (G_OBJECT (wscroll), - "value-changed", - scroll_callback, - (gpointer) bar); /* The EMACS_INT cast avoids a warning. */ g_signal_connect (G_OBJECT (wscroll), "destroy", G_CALLBACK (xg_gtk_scroll_destroy), (gpointer) (EMACS_INT) scroll_id); - + g_signal_connect (G_OBJECT (wscroll), + "change-value", + scroll_callback, + (gpointer) bar); g_signal_connect (G_OBJECT (wscroll), "button-release-event", - G_CALLBACK (scroll_end_callback), + end_callback, (gpointer) bar); /* The scroll bar widget does not draw on a window of its own. Instead @@ -3327,14 +3312,16 @@ { int retval = 0; - if (f && event->type == ButtonPress) + if (f && event->type == ButtonPress && event->xbutton.button < 4) { /* Check if press occurred outside the edit widget. */ GdkDisplay *gdpy = gdk_x11_lookup_xdisplay (FRAME_X_DISPLAY (f)); retval = gdk_display_get_window_at_pointer (gdpy, NULL, NULL) != f->output_data.x->edit_widget->window; } - else if (f && (event->type == ButtonRelease || event->type == MotionNotify)) + else if (f + && ((event->type == ButtonRelease && event->xbutton.button < 4) + || event->type == MotionNotify)) { /* If we are releasing or moving the scroll bar, it has the grab. */ retval = gtk_grab_get_current () != 0 diff -r 3d091f151696 -r bac7488df503 src/gtkutil.h --- a/src/gtkutil.h Sun Dec 13 13:16:17 2009 +0000 +++ b/src/gtkutil.h Sun Dec 13 13:31:35 2009 +0000 @@ -32,12 +32,9 @@ #define XG_SB_MAX 10000000 #define XG_SB_RANGE (XG_SB_MAX-XG_SB_MIN) -/* Key for data that is valid for menus in a frame */ +/* Key for data that is valid for menus and scroll bars in a frame */ #define XG_FRAME_DATA "emacs_frame" -/* Key for data that is the last scrollbar value */ -#define XG_LAST_SB_DATA "emacs_last_sb_value" - /* Key for data that menu items hold. */ #define XG_ITEM_DATA "emacs_menuitem" @@ -164,6 +161,7 @@ extern void xg_create_scroll_bar P_ ((FRAME_PTR f, struct scroll_bar *bar, GCallback scroll_callback, + GCallback end_callback, char *scroll_bar_name)); extern void xg_show_scroll_bar P_ ((int scrollbar_id)); extern void xg_remove_scroll_bar P_ ((FRAME_PTR f, int scrollbar_id)); diff -r 3d091f151696 -r bac7488df503 src/xterm.c --- a/src/xterm.c Sun Dec 13 13:16:17 2009 +0000 +++ b/src/xterm.c Sun Dec 13 13:31:35 2009 +0000 @@ -4374,63 +4374,51 @@ /* Scroll bar callback for GTK scroll bars. WIDGET is the scroll bar widget. DATA is a pointer to the scroll_bar structure. */ -static void -xg_scroll_callback (widget, data) - GtkRange *widget; - gpointer data; -{ - struct scroll_bar *bar = (struct scroll_bar *) data; - gdouble previous; +static gboolean +xg_scroll_callback (GtkRange *range, + GtkScrollType scroll, + gdouble value, + gpointer user_data) +{ + struct scroll_bar *bar = (struct scroll_bar *) user_data; gdouble position; - gdouble *p; - int diff; - int part = -1, whole = 0, portion = 0; - GtkAdjustment *adj = GTK_ADJUSTMENT (gtk_range_get_adjustment (widget)); - + GtkAdjustment *adj = GTK_ADJUSTMENT (gtk_range_get_adjustment (range)); + FRAME_PTR f = (FRAME_PTR) g_object_get_data (G_OBJECT (range), XG_FRAME_DATA); + + if (xg_ignore_gtk_scrollbar) return FALSE; position = gtk_adjustment_get_value (adj); - p = g_object_get_data (G_OBJECT (widget), XG_LAST_SB_DATA); - if (! p) - { - p = (gdouble*) xmalloc (sizeof (gdouble)); - *p = XG_SB_MIN; - g_object_set_data (G_OBJECT (widget), XG_LAST_SB_DATA, p); - } - - previous = *p; - *p = position; - - if (xg_ignore_gtk_scrollbar) return; - - diff = (int) (position - previous); - - if (diff == (int) adj->step_increment) - { + + switch (scroll) + { + case GTK_SCROLL_JUMP: + /* Buttons 1 2 or 3 must be grabbed. */ + if (FRAME_X_DISPLAY_INFO (f)->grabbed != 0 + && FRAME_X_DISPLAY_INFO (f)->grabbed < (1 << 4)) + { + part = scroll_bar_handle; + whole = adj->upper - adj->page_size; + portion = min ((int)position, whole); + bar->dragging = make_number ((int)portion); + } + break; + case GTK_SCROLL_STEP_BACKWARD: + part = scroll_bar_up_arrow; + bar->dragging = Qnil; + break; + case GTK_SCROLL_STEP_FORWARD: part = scroll_bar_down_arrow; bar->dragging = Qnil; - } - else if (-diff == (int) adj->step_increment) - { - part = scroll_bar_up_arrow; + break; + case GTK_SCROLL_PAGE_BACKWARD: + part = scroll_bar_above_handle; bar->dragging = Qnil; - } - else if (diff == (int) adj->page_increment) - { + break; + case GTK_SCROLL_PAGE_FORWARD: part = scroll_bar_below_handle; bar->dragging = Qnil; - } - else if (-diff == (int) adj->page_increment) - { - part = scroll_bar_above_handle; - bar->dragging = Qnil; - } - else - { - part = scroll_bar_handle; - whole = adj->upper - adj->page_size; - portion = min ((int)position, whole); - bar->dragging = make_number ((int)portion); + break; } if (part >= 0) @@ -4439,7 +4427,29 @@ last_scroll_bar_part = part; x_send_scroll_bar_event (bar->window, part, portion, whole); } -} + + return FALSE; +} + +/* Callback for button release. Sets dragging to Qnil when dragging is done. */ + +static gboolean +xg_end_scroll_callback (GtkWidget *widget, + GdkEventButton *event, + gpointer user_data) +{ + struct scroll_bar *bar = (struct scroll_bar *) user_data; + bar->dragging = Qnil; + if (WINDOWP (window_being_scrolled)) + { + x_send_scroll_bar_event (window_being_scrolled, + scroll_bar_end_scroll, 0, 0); + window_being_scrolled = Qnil; + } + + return FALSE; +} + #else /* not USE_GTK and not USE_MOTIF */ @@ -4541,6 +4551,7 @@ BLOCK_INPUT; xg_create_scroll_bar (f, bar, G_CALLBACK (xg_scroll_callback), + G_CALLBACK (xg_end_scroll_callback), scroll_bar_name); UNBLOCK_INPUT; }