After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 682362 - Multi touch events skipped
Multi touch events skipped
Status: RESOLVED FIXED
Product: clutter
Classification: Platform
Component: general
git master
Other Linux
: Normal normal
: ---
Assigned To: clutter-maint
clutter-maint
Depends on:
Blocks:
 
 
Reported: 2012-08-21 14:50 UTC by Lionel Landwerlin
Modified: 2012-09-03 20:55 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Patch v1 (6.08 KB, patch)
2012-08-21 14:51 UTC, Lionel Landwerlin
none Details | Review
input-device: don't reset a device's stage until all touch points are gone (11.58 KB, patch)
2012-08-31 16:19 UTC, Tomeu Vizoso
none Details | Review
input-device: don't reset a device's stage until all touch points are gone (11.59 KB, patch)
2012-09-03 13:02 UTC, Tomeu Vizoso
committed Details | Review

Description Lionel Landwerlin 2012-08-21 14:50:09 UTC
803b3bafb617c2df703aa8b834ff0df2f0c5c26c introduced a new issue for
multi touch events.

In the case where 2 touch events for 2 different touch points are
processed in the same iteration, a call to
_clutter_stage_remove_device() when processing the first event will
remove the stage setting of the InputDevice. That means Clutter will
skip the second event, because it can't find a stage to which relate
the event, so no related actor and so no emission.

To fix this we move the _clutter_stage_(add/remove)_device() calls
into the input device. This way the input device can find out exactly
when to call these functions (i.e. when no touch point were previously
active or when no touch point remain active).
Comment 1 Lionel Landwerlin 2012-08-21 14:51:05 UTC
Created attachment 222018 [details] [review]
Patch v1
Comment 2 Tomeu Vizoso 2012-08-22 09:54:17 UTC
Doesn't seem to work here, with this patch applied, touch events have no stage defined and thus aren't delivered:

Clutter-Message: [         +448153]:[EVENT]:./clutter-input-device.c:861: No stage defined for device 'Virtual core pointer'
Comment 3 Lionel Landwerlin 2012-08-22 17:25:36 UTC
Could you put a break point on the _clutter_input_device_set_stage() function and print the backtrace when that function gets called with NULL as second argument?

That will cause the reset of the stage value of the input device which ends up generating that message.

Thanks
Comment 4 Tomeu Vizoso 2012-08-23 09:36:53 UTC
Backtrace:

  • #0 _clutter_input_device_set_stage
    at ./clutter-input-device.c line 483
  • #1 _clutter_stage_remove_device
    at ./clutter-stage.c line 4183
  • #2 clutter_device_manager_xi2_translate_event
    at ./x11/clutter-device-manager-xi2.c line 1202
  • #3 _clutter_event_translator_translate_event
    at ./clutter-event-translator.c line 37
  • #4 clutter_backend_real_translate_event
    at ./clutter-backend.c line 572
  • #5 clutter_backend_x11_translate_event
    at ./x11/clutter-backend-x11.c line 695
  • #6 _clutter_backend_translate_event
    at ./clutter-backend.c line 1256
  • #7 clutter_x11_handle_event
    at ./x11/clutter-event-x11.c line 199
  • #8 meta_plugin_manager_xevent_filter
    at compositor/meta-plugin-manager.c line 311
  • #9 meta_compositor_process_event
    at compositor/compositor.c line 775
  • #10 event_callback
    at core/display.c line 2704
  • #11 filter_func
    at ui/ui.c line 228
  • #12 gdk_event_apply_filters
    at gdkeventsource.c line 81
  • #13 gdk_event_source_translate_event
    at gdkeventsource.c line 195
  • #14 _gdk_x11_display_queue_events
    at gdkeventsource.c line 332
  • #15 gdk_display_get_event
    at gdkdisplay.c line 310
  • #16 gdk_event_source_dispatch
    at gdkeventsource.c line 354
  • #17 g_main_dispatch
    at gmain.c line 2698
  • #18 g_main_context_dispatch
    at gmain.c line 3202
  • #19 g_main_context_iterate
    at gmain.c line 3273
  • #20 g_main_loop_run
    at gmain.c line 3467
  • #21 meta_run
    at core/main.c line 546
  • #22 main
    at core/mutter.c line 86

Device:

$1 = {parent_instance = {g_type_instance = {g_class = 0x464260}, ref_count = 2, qdata = 
    0x0}, id = 2, device_type = CLUTTER_POINTER_DEVICE, 
  device_mode = CLUTTER_INPUT_MODE_MASTER, device_name = 0x630960 "Virtual core pointer", 
  device_manager = 0x467d20, backend = 0x416080, associated = 0x5bfb90, slaves = 0x0, 
  cursor_actor = 0x0, inv_touch_sequence_actors = 0x65ecc0, pointer_grab_actor = 0x0, 
  keyboard_grab_actor = 0x0, sequence_grab_actors = 0x0, inv_sequence_grab_actors = 0x0, 
  click_count = 0, stage = 0x74aea0, current_x = 432, current_y = 169, 
  current_time = 12910520, current_button_number = -1, current_state = 0, 
  touch_sequences_info = 0x65ec60, previous_x = -1, previous_y = -1, previous_time = 0, 
  previous_button_number = -1, previous_state = 0, axes = 0x466ec0, n_keys = 0, keys = 0x0, 
  scroll_info = 0x0, has_cursor = 1, is_enabled = 1}

ClutterEvent:

$2 = {type = CLUTTER_LEAVE, any = {type = CLUTTER_LEAVE, time = 12910520, 
    flags = CLUTTER_EVENT_NONE, stage = 0x74aea0, source = 0x74aea0}, button = {
    type = CLUTTER_LEAVE, time = 12910520, flags = CLUTTER_EVENT_NONE, stage = 0x74aea0, 
    source = 0x74aea0, x = 432, y = 169, modifier_state = 0, button = 0, click_count = 0, 
    axes = 0x0, device = 0x0}, key = {type = CLUTTER_LEAVE, time = 12910520, 
    flags = CLUTTER_EVENT_NONE, stage = 0x74aea0, source = 0x74aea0, 
    modifier_state = 1138229248, keyval = 1126760448, hardware_keycode = 0, 
    unicode_value = 0, device = 0x0}, motion = {type = CLUTTER_LEAVE, time = 12910520, 
    flags = CLUTTER_EVENT_NONE, stage = 0x74aea0, source = 0x74aea0, x = 432, y = 169, 
    modifier_state = 0, axes = 0x0, device = 0x0}, scroll = {type = CLUTTER_LEAVE, 
    time = 12910520, flags = CLUTTER_EVENT_NONE, stage = 0x74aea0, source = 0x74aea0, 
    x = 432, y = 169, direction = CLUTTER_SCROLL_UP, modifier_state = 0, axes = 0x0, 
    device = 0x0}, stage_state = {type = CLUTTER_LEAVE, time = 12910520, 
    flags = CLUTTER_EVENT_NONE, stage = 0x74aea0, source = 0x74aea0, 
    changed_mask = (unknown: 1138229248), new_state = (unknown: 1126760448)}, crossing = {
    type = CLUTTER_LEAVE, time = 12910520, flags = CLUTTER_EVENT_NONE, stage = 0x74aea0, 
    source = 0x74aea0, x = 432, y = 169, device = 0x0, related = 0x0}, touch = {
    type = CLUTTER_LEAVE, time = 12910520, flags = CLUTTER_EVENT_NONE, stage = 0x74aea0, 
    source = 0x74aea0, x = 432, y = 169, sequence = 0x0, modifier_state = 0, axes = 0x0, 
    device = 0x0}}

XIDeviceEvent (XI_Leave):

$3 = {type = 35, serial = 0, send_event = 0, display = 0x44c6a0, extension = 131, 
  evtype = 8, time = 12910520, deviceid = 2, sourceid = 2, detail = 2, root = 99, 
  event = 8388631, child = 0, root_x = 432, root_y = 169, event_x = 432, event_y = 169, 
  mode = 0, focus = 0, same_screen = 1, buttons = {mask_len = 4, mask = 0x7e37b8 ""}, 
  mods = {base = 8, latched = 0, locked = 18, effective = 0}, group = {base = 0, 
    latched = 0, locked = 0, effective = 0}}
Comment 5 Lionel Landwerlin 2012-08-23 09:50:54 UTC
Ah! Really interesting that this is done by the backend.
The purpose of my patch was to move the device/stage association to the generic part of clutter (clutter-main.c/clutter-input-device.c).

I suppose if I remove all these calls from the backends, then things should work.

At the moment we call _clutter_stage_add_device()/_clutter_stage_remove_device() from the backend side at event translation time and then we do it again when processing the event in clutter-main.c.

Emmanuele any advice on this?
Comment 6 Emmanuele Bassi (:ebassi) 2012-08-23 10:08:22 UTC
in theory, it should be possible to do it from the event processing stage, instead of the event translation stage; I'm just a bit worried to break existing invariants - e.g. crossing events get delivered to an actor placed at the edge of the stage before sending the crossing event to the stage (tests/interactive/test-events has a purple actor positioned there just for this use case).
Comment 7 Tomeu Vizoso 2012-08-31 16:19:09 UTC
Created attachment 223082 [details] [review]
input-device: don't reset a device's stage until all touch points are gone

803b3bafb617c2df703aa8b834ff0df2f0c5c26c introduced a new issue for
multi touch events.

In the case where 2 touch events for 2 different touch points are
processed in the same iteration, a call to
_clutter_stage_remove_device() when processing the first event will
remove the stage setting of the InputDevice. That means Clutter will
skip the second event, because it can't find a stage to which relate
the event, so no related actor and so no emission.

To fix this we move the _clutter_stage_(add/remove)_device() calls
into the input device. This way the input device can find out exactly
when to call these functions (i.e. when no touch point were previously
active or when no touch point remain active).
Comment 8 Tomeu Vizoso 2012-09-03 13:02:03 UTC
Created attachment 223296 [details] [review]
input-device: don't reset a device's stage until all touch points are gone

The previous patch didn't apply cleanly, this one should.
Comment 9 Lionel Landwerlin 2012-09-03 20:45:41 UTC
The patch (https://bugzilla.gnome.org/attachment.cgi?id=223082) works for fine for me on top of https://bugzilla.gnome.org/show_bug.cgi?id=683126

But not sure why the last one do not apply on top of https://bugzilla.gnome.org/show_bug.cgi?id=683126

Anyway, thanks problem solved!
Comment 10 Emmanuele Bassi (:ebassi) 2012-09-03 20:55:30 UTC
Attachment 223296 [details] pushed as d6a0f7e - input-device: don't reset a device's stage until all touch points are gone