diff --git a/12to11.man b/12to11.man index cd35cb7..7f7acdc 100644 --- a/12to11.man +++ b/12to11.man @@ -199,7 +199,7 @@ wl_compositor 5 wl_shm 1 xdg_wm_base 5 wl_subcompositor 1 -wl_seat 7 +wl_seat 8 wl_data_device_manager 3 zwp_linux_dmabuf_v1 4 zwp_primary_selection_device_manager_v1 1 diff --git a/README b/README index cfa9c28..ece6452 100644 --- a/README +++ b/README @@ -57,7 +57,7 @@ complete degree: 'wl_shm', version: 1 'xdg_wm_base', version: 5 'wl_subcompositor', version: 1 - 'wl_seat', version: 7 + 'wl_seat', version: 8 'wl_data_device_manager', version: 3 'zwp_linux_dmabuf_v1', version: 4 'zwp_primary_selection_device_manager_v1', version: 1 diff --git a/seat.c b/seat.c index 90923dc..26f9040 100644 --- a/seat.c +++ b/seat.c @@ -1832,7 +1832,7 @@ MakeSeatForDevicePair (int master_keyboard, int master_pointer, seat->master_keyboard = master_keyboard; seat->master_pointer = master_pointer; seat->global = wl_global_create (compositor.wl_display, - &wl_seat_interface, 7, + &wl_seat_interface, 8, seat, HandleBind); seat->client_info.next = &seat->client_info; seat->client_info.last = &seat->client_info; @@ -2542,9 +2542,10 @@ HandleRawButton (XIRawEvent *event) if (QueryPointer (seat, window, &win_x, &win_y)) { /* Otherwise, the pointer is on a different screen! */ - TransformToSurface (seat->last_seen_surface, win_x, win_y, &dispatch_x, &dispatch_y); + + /* And finally the button release. */ SendButton (seat, seat->last_seen_surface, event->time, button, WL_POINTER_BUTTON_STATE_RELEASED, dispatch_x, dispatch_y); @@ -3639,6 +3640,12 @@ DispatchEntryExit (Subcompositor *subcompositor, XIEnterEvent *event) TransformToSurface (dispatch, event_x, event_y, &x, &y); EnteredSurface (seat, dispatch, event->time, x, y, False); + + /* If this entry event was the result of a grab, also send + motion now, as a corresponding XI_Motion will not arrive + later. */ + if (event->mode == XINotifyUngrab) + SendMotion (seat, dispatch, x, y, event->time); } seat->last_motion_x = event->root_x; @@ -3726,15 +3733,33 @@ SendScrollAxis (Seat *seat, Surface *surface, Time time, pointer->info->last_enter_serial = serial; } - if (axis_x != 0.0) - wl_pointer_send_axis (pointer->resource, time, - WL_POINTER_AXIS_HORIZONTAL_SCROLL, - wl_fixed_from_double (axis_x)); + if (wl_resource_get_version (pointer->resource) < 8) + { + if (axis_x != 0.0) + wl_pointer_send_axis (pointer->resource, time, + WL_POINTER_AXIS_HORIZONTAL_SCROLL, + wl_fixed_from_double (axis_x)); - if (axis_y != 0.0) - wl_pointer_send_axis (pointer->resource, time, - WL_POINTER_AXIS_VERTICAL_SCROLL, - wl_fixed_from_double (axis_y)); + if (axis_y != 0.0) + wl_pointer_send_axis (pointer->resource, time, + WL_POINTER_AXIS_VERTICAL_SCROLL, + wl_fixed_from_double (axis_y)); + } + else + { + /* Send value120 events if they are available; those events + make more sense. */ + + if (axis_x != 0.0) + wl_pointer_send_axis_value120 (pointer->resource, + WL_POINTER_AXIS_HORIZONTAL_SCROLL, + axis_x * 12); + + if (axis_y != 0.0) + wl_pointer_send_axis_value120 (pointer->resource, + WL_POINTER_AXIS_VERTICAL_SCROLL, + axis_y * 12); + } if (axis_y == 0.0 && axis_x == 0.0) { diff --git a/subsurface.c b/subsurface.c index b9182ff..211803a 100644 --- a/subsurface.c +++ b/subsurface.c @@ -853,6 +853,22 @@ HandleSubsurfaceResourceDestroy (struct wl_resource *resource) DestroyBacking (subsurface); } +static Surface * +GetRootSurface (Surface *surface) +{ + Subsurface *subsurface; + + if (surface->role_type != SubsurfaceType || !surface->role) + return surface; + + subsurface = SubsurfaceFromRole (surface->role); + + if (!subsurface->parent) + return surface; + + return GetRootSurface (subsurface->parent); +} + static void GetSubsurface (struct wl_client *client, struct wl_resource *resource, uint32_t id, struct wl_resource *surface_resource, @@ -870,11 +886,27 @@ GetSubsurface (struct wl_client *client, struct wl_resource *resource, if (surface->role || (surface->role_type != AnythingType && surface->role_type != SubsurfaceType)) { - wl_resource_post_error (resource, WL_DISPLAY_ERROR_IMPLEMENTATION, + wl_resource_post_error (resource, WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE, "trying to attach subsurface to surface with role"); return; } + /* Check that a parent loop won't happen. */ + + if (parent == surface) + { + wl_resource_post_error (resource, WL_SUBCOMPOSITOR_ERROR_BAD_PARENT, + "trying to attach subsurface to itself"); + return; + } + + if (GetRootSurface (parent) == surface) + { + wl_resource_post_error (resource, WL_SUBCOMPOSITOR_ERROR_BAD_PARENT, + "specified parent is ancestor of subsurface"); + return; + } + subsurface = XLSafeMalloc (sizeof *subsurface); if (!subsurface)