st-scroll-bar: use clutter_grab_pointer()
StScrollBar was intercepting motion events by using captured-event on the stage, which required additional dirty tricks, which required additional hacks. Simplify it by just using clutter_grab_pointer() instead. https://bugzilla.gnome.org/show_bug.cgi?id=671001
This commit is contained in:
parent
b36029f6c4
commit
c540cb5e16
@ -863,10 +863,6 @@ const PopupMenuBase = new Lang.Class({
|
|||||||
// for the menu which causes its prelight state to freeze
|
// for the menu which causes its prelight state to freeze
|
||||||
this.blockSourceEvents = false;
|
this.blockSourceEvents = false;
|
||||||
|
|
||||||
// Can be set while a menu is up to let all events through without special
|
|
||||||
// menu handling useful for scrollbars in menus, and probably not otherwise.
|
|
||||||
this.passEvents = false;
|
|
||||||
|
|
||||||
this._activeMenuItem = null;
|
this._activeMenuItem = null;
|
||||||
this._childMenus = [];
|
this._childMenus = [];
|
||||||
this._settingsActions = { };
|
this._settingsActions = { };
|
||||||
@ -1285,24 +1281,6 @@ const PopupSubMenu = new Lang.Class({
|
|||||||
hscrollbar_policy: Gtk.PolicyType.NEVER,
|
hscrollbar_policy: Gtk.PolicyType.NEVER,
|
||||||
vscrollbar_policy: Gtk.PolicyType.NEVER });
|
vscrollbar_policy: Gtk.PolicyType.NEVER });
|
||||||
|
|
||||||
// StScrollbar plays dirty tricks with events, calling
|
|
||||||
// clutter_set_motion_events_enabled (FALSE) during the scroll; this
|
|
||||||
// confuses our event tracking, so we just turn it off during the
|
|
||||||
// scroll.
|
|
||||||
let vscroll = this.actor.get_vscroll_bar();
|
|
||||||
vscroll.connect('scroll-start',
|
|
||||||
Lang.bind(this, function() {
|
|
||||||
let topMenu = this._getTopMenu();
|
|
||||||
if (topMenu)
|
|
||||||
topMenu.passEvents = true;
|
|
||||||
}));
|
|
||||||
vscroll.connect('scroll-stop',
|
|
||||||
Lang.bind(this, function() {
|
|
||||||
let topMenu = this._getTopMenu();
|
|
||||||
if (topMenu)
|
|
||||||
topMenu.passEvents = false;
|
|
||||||
}));
|
|
||||||
|
|
||||||
this.actor.add_actor(this.box);
|
this.actor.add_actor(this.box);
|
||||||
this.actor._delegate = this;
|
this.actor._delegate = this;
|
||||||
this.actor.clip_to_allocation = true;
|
this.actor.clip_to_allocation = true;
|
||||||
@ -2279,9 +2257,6 @@ const PopupMenuManager = new Lang.Class({
|
|||||||
this._owner.menuEventFilter(event))
|
this._owner.menuEventFilter(event))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (this._activeMenu != null && this._activeMenu.passEvents)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (this._didPop) {
|
if (this._didPop) {
|
||||||
this._didPop = false;
|
this._didPop = false;
|
||||||
return true;
|
return true;
|
||||||
|
@ -52,7 +52,7 @@ struct _StScrollBarPrivate
|
|||||||
{
|
{
|
||||||
StAdjustment *adjustment;
|
StAdjustment *adjustment;
|
||||||
|
|
||||||
gulong capture_handler;
|
gboolean grabbed;
|
||||||
gfloat x_origin;
|
gfloat x_origin;
|
||||||
gfloat y_origin;
|
gfloat y_origin;
|
||||||
|
|
||||||
@ -586,52 +586,37 @@ move_slider (StScrollBar *bar,
|
|||||||
static void
|
static void
|
||||||
stop_scrolling (StScrollBar *bar)
|
stop_scrolling (StScrollBar *bar)
|
||||||
{
|
{
|
||||||
ClutterStage *stage;
|
if (!bar->priv->grabbed)
|
||||||
|
|
||||||
if (!bar->priv->capture_handler)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
st_widget_remove_style_pseudo_class (ST_WIDGET (bar->priv->handle), "active");
|
st_widget_remove_style_pseudo_class (ST_WIDGET (bar->priv->handle), "active");
|
||||||
|
|
||||||
stage = CLUTTER_STAGE (clutter_actor_get_stage (bar->priv->trough));
|
clutter_ungrab_pointer ();
|
||||||
g_signal_handler_disconnect (stage, bar->priv->capture_handler);
|
bar->priv->grabbed = FALSE;
|
||||||
bar->priv->capture_handler = 0;
|
|
||||||
|
|
||||||
clutter_stage_set_motion_events_enabled (stage, TRUE);
|
|
||||||
g_signal_emit (bar, signals[SCROLL_STOP], 0);
|
g_signal_emit (bar, signals[SCROLL_STOP], 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
handle_capture_event_cb (ClutterActor *trough,
|
handle_motion_event_cb (ClutterActor *trough,
|
||||||
ClutterEvent *event,
|
ClutterMotionEvent *event,
|
||||||
StScrollBar *bar)
|
StScrollBar *bar)
|
||||||
{
|
{
|
||||||
if (clutter_event_type (event) == CLUTTER_MOTION)
|
if (!bar->priv->grabbed)
|
||||||
{
|
return FALSE;
|
||||||
move_slider (bar,
|
|
||||||
((ClutterMotionEvent*) event)->x,
|
move_slider (bar, event->x, event->y);
|
||||||
((ClutterMotionEvent*) event)->y);
|
return TRUE;
|
||||||
}
|
}
|
||||||
else if (clutter_event_type (event) == CLUTTER_BUTTON_RELEASE
|
|
||||||
&& ((ClutterButtonEvent*) event)->button == 1)
|
static gboolean
|
||||||
{
|
handle_button_release_event_cb (ClutterActor *trough,
|
||||||
ClutterActor *stage, *target;
|
ClutterButtonEvent *event,
|
||||||
|
StScrollBar *bar)
|
||||||
|
{
|
||||||
|
if (event->button != 1)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
stop_scrolling (bar);
|
stop_scrolling (bar);
|
||||||
|
|
||||||
/* check if the mouse pointer has left the handle during the drag and
|
|
||||||
* remove the hover state if it has */
|
|
||||||
stage = clutter_actor_get_stage (bar->priv->trough);
|
|
||||||
target = clutter_stage_get_actor_at_pos ((ClutterStage*) stage,
|
|
||||||
CLUTTER_PICK_REACTIVE,
|
|
||||||
((ClutterButtonEvent*) event)->x,
|
|
||||||
((ClutterButtonEvent*) event)->y);
|
|
||||||
if (target != bar->priv->handle)
|
|
||||||
{
|
|
||||||
st_widget_remove_style_pseudo_class ((StWidget*) bar->priv->handle, "hover");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -640,7 +625,6 @@ handle_button_press_event_cb (ClutterActor *actor,
|
|||||||
ClutterButtonEvent *event,
|
ClutterButtonEvent *event,
|
||||||
StScrollBar *bar)
|
StScrollBar *bar)
|
||||||
{
|
{
|
||||||
ClutterStage *stage;
|
|
||||||
StScrollBarPrivate *priv = bar->priv;
|
StScrollBarPrivate *priv = bar->priv;
|
||||||
|
|
||||||
if (event->button != 1)
|
if (event->button != 1)
|
||||||
@ -659,16 +643,10 @@ handle_button_press_event_cb (ClutterActor *actor,
|
|||||||
priv->x_origin += clutter_actor_get_x (priv->trough);
|
priv->x_origin += clutter_actor_get_x (priv->trough);
|
||||||
priv->y_origin += clutter_actor_get_y (priv->trough);
|
priv->y_origin += clutter_actor_get_y (priv->trough);
|
||||||
|
|
||||||
stage = CLUTTER_STAGE (clutter_actor_get_stage (bar->priv->trough));
|
g_assert (!priv->grabbed);
|
||||||
|
|
||||||
/* Turn off picking for motion events */
|
clutter_grab_pointer (priv->handle);
|
||||||
clutter_stage_set_motion_events_enabled (stage, FALSE);
|
priv->grabbed = TRUE;
|
||||||
|
|
||||||
priv->capture_handler = g_signal_connect_after (
|
|
||||||
clutter_actor_get_stage (priv->trough),
|
|
||||||
"captured-event",
|
|
||||||
G_CALLBACK (handle_capture_event_cb),
|
|
||||||
bar);
|
|
||||||
g_signal_emit (bar, signals[SCROLL_START], 0);
|
g_signal_emit (bar, signals[SCROLL_START], 0);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -885,6 +863,10 @@ st_scroll_bar_init (StScrollBar *self)
|
|||||||
CLUTTER_ACTOR (self->priv->handle));
|
CLUTTER_ACTOR (self->priv->handle));
|
||||||
g_signal_connect (self->priv->handle, "button-press-event",
|
g_signal_connect (self->priv->handle, "button-press-event",
|
||||||
G_CALLBACK (handle_button_press_event_cb), self);
|
G_CALLBACK (handle_button_press_event_cb), self);
|
||||||
|
g_signal_connect (self->priv->handle, "button-release-event",
|
||||||
|
G_CALLBACK (handle_button_release_event_cb), self);
|
||||||
|
g_signal_connect (self->priv->handle, "motion-event",
|
||||||
|
G_CALLBACK (handle_motion_event_cb), self);
|
||||||
|
|
||||||
clutter_actor_set_reactive (CLUTTER_ACTOR (self), TRUE);
|
clutter_actor_set_reactive (CLUTTER_ACTOR (self), TRUE);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user