Implement support for zwp_pointer_constraints_v1

* 12to11.c (XLMain): Initialize pointer constraints.
* 12to11.conf: Add Emacs local variables section.
* 12to11.man: Document new protocol.
* Imakefile (SRCS): Add pointer_constraints.c.
(OBJS): Add pointer_constraints.o.
(pointer-constraints-unstable-v1): New scanner target.
* README: Update accordingly.
* compositor.h (enum _ClientDataType): Add
PointerConfinementData.
* dmabuf.c (struct _BufferParams): Rearrange for alignment.
(struct _Buffer): Rearrange for alignment.
* dnd.c (struct _DndState, struct _DragState)
(struct _WindowCacheEntry):
* seat.c (struct _SeatCursor, struct _ScrollValuator)
(struct _SeatClientInfo, struct _Seat): Rearrange for alignment.
(SendMotion): Do not send pointer motion to locked seats.
(CheckPointerBarrier): New function.
(EnteredSurface, DispatchMotion): Check for pointer confinement
changes.
(XLSeatGetPointerDevice): New function.
(XLPointerGetSeat, XLSeatGetMouseData, XLSeatLockPointer)
(XLSeatUnlockPointer): New functions.
* shm.c (HandleResourceDestroy, CreatePool, HandleBind): Remove
redundant `all_shms' field.
* subcompositor.c (struct _View): New function `maybe_resized'.
(ViewAfterSizeUpdate): Call it if necessary.
(ViewAttachBuffer): Update a comment.
(ViewSetMaybeResizedFunction): New function.
* subsurface.c (MoveFractional):
* surface.c (ApplyInputRegion, HandleScaleChanged, MaybeResized)
(XLCreateSurface, XLWindowFromSurface): Update pointer
constraints.
* xdata.c (struct _ReadTargetsData, struct _ConversionTransferInfo)
(struct _TargetMappingTable): Rearrange for alignment.
(XLInitXData): Require fixes 1.5.
* xdg_surface.c (struct _XdgRole): Rearrange fr alignment.
(AckConfigure): Fix serial monotonicity checking.
(NoteConfigure): Update pointer constraints.
* xdg_toplevel.c (struct _XdgToplevel): Rearrange for alignment.
This commit is contained in:
oldosfan 2022-10-15 07:58:40 +00:00
parent 7810cbb79f
commit 98bbad068c
16 changed files with 371 additions and 244 deletions

View file

@ -225,6 +225,7 @@ XLMain (int argc, char **argv)
XLInitTextInput ();
XLInitSinglePixelBuffer ();
XLInitDrmLease ();
XLInitPointerConstraints ();
/* This has to come after the rest of the initialization. */
DetermineServerTime ();

View file

@ -18,6 +18,9 @@ WAYLAND_SCANNER = wayland-scanner
/* Uncomment the following code if building with EGL support. */
XCOMM #define HaveEglSupport
XCOMM
XCOMM EGL = -lEGL
XCOMM GLES = -lGLESv2
XCOMM Local Variables:
XCOMM mode: makefile-imake
XCOMM End:

View file

@ -201,6 +201,7 @@ wp_viewporter 1
zxdg_decoration_manager_v1 1
zwp_text_input_manager_v3 1
wp_single_pixel_buffer_manager_v1 1
zwp_pointer_constraints_v1 1
.TE
.PP
When the protocol translator is built with EGL support, the following

View file

@ -23,7 +23,7 @@ SRCS = 12to11.c run.c alloc.c fns.c output.c compositor.c \
icon_surface.c primary_selection.c renderer.c \
picture_renderer.c explicit_synchronization.c transform.c \
wp_viewporter.c decoration.c text_input.c \
single_pixel_buffer.c drm_lease.c
single_pixel_buffer.c drm_lease.c pointer_constraints.c
OBJS = 12to11.o run.o alloc.o fns.o output.o compositor.o \
surface.o region.o shm.o atoms.o subcompositor.o positioner.o \
@ -33,7 +33,7 @@ OBJS = 12to11.o run.o alloc.o fns.o output.o compositor.o \
icon_surface.o primary_selection.o renderer.o \
picture_renderer.o explicit_synchronization.o transform.o \
wp_viewporter.o decoration.o text_input.o \
single_pixel_buffer.o drm_lease.o
single_pixel_buffer.o drm_lease.o pointer_constraints.o
GENHEADERS = transfer_atoms.h
@ -117,6 +117,7 @@ ScannerTarget(xdg-decoration-unstable-v1)
ScannerTarget(text-input-unstable-v3)
ScannerTarget(single-pixel-buffer-v1)
ScannerTarget(drm-lease-v1)
ScannerTarget(pointer-constraints-unstable-v1)
/* Make OBJS depend on scanner headers, and depend on both them and SRCS. */
$(OBJS): $(GENHEADERS)

23
README
View file

@ -2,10 +2,7 @@ This is a tool for running Wayland applications on an X server,
preferably with a compositing manager running.
It is not yet complete. What is not yet implemented includes support
for touchscreens, input methods, device switching in dmabuf feedback,
and the single-pixel buffer protocol extension.
There are also problems with output reporting in subsurfaces.
for touchscreens, and device switching in dmabuf feedback.
It is not portable to systems other than recent versions of GNU/Linux
running the X.Org server 1.20 or later, and has not been tested on
@ -20,20 +17,19 @@ extensions:
Nonrectangular Window Shape Extension, version 1.1 or later
MIT Shared Memory Extension, version 1.2 or later
X Resize, Rotate and Reflect Extension, version 1.3 or later
(this will soon be 1.4, once support for multiple GPU
systems is fully implemented)
X Synchronization Extension, version 1.0 or later
X Rendering Extension, version 1.2 or later
X Input Extension, version 2.3 or later
Direct Rendering Interface 3, version 1.2 or later
X Fixes Extension, version 1 or later
X Fixes Extension, version 1.5 or later
X Presentation Extension, version 1.0 or later
In addition, it requires Xlib to be built with the XCB transport, and
the XCB bindings for MIT-SHM and DRI3 to be available.
Sometimes, it might be desirable to build with EGL, and use OpenGL ES
2.0 for i.e. YUV video format support. To do so, uncomment the block
of code for EGL support in libraries.def before running `xmkmf'. This
of code for EGL support in 12to11.conf before running `xmkmf'. This
will additionally require the EGL and GLESv2 development files, and
for the following EGL and GLES extensions to be present at runtime:
@ -69,11 +65,18 @@ complete degree:
'zxdg_decoration_manager_v1', version: 1
'zwp_text_input_manager_v3', version: 1
'wp_single_pixel_buffer_manager_v1', version: 1
'zwp_pointer_constraints_v1', version: 1
When built with EGL, the following Wayland protocol is also supported:
'zwp_linux_explicit_synchronization_v1', version: 2
When the X server supports version 1.6 or later of the X Resize,
Rotate and Reflect Extension, the following Wayland protocol is also
supported:
'wp_drm_lease_device_v1', version: 1
With the main caveat being that zwp_linux_dmabuf_v1 has no real
support for multiple-provider setups (help wanted).
@ -85,7 +88,7 @@ It would also be nice to have pinch gesture support.
This directory is organized as follows:
Imakefile - the top level Makefile template
libraries.def - files for libraries that don't provide Imakefiles
12to11.conf - configuration
*.xml - Wayland protocol definition source
*.c, *.h - C source code
*.awk - scripts used to generate headers
@ -93,7 +96,7 @@ This directory is organized as follows:
those containing MIME types or shaders
Building the source code is simple, provided that you have the
necessary libwayland-server library, pixman, XCB, and X extension
necessary libwayland-server library, pixman, XCB, DRM, and X extension
libraries installed:
xmkmf # to generate the Makefile

View file

@ -89,6 +89,7 @@ struct _Compositor
/* Forward declarations from seat.c. */
typedef struct _Seat Seat;
typedef struct _Pointer Pointer;
/* Forward declarations from primary_selection.c. */
@ -749,6 +750,8 @@ extern void ViewClearViewport (View *);
extern void ViewSetData (View *, void *);
extern void *ViewGetData (View *);
extern void ViewSetMaybeResizedFunction (View *, void (*) (View *));
extern void ViewTranslate (View *, int, int, int *, int *);
extern void ViewFree (View *);
@ -860,6 +863,7 @@ typedef struct _DestroyCallback DestroyCallback;
enum _ClientDataType
{
SubsurfaceData,
PointerConfinementData,
MaxClientData,
};
@ -1398,9 +1402,15 @@ extern unsigned int XLSeatGetEffectiveModifiers (Seat *);
extern Bool XLSeatResizeInProgress (Seat *);
extern void XLSeatSetTextInputFuncs (TextInputFuncs *);
extern int XLSeatGetKeyboardDevice (Seat *);
extern int XLSeatGetPointerDevice (Seat *);
extern Seat *XLSeatGetInputMethodSeat (void);
extern void XLSeatDispatchCoreKeyEvent (Seat *, Surface *, XEvent *,
KeySym);
extern Seat *XLPointerGetSeat (Pointer *);
extern void XLSeatGetMouseData (Seat *, Surface **, double *, double *,
double *, double *);
extern void XLSeatLockPointer (Seat *);
extern void XLSeatUnlockPointer (Seat *);
extern Cursor InitDefaultCursor (void);
@ -1554,10 +1564,20 @@ extern void XLInitDecoration (void);
extern void XLInitSinglePixelBuffer (void);
/* Defined in drm_lease.h. */
/* Defined in drm_lease.c. */
extern void XLInitDrmLease (void);
/* Defined in pointer_constraints.c. */
extern void XLInitPointerConstraints (void);
extern void XLPointerBarrierCheck (Seat *, Surface *, double, double,
double, double);
extern void XLPointerBarrierLeft (Seat *, Surface *);
extern void XLPointerConstraintsSurfaceMovedTo (Surface *, int, int);
extern void XLPointerConstraintsSubsurfaceMoved (Surface *);
extern void XLPointerConstraintsReconfineSurface (Surface *);
/* Utility functions that don't belong in a specific file. */
#define ArrayElements(arr) (sizeof (arr) / sizeof (arr)[0])

View file

@ -62,12 +62,12 @@ struct _BufferParams
/* Entries for each plane. DRI3 only supports up to 4 planes. */
TemporarySetEntry entries[4];
/* Some flags. */
int flags;
/* The struct wl_resource associated with this object. */
struct wl_resource *resource;
/* Some flags. */
int flags;
/* The width and height of the buffer that will be created. */
int width, height;
};
@ -80,15 +80,15 @@ struct _Buffer
/* The RenderBuffer associated with this buffer. */
RenderBuffer render_buffer;
/* The width and height of this buffer. */
unsigned int width, height;
/* The wl_resource corresponding to this buffer. */
struct wl_resource *resource;
/* List of "destroy listeners" connected to this buffer. */
XLList *destroy_listeners;
/* The width and height of this buffer. */
unsigned int width, height;
/* The number of references to this buffer. */
int refcount;
};

58
dnd.c
View file

@ -59,9 +59,6 @@ struct _DndState
/* The target window. */
Window target_window;
/* The protocol version in use. */
int proto;
/* The seat that is being used. */
Seat *seat;
@ -73,6 +70,19 @@ struct _DndState
convenient. */
char **targets;
/* The timestamp to use for accessing selection data. */
Time timestamp;
/* The toplevel or child surface the pointer is currently
inside. */
Surface *child;
/* The unmap callback for that child. */
UnmapCallback *unmap_callback;
/* The protocol version in use. */
int proto;
/* Number of targets in that array. */
int ntargets;
@ -111,16 +121,6 @@ struct _DndState
/* Whether or not the drop has already happened. */
Bool dropped;
/* The timestamp to use for accessing selection data. */
Time timestamp;
/* The toplevel or child surface the pointer is currently
inside. */
Surface *child;
/* The unmap callback for that child. */
UnmapCallback *unmap_callback;
/* The version of the XDND protocol being used. */
int version;
};
@ -153,6 +153,12 @@ struct _DragState
/* The window cache. */
WindowCache *window_cache;
/* The time at which ownership of the selection was obtained. */
Time timestamp;
/* The selected action. */
Atom action;
/* The last coordinates the pointer was seen at. */
int last_root_x, last_root_y;
@ -173,12 +179,6 @@ struct _DragState
sent. */
XRectangle mouse_rect;
/* The time at which ownership of the selection was obtained. */
Time timestamp;
/* The selected action. */
Atom action;
/* The modifiers currently held down. */
unsigned int modifiers;
};
@ -215,19 +215,9 @@ struct _WindowCacheEntry
is really a WindowCacheEntryHeader. */
WindowCacheEntry *children;
/* The bounds of the window relative to its parents. */
int x, y, width, height;
/* Some flags. The protocol version is flags >> 16 & 0xff; 0 means
XDND is not supported. */
int flags;
/* The XDND proxy window. Usually None. */
Window dnd_proxy;
/* The region describing its shape. */
pixman_region32_t shape;
/* The window cache. */
WindowCache *cache;
@ -236,6 +226,16 @@ struct _WindowCacheEntry
/* The key for input selection, if this is the root window. */
RootWindowSelection *input_key;
/* The bounds of the window relative to its parents. */
int x, y, width, height;
/* Some flags. The protocol version is flags >> 16 & 0xff; 0 means
XDND is not supported. */
int flags;
/* The region describing its shape. */
pixman_region32_t shape;
};
/* The global drop state. */

262
seat.c
View file

@ -87,6 +87,7 @@ enum
IsDragging = (1 << 3),
IsDropped = (1 << 4),
IsTextInputSeat = (1 << 5),
IsPointerLocked = (1 << 6),
};
enum
@ -215,22 +216,22 @@ struct _SeatCursor
/* The seat this cursor is for. */
Seat *seat;
/* The hotspot of the cursor. */
int hotspot_x, hotspot_y;
/* The subcompositor for this cursor. */
Subcompositor *subcompositor;
/* The frame callback for this cursor. */
void *cursor_frame_key;
/* Whether or not this cursor is currently keeping the cursor clock
active. */
Bool holding_cursor_clock;
/* Ring of render targets for cursors. This allows updating the
cursor while not creating a new render target each time. */
CursorRing *cursor_ring;
/* The hotspot of the cursor. */
int hotspot_x, hotspot_y;
/* Whether or not this cursor is currently keeping the cursor clock
active. */
Bool holding_cursor_clock;
};
struct _ResizeDoneCallback
@ -250,8 +251,8 @@ struct _ScrollValuator
/* The next scroll valuator in this list. */
ScrollValuator *next;
/* The direction of this valuator. */
Direction direction;
/* The serial of the last event to have updated this valuator. */
unsigned long enter_serial;
/* The current value of this valuator. */
double value;
@ -262,8 +263,8 @@ struct _ScrollValuator
/* The number of this valuator. */
int number;
/* The serial of the last event to have updated this valuator. */
unsigned long enter_serial;
/* The direction of this valuator. */
Direction direction;
};
struct _Pointer
@ -309,17 +310,17 @@ struct _SeatClientInfo
/* The next and last structures in the client info chain. */
SeatClientInfo *next, *last;
/* List of pointer objects on this seat for this client. */
Pointer pointers;
/* List of keyboard objects on this seat for this client. */
Keyboard keyboards;
/* The client corresponding to this object. */
struct wl_client *client;
/* List of pointer objects on this seat for this client. */
Pointer pointers;
/* The serial of the last enter event sent. */
uint32_t last_enter_serial;
/* List of keyboard objects on this seat for this client. */
Keyboard keyboards;
};
struct _ModifierChangeCallback
@ -336,15 +337,15 @@ struct _ModifierChangeCallback
struct _Seat
{
/* wl_global associated with this seat. */
struct wl_global *global;
/* XI device ID of the master keyboard device. */
int master_keyboard;
/* XI device ID of the master pointer device. */
int master_pointer;
/* wl_global associated with this seat. */
struct wl_global *global;
/* Number of references to this seat. */
int refcount;
@ -382,9 +383,6 @@ struct _Seat
/* How many times the grab is held on this seat. */
int grab_held;
/* Array of keys currently held down. */
struct wl_array keys;
/* Modifier masks. */
unsigned int base, locked, latched;
@ -402,42 +400,18 @@ struct _Seat
/* The current cursor attached to this seat. */
SeatCursor *cursor;
/* The serial of the last button event sent. */
uint32_t last_button_serial;
/* The serial of the last button press event sent. GTK 4 sends this
even when grabbing a popup in response to a button release
event. */
uint32_t last_button_press_serial;
/* The last serial used to obtain a grab. */
uint32_t last_grab_serial;
/* The last edge used to obtain a grab. */
WhatEdge last_grab_edge;
/* The last timestamp used to obtain a grab. */
Time last_grab_time;
/* The button of the last button event sent, and the root_x and
root_y of the last button or motion event. */
int last_button, its_root_x, its_root_y;
/* When it was sent. */
Time its_press_time;
/* The serial of the last key event sent. */
uint32_t last_keyboard_serial;
/* The time of the last key event sent. */
Time its_depress_time;
/* Whether or not a resize is in progress. */
Bool resize_in_progress;
/* The icon surface. */
IconSurface *icon_surface;
/* Callbacks run after a resize completes. */
ResizeDoneCallback resize_callbacks;
/* The drag-and-drop grab window. This is a 1x1 InputOnly window
with an empty input region at 0, 0, used to differentiate between
events delivered to a surface during drag and drop, and events
delivered due to the grab. */
Window grab_window;
/* List of scroll valuators on this seat. */
ScrollValuator *valuators;
@ -453,6 +427,67 @@ struct _Seat
/* Unmap callback for that surface. */
UnmapCallback *resize_surface_callback;
/* The last edge used to obtain a grab. */
WhatEdge last_grab_edge;
/* The last timestamp used to obtain a grab. */
Time last_grab_time;
/* When it was sent. */
Time its_press_time;
/* The time of the last key event sent. */
Time its_depress_time;
/* The grab surface. While it exists, events for different clients
will be reported relative to it. */
Surface *grab_surface;
/* The unmap callback. */
UnmapCallback *grab_surface_callback;
/* The data source for drag-and-drop. */
DataSource *data_source;
/* The destroy callback for the data source. */
void *data_source_destroy_callback;
/* The surface on which this drag operation started. */
Surface *drag_start_surface;
/* The UnmapCallback for that surface. */
UnmapCallback *drag_start_unmap_callback;
/* The last surface to be entered during drag-and-drop. */
Surface *drag_last_surface;
/* The destroy callback for that surface. */
DestroyCallback *drag_last_surface_destroy_callback;
/* The time the active grab was acquired. */
Time drag_grab_time;
/* The button of the last button event sent, and the root_x and
root_y of the last button or motion event. */
int last_button, its_root_x, its_root_y;
/* The serial of the last button event sent. */
uint32_t last_button_serial;
/* The serial of the last button press event sent. GTK 4 sends this
even when grabbing a popup in response to a button release
event. */
uint32_t last_button_press_serial;
/* The last serial used to obtain a grab. */
uint32_t last_grab_serial;
/* The serial of the last key event sent. */
uint32_t last_keyboard_serial;
/* Whether or not a resize is in progress. */
Bool resize_in_progress;
/* Where that resize started. */
int resize_start_root_x, resize_start_root_y;
@ -483,45 +518,14 @@ struct _Seat
/* The root_x and root_y of the last motion or crossing event. */
double last_motion_x, last_motion_y;
/* The grab surface. While it exists, events for different clients
will be reported relative to it. */
Surface *grab_surface;
/* The unmap callback. */
UnmapCallback *grab_surface_callback;
/* The data source for drag-and-drop. */
DataSource *data_source;
/* The destroy callback for the data source. */
void *data_source_destroy_callback;
/* The surface on which this drag operation started. */
Surface *drag_start_surface;
/* The UnmapCallback for that surface. */
UnmapCallback *drag_start_unmap_callback;
/* The last surface to be entered during drag-and-drop. */
Surface *drag_last_surface;
/* The destroy callback for that surface. */
DestroyCallback *drag_last_surface_destroy_callback;
/* The time the active grab was acquired. */
Time drag_grab_time;
/* The icon surface. */
IconSurface *icon_surface;
/* The drag-and-drop grab window. This is a 1x1 InputOnly window
with an empty input region at 0, 0, used to differentiate between
events delivered to a surface during drag and drop, and events
delivered due to the grab. */
Window grab_window;
/* The x and y of the last surface movement. */
double last_surface_x, last_surface_y;
/* List of all modifier change callbacks attached to this seat. */
ModifierChangeCallback modifier_callbacks;
/* Array of keys currently held down. */
struct wl_array keys;
};
struct _DeviceInfo
@ -3056,9 +3060,13 @@ SendMotion (Seat *seat, Surface *surface, double x, double y,
pointer->info->last_enter_serial = serial;
}
wl_pointer_send_motion (pointer->resource, time,
wl_fixed_from_double (x),
wl_fixed_from_double (y));
/* If the seat is locked, don't send any motion events at
all. */
if (!(seat->flags & IsPointerLocked))
wl_pointer_send_motion (pointer->resource, time,
wl_fixed_from_double (x),
wl_fixed_from_double (y));
if (wl_resource_get_version (pointer->resource) >= 5)
wl_pointer_send_frame (pointer->resource);
@ -3312,6 +3320,10 @@ EnteredSurface (Seat *seat, Surface *surface, Time time,
FreeCursor (seat->cursor);
}
/* Cancel any pointer confinement. */
XLPointerBarrierLeft (seat, seat->last_seen_surface);
/* Clear the surface. */
XLSurfaceCancelRunOnFree (seat->last_seen_surface_callback);
seat->last_seen_surface = NULL;
seat->last_seen_surface_callback = NULL;
@ -3322,6 +3334,8 @@ EnteredSurface (Seat *seat, Surface *surface, Time time,
seat->last_seen_surface = surface;
seat->last_seen_surface_callback
= XLSurfaceRunOnFree (surface, ClearLastSeenSurface, seat);
seat->last_surface_x = x;
seat->last_surface_y = y;
if (seat->flags & IsDragging)
DragEnter (seat, surface, x, y);
@ -3681,6 +3695,16 @@ HandleValuatorMotion (Seat *seat, Surface *dispatch, double x, double y,
return value;
}
static void
CheckPointerBarrier (Seat *seat, Surface *dispatch, double x, double y,
double root_x, double root_y)
{
/* Check if DISPATCH has a pointer confinement that would be
activated by this motion. */
XLPointerBarrierCheck (seat, dispatch, x, y, root_x, root_y);
}
static void
DispatchMotion (Subcompositor *subcompositor, XIDeviceEvent *xev)
{
@ -3774,7 +3798,19 @@ DispatchMotion (Subcompositor *subcompositor, XIDeviceEvent *xev)
if (seat->flags & IsDragging)
DragMotion (seat, dispatch, x, y, xev->time);
else
SendMotion (seat, dispatch, x, y, xev->time);
{
/* Send the motion event. */
SendMotion (seat, dispatch, x, y, xev->time);
/* Check if this motion would cause a pointer constraint to
activate. */
CheckPointerBarrier (seat, dispatch, x, y, xev->root_x,
xev->root_y);
}
/* Set the last movement location. */
seat->last_surface_x = x;
seat->last_surface_y = y;
}
/* These values are for tracking the output that a cursor is in. */
@ -5422,6 +5458,12 @@ XLSeatGetKeyboardDevice (Seat *seat)
return seat->master_keyboard;
}
int
XLSeatGetPointerDevice (Seat *seat)
{
return seat->master_pointer;
}
Seat *
XLSeatGetInputMethodSeat (void)
{
@ -5509,3 +5551,33 @@ XLSeatDispatchCoreKeyEvent (Seat *seat, Surface *surface, XEvent *event,
if (group != seat->effective_group || state != effective)
SendKeyboardModifiers (seat, surface);
}
Seat *
XLPointerGetSeat (Pointer *pointer)
{
return pointer->seat;
}
void
XLSeatGetMouseData (Seat *seat, Surface **last_seen_surface,
double *last_surface_x, double *last_surface_y,
double *its_root_x, double *its_root_y)
{
*last_seen_surface = seat->last_seen_surface;
*last_surface_x = seat->last_surface_x;
*last_surface_y = seat->last_surface_y;
*its_root_x = seat->its_root_x;
*its_root_y = seat->its_root_y;
}
void
XLSeatLockPointer (Seat *seat)
{
seat->flags |= IsPointerLocked;
}
void
XLSeatUnlockPointer (Seat *seat)
{
seat->flags &= ~IsPointerLocked;
}

12
shm.c
View file

@ -74,9 +74,6 @@ typedef struct _Buffer
int refcount;
} Buffer;
/* List of all resources for our shared memory global. */
static XLList *all_shms;
/* The shared memory global. */
static struct wl_global *global_shm;
@ -412,12 +409,6 @@ static const struct wl_shm_pool_interface wl_shm_pool_impl =
.create_buffer = CreateBuffer,
};
static void
HandleResourceDestroy (struct wl_resource *resource)
{
all_shms = XLListRemove (all_shms, resource);
}
static void
CreatePool (struct wl_client *client, struct wl_resource *resource,
uint32_t id, int32_t fd, int32_t size)
@ -533,8 +524,7 @@ HandleBind (struct wl_client *client, void *data,
}
wl_resource_set_implementation (resource, &wl_shm_impl,
NULL, HandleResourceDestroy);
all_shms = XLListPrepend (all_shms, resource);
NULL, NULL);
PostFormats (resource);
}

View file

@ -273,6 +273,9 @@ struct _View
attached. */
ExtBuffer *buffer;
/* Function called upon the view potentially being resized. */
void (*maybe_resized) (View *);
/* The damaged and opaque regions. */
pixman_region32_t damage, opaque;
@ -1262,7 +1265,8 @@ main (int argc, char **argv)
/* Notice that VIEW's size has changed, while VIEW itself has not
moved. Recompute the max_x, min_x, min_y, and max_y of its
subcompositor. */
subcompositor. In addition, run the view's resize function, if
any. */
static void
ViewAfterSizeUpdate (View *view)
@ -1270,6 +1274,9 @@ ViewAfterSizeUpdate (View *view)
int doflags;
Bool mapped;
if (view->maybe_resized)
view->maybe_resized (view);
if (!view->subcompositor || !ViewVisibilityState (view, &mapped)
|| !mapped || IsSkipped (view))
return;
@ -1332,7 +1339,7 @@ ViewAttachBuffer (View *view, ExtBuffer *buffer)
as well. */
SetGarbaged (view->subcompositor);
/* Recompute view bounds. */
/* Recompute view and subcompositor bounds. */
ViewAfterSizeUpdate (view);
}
}
@ -2991,6 +2998,12 @@ ViewSetData (View *view, void *data)
view->data = data;
}
void
ViewSetMaybeResizedFunction (View *view, void (*func) (View *))
{
view->maybe_resized = func;
}
void
ViewTranslate (View *view, int x, int y, int *x_out, int *y_out)
{

View file

@ -557,6 +557,9 @@ MoveFractional (Subsurface *subsurface)
purposes. */
subsurface->role.surface->input_delta_x = x - x_int;
subsurface->role.surface->input_delta_y = y - y_int;
/* Apply pointer constraints. */
XLPointerConstraintsSubsurfaceMoved (subsurface->role.surface);
}
static void

View file

@ -634,6 +634,10 @@ ApplyInputRegion (Surface *surface)
ViewSetInput (surface->view, &temp);
pixman_region32_fini (&temp);
}
/* The input region has changed, so pointer confinement must be
redone. */
XLPointerConstraintsReconfineSurface (surface);
}
static void
@ -828,6 +832,9 @@ HandleScaleChanged (void *data, int new_scale)
surface->role->funcs.end_subframe (surface, surface->role);
}
}
/* The scale has changed, so pointer confinement must be redone. */
XLPointerConstraintsReconfineSurface (surface);
}
static void
@ -1428,6 +1435,18 @@ HandleSurfaceDestroy (struct wl_resource *resource)
XLFree (surface);
}
static void
MaybeResized (View *view)
{
Surface *surface;
surface = ViewGetData (view);
/* The view may have been resized; recompute pointer confinement
area if necessary. */
XLPointerConstraintsReconfineSurface (surface);
}
void
XLCreateSurface (struct wl_client *client,
struct wl_resource *resource,
@ -1468,6 +1487,9 @@ XLCreateSurface (struct wl_client *client,
view. */
ViewSetData (surface->view, surface);
/* Make it so pointer confinement stuff can run after resize. */
ViewSetMaybeResizedFunction (surface->view, MaybeResized);
/* Initialize the sentinel node for the commit callback list. */
surface->commit_callbacks.last = &surface->commit_callbacks;
surface->commit_callbacks.next = &surface->commit_callbacks;
@ -1702,8 +1724,7 @@ Window
XLWindowFromSurface (Surface *surface)
{
if (!surface->role
|| !surface->role->funcs.get_window (surface,
surface->role))
|| !surface->role->funcs.get_window)
return None;
return surface->role->funcs.get_window (surface,

28
xdata.c
View file

@ -50,11 +50,11 @@ struct _ReadTargetsData
/* Array of atoms read from the selection. */
Atom *atoms;
/* Number of atoms read. */
int n_atoms;
/* What selection is being read from. */
Atom selection;
/* Number of atoms read. */
int n_atoms;
};
struct _TargetMapping
@ -145,11 +145,11 @@ struct _ConversionTransferInfo
/* And the amount of data used in the output buffer. */
size_t outsize;
/* The data format conversion context. */
iconv_t cd;
/* Any active file descriptor write callback. */
WriteFd *write_callback;
/* The data format conversion context. */
iconv_t cd;
};
enum
@ -201,17 +201,17 @@ struct _ConversionWriteInfo
struct _TargetMappingTable
{
/* Array of indices into direct_transfer. */
unsigned short *buckets[32];
/* Number of elements in each array. */
unsigned short n_elements[32];
/* Array of indices into direct_transfer. */
unsigned short *atom_buckets[16];
/* Number of elements in each array. */
/* Array of indices into direct_transfer. */
unsigned short *buckets[32];
/* Number of elements in each atom bucket. */
unsigned short n_atom_elements[16];
/* Number of elements in each bucket. */
unsigned short n_elements[32];
};
/* Base event code of the Xfixes extension. */
@ -2228,7 +2228,7 @@ XLInitXData (void)
rc = XFixesQueryVersion (compositor.display,
&major, &minor);
if (!rc || major < 1)
if (!rc || major < 5)
{
fprintf (stderr, "The X server does not support the "
"right version of the XFixes protocol extension\n");

View file

@ -90,11 +90,6 @@ struct _XdgRole
/* The role object. */
Role role;
/* Number of references to this role. Used when the client
terminates and the Wayland library destroys objects out of
order. */
int refcount;
/* The window backing this role. */
Window window;
@ -110,6 +105,11 @@ struct _XdgRole
/* The pending frame ID. */
uint64_t pending_frame;
/* Number of references to this role. Used when the client
terminates and the Wayland library destroys objects out of
order. */
int refcount;
/* Various role state. */
int state;
@ -126,6 +126,9 @@ struct _XdgRole
/* The current xdg_surface state. */
XdgState current_state;
/* List of callbacks run upon a ConfigureNotify event. */
ReconstrainCallback reconstrain_callbacks;
/* Configure event serial. */
uint32_t conf_serial, last_specified_serial;
@ -142,17 +145,14 @@ struct _XdgRole
events to wait for before ignoring those coordinates. */
int pending_synth_configure;
/* The type of the attached role. */
XdgRoleImplementationType type;
/* The input region of the attached subsurface. */
pixman_region32_t input_region;
/* List of callbacks run upon a ConfigureNotify event. */
ReconstrainCallback reconstrain_callbacks;
/* The number of desynchronous children of this toplevel. */
int n_desync_children;
/* The type of the attached role. */
XdgRoleImplementationType type;
};
struct _ReleaseLaterRecord
@ -537,15 +537,7 @@ AckConfigure (struct wl_client *client, struct wl_resource *resource,
fprintf (stderr, "ack_configure: %"PRIu32"\n", serial);
#endif
if (serial < xdg_role->conf_serial)
{
/* The client specified an outdated serial. */
wl_resource_post_error (resource, XDG_SURFACE_ERROR_INVALID_SERIAL,
"serial specified not monotonic");
return;
}
if (serial && serial == xdg_role->last_specified_serial)
if (serial && serial <= xdg_role->last_specified_serial)
{
/* The client specified the same serial twice. */
wl_resource_post_error (resource, XDG_SURFACE_ERROR_INVALID_SERIAL,
@ -1005,12 +997,19 @@ NoteConfigure (XdgRole *role, XEvent *event)
if (role->pending_synth_configure)
role->pending_synth_configure--;
/* Update the surface that the surface is inside. */
if (role->role.surface)
XLUpdateSurfaceOutputs (role->role.surface,
event->xconfigure.x + role->min_x,
event->xconfigure.y + role->min_y,
-1, -1);
{
/* Update the list of outputs that the surface is inside. */
XLUpdateSurfaceOutputs (role->role.surface,
event->xconfigure.x + role->min_x,
event->xconfigure.y + role->min_y,
-1, -1);
/* Update pointer constraints. */
XLPointerConstraintsSurfaceMovedTo (role->role.surface,
event->xconfigure.x,
event->xconfigure.y);
}
RunReconstrainCallbacksForXEvent (role, event);
}

View file

@ -134,26 +134,6 @@ struct _XdgToplevel
/* The wl_resource associated with this toplevel. */
struct wl_resource *resource;
/* The number of references to this toplevel. */
int refcount;
/* Some state associated with this toplevel. */
int state;
/* The serial of the last configure sent. */
uint32_t conf_serial;
/* Whether or not we are waiting for a reply to a configure
event. */
Bool conf_reply;
/* Array of states. */
struct wl_array states;
/* The current width and height of this toplevel as received in the
last ConfigureNotify event. */
int width, height;
/* The Motif window manager hints associated with this toplevel. */
PropMotifWmHints motif;
@ -163,22 +143,14 @@ struct _XdgToplevel
/* All resize callbacks currently posted. */
XLList *resize_callbacks;
/* Minimum size of this toplevel. */
int min_width, min_height;
/* Maximim size of this toplevel. */
int max_width, max_height;
/* Pending values. */
int pending_max_width, pending_max_height;
int pending_min_height, pending_min_width;
/* How much to move upon the next ack_configure. Used to resize a
window westwards or northwards. */
int ack_west, ack_north;
/* X Windows size hints. */
XSizeHints size_hints;
/* Timer for completing window state changes. The order of
_NET_WM_STATE changes and ConfigureNotify events is not
predictable, so we batch up both kinds of events with a 0.01
second delay by default, before sending the resulting
ConfigureNotify event. However, if drag-to-resize is in
progress, no such delay is effected. */
#define DefaultStateDelayNanoseconds 10000000
Timer *configuration_timer;
/* List of callbacks run upon unmapping. The callbacks are then
deleted. */
@ -190,6 +162,9 @@ struct _XdgToplevel
/* The unmap callback for the parent toplevel. */
XdgUnmapCallback *parent_callback;
/* Any decoration resource associated with this toplevel. */
XdgDecoration *decoration;
/* Various geometries before a given state change.
width00/height00 mean the size when the toplevel was neither
@ -210,6 +185,20 @@ struct _XdgToplevel
int width01, height01, width10, height10;
int width00, height00, width11, height11;
/* Minimum size of this toplevel. */
int min_width, min_height;
/* Maximim size of this toplevel. */
int max_width, max_height;
/* Pending values. */
int pending_max_width, pending_max_height;
int pending_min_height, pending_min_width;
/* How much to move upon the next ack_configure. Used to resize a
window westwards or northwards. */
int ack_west, ack_north;
/* The width, height, west and north motion of the next resize. */
int resize_width, resize_height, resize_west, resize_north;
@ -218,24 +207,35 @@ struct _XdgToplevel
_NET_WM_ALLOWED_ACTIONS. */
int supported;
/* Timer for completing window state changes. The order of
_NET_WM_STATE changes and ConfigureNotify events is not
predictable, so we batch up both kinds of events with a 0.01
second delay by default, before sending the resulting
ConfigureNotify event. However, if drag-to-resize is in
progress, no such delay is effected. */
#define DefaultStateDelayNanoseconds 10000000
Timer *configuration_timer;
/* The number of references to this toplevel. */
int refcount;
/* Some state associated with this toplevel. */
int state;
/* The serial of the last configure sent. */
uint32_t conf_serial;
/* Whether or not we are waiting for a reply to a configure
event. */
Bool conf_reply;
/* The current width and height of this toplevel as received in the
last ConfigureNotify event. */
int width, height;
/* The width and height used by that timer if
StatePendingConfigureSize is set. */
int configure_width, configure_height;
/* Any decoration resource associated with this toplevel. */
XdgDecoration *decoration;
/* Array of states. */
struct wl_array states;
/* The decoration mode. */
DecorationMode decor;
/* X Windows size hints. */
XSizeHints size_hints;
};
struct _XdgDecoration