It should be possible to destroy the actor currently being dragged from
within the ::drag-end signal. In order to do this, we need to keep a
reference on the action for the duration of the emit_drag_end() function
as well as resetting the action's state inside the dispose()
implementation, to avoid trying to access cleared data.
https://bugzilla.gnome.org/show_bug.cgi?id=681814
When setting a drag handle, transform the original press
coordinates using the drag handle as reference instead of the
associated actor.
This causes the initial misplacement of drag handle in
example/drag-action when holding down the Shift key: the handle
gets placed at the main actor origin on the first drag event,
instead of following the mouse pointer.
All subsequent motion events already use the right actor when
transforming the coordinates, thus they are not affected.
https://bugzilla.gnome.org/show_bug.cgi?id=681746
If the DragAction has a drag handle that gets destroyed inside the
::drag-end signal handler, the destruction sequence will trigger a
callback we have in place to check if the handle is being destroyed
mid-drag, e.g. from a ::drag-motion event.
The callback on the drag handle destruction will check if we are still
in the middle of a drag and emit the ::drag-end signal to allow cleaning
up; the callback erroneously uses the drag handle as the argument for
the emit_drag_end() function — instead of the actor to which the drag
action has been attached. Also, by the time we emit the ::drag-end, we
are not dragging the actor any more, so we shouldn't be emitted the
::drag-end signal twice.
The fix is, thus, made of two parts:
- reset the in_drag boolean before emitting the ::drag-end signal
so that destroying the drag handle will not result in a double
signal emission;
- use the correct actor when calling emit_drag_end().
https://bugzilla.gnome.org/show_bug.cgi?id=681814
Allow setting a ClutterRect on the drag action and force the
dragged actor's position to be always within that rectangle (relative
to the actor's parent).
https://bugzilla.gnome.org/show_bug.cgi?id=681168
Overriding the default behaviour of ClutterDragAction::drag-motion is
currently a pain; you either need to subclass the ClutterDragAction and
override the class closure for the signal, or you need to connect to the
signal and call g_signal_stop_emission_by_name() - neither option being
particularly nice or clean. The established pattern for these cases
would be to have a boolean return value on the ::drag-motion signal, but
we cannot do that without breaking ABI.
To solve the issue in a backward compatible way, we should introduce a
new signal, ::drag-progress, with a boolean return value. If the signal
emission chain returns TRUE, the ::drag-motion signal will be emitted,
and the default behaviour will be honoured; if the signal emission chain
returns FALSE, instead, the ::drag-motion signal will not be emitted.
https://bugzilla.gnome.org/show_bug.cgi?id=679451
The example code that is meant to be XIncluded into the API reference
should not be part of the interactive test suite: it's code that it is
meant to be used as a reference implementation - whereas the interactive
test suite should be allowed to be lean and test behaviour even in nasty
ways. In short: the test suite should not be the place where we show off
idiomatic code for educational purposes.
The introspection scanner has become slightly more annoying, in the hope
that people start fixing their annotations. As it turns out, it was the
right move.
Complete the quest of commit bc548dc862
by making the ClutterStage methods for controlling the per-actor motion
and crossing event delivery public, and deprecating the global ones.
ClutterDragAction should be able to use the newly added ClutterSettings
property exposing the system's drag threshold.
Currently, the x-drag-threshold and the y-drag-threshold properties (and
relative accessors) use an unsigned integer for their values; we should
be able to safely expand the range to include -1 as the minimum value,
and use this new value to tell the ClutterDragAction that it should query
the ClutterSettings object for the drag threshold.
The storage of the properties has been changed, albeit in a compatible
way, as GObject installs a uint ↔ int transformation function for GValue
automatically.
The setter for the drag thresholds has been changes to use a signed
integer, but the getter has been updated to always Do The Right Thing™:
it never returns -1 but, instead, will return the valid drag threshold,
either from the value set or from the Settings singleton.
This change is ABI compatible.
http://bugzilla.clutter-project.org/show_bug.cgi?id=2583
When drag threshold is not reached, emit_drag_begin() is not called
causing default value of priv->motion_events_enabled (false) to used to
restore motion events enabled state in Clutter. This causes drag action
to indefinitely disable motion events. The current value of motion
events enabled state is now queried on button press which guarantees
that the state will be restored with the correct value in
emit_drag_end()
http://bugzilla.clutter-project.org/show_bug.cgi?id=2522
GObject ≥ 2.26.0 added a nice convenience call for installing properties
from an array of GParamSpec. Since we're already storing all GParamSpec
in an array in order to use them with g_object_notify_by_pspec(), this
turns out nicely for us.
Since we do not depend on GLib 2.26 (yet), we need to provide a simple
private wrapper that implements the fall back to the default
g_object_class_install_property() call.
ClutterDragAction has been converted as a proof of concept.
*** This is an API change ***
Replaced the original drag-threshold property with two separate
horizontal (x-drag-threshold) and vertical (y-drag-threshold)
thresholds.
It is some times necessary to have different drag thresholds for the
horizontal and vertical axes. For example, when a draggable actor is
inside a horizontal scrolling area, only vertical movement must begin
dragging. That can be achieved by setting the x-drag-threshold to
G_MAXUINT while y-drag-threshold is something usual, say, 20 pixels.
This is different than drag axis, because after the threshold
has been cleared by the pointer, the draggable actor can be dragged
along both axes (if allowed by the drag-axis property).
http://bugzilla.clutter-project.org/show_bug.cgi?id=2291
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
This adds a wrapper macro to clutter-private that will use
g_object_notify_by_pspec if it's compiled against a version of GLib
that is sufficiently new. Otherwise it will notify by the property
name as before by extracting the name from the pspec. The objects can
then store a static array of GParamSpecs and notify using those as
suggested in the documentation for g_object_notify_by_pspec.
Note that the name of the variable used for storing the array of
GParamSpecs is obj_props instead of properties as used in the
documentation because some places in Clutter uses 'properties' as the
name of a local variable.
Mose of the classes in Clutter have been converted using the script in
the bug report. Some classes have not been modified even though the
script picked them up as described here:
json-generator:
We probably don't want to modify the internal copy of JSON
behaviour-depth:
rectangle:
score:
stage-manager:
These aren't using the separate GParamSpec* variable style.
blur-effect:
win32/device-manager:
Don't actually define any properties even though it has the enum.
box-layout:
flow-layout:
Have some per-child properties that don't work automatically with
the script.
clutter-model:
The script gets confused with ClutterModelIter
stage:
Script gets confused because PROP_USER_RESIZE doesn't match
"user-resizable"
test-layout:
Don't really want to modify the tests
http://bugzilla.clutter-project.org/show_bug.cgi?id=2150
While dragging we don't need to perform picking to determine the actor
underneath the pointer, for two reasons:
• we use a capture on the stage to determine the motion delta.
• we know the actor underneath the pointer because that's the
actor we are dragging around.
This change should make dragging actors in complex scenes a bit faster.
Both ::drag-begin and ::drag-end have a "button" argument - even though
we assume internally, and externally, that dragging can only be the
result of a primary button operation.
The marshallers we use for the signals are declared in a private header,
and it stands to reason that they should also be hidden in the shared
object by using the common '_' prefix. We are also using some direct
g_cclosure_marshal_* symbol from GLib, instead of consistently use the
clutter_marshal_* symbol.
Since emit_drag_end() can be called from a MOTION event capture we
cannot call clutter_event_get_button(). We should, instead, use the
press_button value because if we're emitting ::drag-end it means we
also emitted ::drag-begin and the value is valid.
The DragAction should, by default, drag the actor to which it has been
applied, instead of delegating what to do to the developer. If custom
code need to override it, g_signal_stop_emission_by_name() can be called
to stop the default handler to ever running.
DragAction is an Action sub-class that provides dragging capabilities to
any actor. DragAction has:
• drag-begin, drag-motion and drag-end signals, relaying the event
information like coordinates, button and modifiers to user code;
• drag-threshold property, for delaying the drag start by a given
amount of pixels;
• drag-handle property, to allow using other actors as the drag
handle.
• drag-axis property, to allow constraining the dragging to a specific
axis.
An interactive test demonstrating the various features is also provided.