Implement keyboard shortcut inhibition
* 12to11.c (XLMain): Initialize keyboard shortcut inhibition. * Imakefile (SRCS): Add keyboard_shortcuts_inhibit.c. (OBJS): Add keyboard_shortcuts_inhibit.o. * compositor.h (enum _ClientDataType): Add ShortcutInhibitData. (struct _ClientData): New structure. (struct _Surface): Make client data a linked list. * pointer_constraints.c (Reconfine, XLPointerBarrierLeft) (XLPointerBarrierCheck, XLPointerConstraintsSurfaceMovedTo): Adjust to new client data storage approach. * seat.c (struct _Seat): New fields `last_focus_time' and `external_grab_time'. (HandleBind, SelectDeviceEvents, SetFocusSurface): Use size_t to represent mask length. (DispatchFocusIn): Set last focus time. (FakePointerEdge, XLSelectStandardEvents): Likewise; use size_t. (XLSeatExplicitlyGrabSurface): Clear active grab. (XLSeatBeginDrag): Use size_t to represent XI mask length. (XLSeatApplyExternalGrab, XLSeatCancelExternalGrab): New functions. * subsurface.c (Teardown, XLSubsurfaceHandleParentCommit): Adjust client data storage. * surface.c (HandleSurfaceDestroy, XLSurfaceGetClientData): Adjust client data storage to use a linked list. (XLSurfaceFindClientData): New function. * text_input.c (FilterInputCallback): Pacify cppcheck.
This commit is contained in:
parent
f683d8c30f
commit
17571b6f97
8 changed files with 196 additions and 57 deletions
1
12to11.c
1
12to11.c
|
@ -236,6 +236,7 @@ XLMain (int argc, char **argv)
|
||||||
XLInitDrmLease ();
|
XLInitDrmLease ();
|
||||||
XLInitPointerConstraints ();
|
XLInitPointerConstraints ();
|
||||||
XLInitRelativePointer ();
|
XLInitRelativePointer ();
|
||||||
|
XLInitKeyboardShortcutsInhibit ();
|
||||||
|
|
||||||
/* This has to come after the rest of the initialization. */
|
/* This has to come after the rest of the initialization. */
|
||||||
DetermineServerTime ();
|
DetermineServerTime ();
|
||||||
|
|
|
@ -24,7 +24,7 @@ SRCS = 12to11.c run.c alloc.c fns.c output.c compositor.c \
|
||||||
picture_renderer.c explicit_synchronization.c transform.c \
|
picture_renderer.c explicit_synchronization.c transform.c \
|
||||||
wp_viewporter.c decoration.c text_input.c \
|
wp_viewporter.c decoration.c text_input.c \
|
||||||
single_pixel_buffer.c drm_lease.c pointer_constraints.c \
|
single_pixel_buffer.c drm_lease.c pointer_constraints.c \
|
||||||
time.c relative_pointer.c
|
time.c relative_pointer.c keyboard_shortcuts_inhibit.c
|
||||||
|
|
||||||
OBJS = 12to11.o run.o alloc.o fns.o output.o compositor.o \
|
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 \
|
surface.o region.o shm.o atoms.o subcompositor.o positioner.o \
|
||||||
|
@ -35,7 +35,7 @@ OBJS = 12to11.o run.o alloc.o fns.o output.o compositor.o \
|
||||||
picture_renderer.o explicit_synchronization.o transform.o \
|
picture_renderer.o explicit_synchronization.o transform.o \
|
||||||
wp_viewporter.o decoration.o text_input.o \
|
wp_viewporter.o decoration.o text_input.o \
|
||||||
single_pixel_buffer.o drm_lease.o pointer_constraints.o \
|
single_pixel_buffer.o drm_lease.o pointer_constraints.o \
|
||||||
time.o relative_pointer.o
|
time.o relative_pointer.o keyboard_shortcuts_inhibit.o
|
||||||
|
|
||||||
GENHEADERS = transfer_atoms.h
|
GENHEADERS = transfer_atoms.h
|
||||||
|
|
||||||
|
@ -121,6 +121,7 @@ ScannerTarget(single-pixel-buffer-v1)
|
||||||
ScannerTarget(drm-lease-v1)
|
ScannerTarget(drm-lease-v1)
|
||||||
ScannerTarget(pointer-constraints-unstable-v1)
|
ScannerTarget(pointer-constraints-unstable-v1)
|
||||||
ScannerTarget(relative-pointer-unstable-v1)
|
ScannerTarget(relative-pointer-unstable-v1)
|
||||||
|
ScannerTarget(keyboard-shortcuts-inhibit-unstable-v1)
|
||||||
|
|
||||||
/* Make OBJS depend on scanner headers, and depend on both them and SRCS. */
|
/* Make OBJS depend on scanner headers, and depend on both them and SRCS. */
|
||||||
$(OBJS): $(GENHEADERS)
|
$(OBJS): $(GENHEADERS)
|
||||||
|
|
33
compositor.h
33
compositor.h
|
@ -892,11 +892,13 @@ typedef struct _RoleFuncs RoleFuncs;
|
||||||
typedef struct _CommitCallback CommitCallback;
|
typedef struct _CommitCallback CommitCallback;
|
||||||
typedef struct _UnmapCallback UnmapCallback;
|
typedef struct _UnmapCallback UnmapCallback;
|
||||||
typedef struct _DestroyCallback DestroyCallback;
|
typedef struct _DestroyCallback DestroyCallback;
|
||||||
|
typedef struct _ClientData ClientData;
|
||||||
|
|
||||||
enum _ClientDataType
|
enum _ClientDataType
|
||||||
{
|
{
|
||||||
SubsurfaceData,
|
SubsurfaceData,
|
||||||
PointerConfinementData,
|
PointerConfinementData,
|
||||||
|
ShortcutInhibitData,
|
||||||
MaxClientData,
|
MaxClientData,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -937,6 +939,21 @@ struct _CommitCallback
|
||||||
CommitCallback *next, *last;
|
CommitCallback *next, *last;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct _ClientData
|
||||||
|
{
|
||||||
|
/* The next piece of client data attached to this surface. */
|
||||||
|
ClientData *next;
|
||||||
|
|
||||||
|
/* The client data itself. */
|
||||||
|
void *data;
|
||||||
|
|
||||||
|
/* The free function. */
|
||||||
|
void (*free_function) (void *);
|
||||||
|
|
||||||
|
/* The type of the client data. */
|
||||||
|
ClientDataType type;
|
||||||
|
};
|
||||||
|
|
||||||
struct _Surface
|
struct _Surface
|
||||||
{
|
{
|
||||||
/* The view associated with this surface. */
|
/* The view associated with this surface. */
|
||||||
|
@ -968,11 +985,8 @@ struct _Surface
|
||||||
/* List of subsurfaces. */
|
/* List of subsurfaces. */
|
||||||
XLList *subsurfaces;
|
XLList *subsurfaces;
|
||||||
|
|
||||||
/* Array of "client data". */
|
/* List of client data. */
|
||||||
void *client_data[MaxClientData];
|
ClientData *client_data;
|
||||||
|
|
||||||
/* List of functions for freeing "client data". */
|
|
||||||
void (*free_client_data[MaxClientData]) (void *);
|
|
||||||
|
|
||||||
/* List of commit callbacks. */
|
/* List of commit callbacks. */
|
||||||
CommitCallback commit_callbacks;
|
CommitCallback commit_callbacks;
|
||||||
|
@ -1087,6 +1101,7 @@ extern DestroyCallback *XLSurfaceRunOnFree (Surface *, void (*) (void *),
|
||||||
extern void XLSurfaceCancelRunOnFree (DestroyCallback *);
|
extern void XLSurfaceCancelRunOnFree (DestroyCallback *);
|
||||||
extern void *XLSurfaceGetClientData (Surface *, ClientDataType,
|
extern void *XLSurfaceGetClientData (Surface *, ClientDataType,
|
||||||
size_t, void (*) (void *));
|
size_t, void (*) (void *));
|
||||||
|
extern void *XLSurfaceFindClientData (Surface *, ClientDataType);
|
||||||
extern Bool XLSurfaceGetResizeDimensions (Surface *, int *, int *);
|
extern Bool XLSurfaceGetResizeDimensions (Surface *, int *, int *);
|
||||||
extern void XLSurfacePostResize (Surface *, int, int, int, int);
|
extern void XLSurfacePostResize (Surface *, int, int, int, int);
|
||||||
extern void XLSurfaceMoveBy (Surface *, int, int);
|
extern void XLSurfaceMoveBy (Surface *, int, int);
|
||||||
|
@ -1450,6 +1465,8 @@ extern void XLSeatLockPointer (Seat *);
|
||||||
extern void XLSeatUnlockPointer (Seat *);
|
extern void XLSeatUnlockPointer (Seat *);
|
||||||
extern RelativePointer *XLSeatGetRelativePointer (Seat *, struct wl_resource *);
|
extern RelativePointer *XLSeatGetRelativePointer (Seat *, struct wl_resource *);
|
||||||
extern void XLSeatDestroyRelativePointer (RelativePointer *);
|
extern void XLSeatDestroyRelativePointer (RelativePointer *);
|
||||||
|
extern Bool XLSeatApplyExternalGrab (Seat *, Surface *);
|
||||||
|
extern void XLSeatCancelExternalGrab (Seat *);
|
||||||
|
|
||||||
extern Cursor InitDefaultCursor (void);
|
extern Cursor InitDefaultCursor (void);
|
||||||
|
|
||||||
|
@ -1623,6 +1640,12 @@ extern void XLInitRelativePointer (void);
|
||||||
extern void XLRelativePointerSendRelativeMotion (struct wl_resource *,
|
extern void XLRelativePointerSendRelativeMotion (struct wl_resource *,
|
||||||
uint64_t, double, double);
|
uint64_t, double, double);
|
||||||
|
|
||||||
|
/* Defined in keyboard_shortcuts_inhibit.c. */
|
||||||
|
|
||||||
|
extern void XLInitKeyboardShortcutsInhibit (void);
|
||||||
|
extern void XLCheckShortcutInhibition (Seat *, Surface *);
|
||||||
|
extern void XLReleaseShortcutInhibition (Seat *, Surface *);
|
||||||
|
|
||||||
/* Utility functions that don't belong in a specific file. */
|
/* Utility functions that don't belong in a specific file. */
|
||||||
|
|
||||||
#define ArrayElements(arr) (sizeof (arr) / sizeof (arr)[0])
|
#define ArrayElements(arr) (sizeof (arr) / sizeof (arr)[0])
|
||||||
|
|
|
@ -1776,7 +1776,7 @@ Reconfine (Surface *surface, int *root_x, int *root_y,
|
||||||
if (!XLWindowFromSurface (surface))
|
if (!XLWindowFromSurface (surface))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
record = surface->client_data[PointerConfinementData];
|
record = XLSurfaceFindClientData (surface, PointerConfinementData);
|
||||||
|
|
||||||
if (!record)
|
if (!record)
|
||||||
return;
|
return;
|
||||||
|
@ -1813,7 +1813,7 @@ XLPointerBarrierLeft (Seat *seat, Surface *surface)
|
||||||
/* The pointer has now left the given surface. If there is an
|
/* The pointer has now left the given surface. If there is an
|
||||||
active confinement for that surface and seat, disable it. */
|
active confinement for that surface and seat, disable it. */
|
||||||
|
|
||||||
record = surface->client_data[PointerConfinementData];
|
record = XLSurfaceFindClientData (surface, PointerConfinementData);
|
||||||
|
|
||||||
if (!record)
|
if (!record)
|
||||||
return;
|
return;
|
||||||
|
@ -1834,7 +1834,7 @@ XLPointerBarrierCheck (Seat *seat, Surface *dispatch, double x, double y,
|
||||||
pixman_box32_t box;
|
pixman_box32_t box;
|
||||||
int offset_x, offset_y;
|
int offset_x, offset_y;
|
||||||
|
|
||||||
record = dispatch->client_data[PointerConfinementData];
|
record = XLSurfaceFindClientData (dispatch, PointerConfinementData);
|
||||||
|
|
||||||
if (!record)
|
if (!record)
|
||||||
return;
|
return;
|
||||||
|
@ -1959,7 +1959,7 @@ XLPointerConstraintsSurfaceMovedTo (Surface *surface, int root_x,
|
||||||
query for the position manually. Simply move the lines for the
|
query for the position manually. Simply move the lines for the
|
||||||
surface's window and each of its subsurfaces. */
|
surface's window and each of its subsurfaces. */
|
||||||
|
|
||||||
record = surface->client_data[PointerConfinementData];
|
record = XLSurfaceFindClientData (surface, PointerConfinementData);
|
||||||
|
|
||||||
if (!record)
|
if (!record)
|
||||||
return;
|
return;
|
||||||
|
|
94
seat.c
94
seat.c
|
@ -89,6 +89,7 @@ enum
|
||||||
IsTextInputSeat = (1 << 5),
|
IsTextInputSeat = (1 << 5),
|
||||||
IsPointerLocked = (1 << 6),
|
IsPointerLocked = (1 << 6),
|
||||||
IsSurfaceCoordSet = (1 << 7),
|
IsSurfaceCoordSet = (1 << 7),
|
||||||
|
IsExternalGrabApplied = (1 << 8),
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
|
@ -362,6 +363,12 @@ struct _Seat
|
||||||
/* The last user time. */
|
/* The last user time. */
|
||||||
Timestamp last_user_time;
|
Timestamp last_user_time;
|
||||||
|
|
||||||
|
/* The last time the focus changed into a surface. */
|
||||||
|
Timestamp last_focus_time;
|
||||||
|
|
||||||
|
/* When the last external grab was applied. */
|
||||||
|
Time external_grab_time;
|
||||||
|
|
||||||
/* wl_global associated with this seat. */
|
/* wl_global associated with this seat. */
|
||||||
struct wl_global *global;
|
struct wl_global *global;
|
||||||
|
|
||||||
|
@ -1749,7 +1756,7 @@ HandleBind (struct wl_client *client, void *data,
|
||||||
{
|
{
|
||||||
struct wl_resource *resource;
|
struct wl_resource *resource;
|
||||||
char *name;
|
char *name;
|
||||||
ptrdiff_t length;
|
size_t length;
|
||||||
Seat *seat;
|
Seat *seat;
|
||||||
|
|
||||||
seat = data;
|
seat = data;
|
||||||
|
@ -2665,7 +2672,7 @@ static void
|
||||||
SelectDeviceEvents (void)
|
SelectDeviceEvents (void)
|
||||||
{
|
{
|
||||||
XIEventMask mask;
|
XIEventMask mask;
|
||||||
ptrdiff_t length;
|
size_t length;
|
||||||
|
|
||||||
length = XIMaskLen (XI_LASTEVENT);
|
length = XIMaskLen (XI_LASTEVENT);
|
||||||
mask.mask = alloca (length);
|
mask.mask = alloca (length);
|
||||||
|
@ -2864,6 +2871,10 @@ SetFocusSurface (Seat *seat, Surface *focus)
|
||||||
{
|
{
|
||||||
SendKeyboardLeave (seat, seat->focus_surface);
|
SendKeyboardLeave (seat, seat->focus_surface);
|
||||||
|
|
||||||
|
/* Cancel any grab that may be associated with shortcut
|
||||||
|
inhibition. */
|
||||||
|
XLReleaseShortcutInhibition (seat, seat->focus_surface);
|
||||||
|
|
||||||
XLSurfaceCancelRunOnFree (seat->focus_destroy_callback);
|
XLSurfaceCancelRunOnFree (seat->focus_destroy_callback);
|
||||||
seat->focus_destroy_callback = NULL;
|
seat->focus_destroy_callback = NULL;
|
||||||
seat->focus_surface = NULL;
|
seat->focus_surface = NULL;
|
||||||
|
@ -2881,6 +2892,9 @@ SetFocusSurface (Seat *seat, Surface *focus)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Apply any shortcut inhibition. */
|
||||||
|
XLCheckShortcutInhibition (seat, focus);
|
||||||
|
|
||||||
if (input_funcs)
|
if (input_funcs)
|
||||||
/* Tell any input method about the change. */
|
/* Tell any input method about the change. */
|
||||||
input_funcs->focus_in (seat, focus);
|
input_funcs->focus_in (seat, focus);
|
||||||
|
@ -2907,6 +2921,9 @@ DispatchFocusIn (Surface *surface, XIFocusInEvent *event)
|
||||||
if (!seat)
|
if (!seat)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/* Record the time the focus changed for the external grab. */
|
||||||
|
seat->last_focus_time = TimestampFromServerTime (event->time);
|
||||||
|
|
||||||
SetFocusSurface (seat, surface);
|
SetFocusSurface (seat, surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4553,7 +4570,7 @@ FakePointerEdge (Seat *seat, Surface *target, uint32_t serial,
|
||||||
Status state;
|
Status state;
|
||||||
Window window;
|
Window window;
|
||||||
XIEventMask mask;
|
XIEventMask mask;
|
||||||
ptrdiff_t length;
|
size_t length;
|
||||||
|
|
||||||
if (edge == NoneEdge)
|
if (edge == NoneEdge)
|
||||||
return False;
|
return False;
|
||||||
|
@ -4751,7 +4768,7 @@ void
|
||||||
XLSelectStandardEvents (Window window)
|
XLSelectStandardEvents (Window window)
|
||||||
{
|
{
|
||||||
XIEventMask mask;
|
XIEventMask mask;
|
||||||
ptrdiff_t length;
|
size_t length;
|
||||||
|
|
||||||
length = XIMaskLen (XI_LASTEVENT);
|
length = XIMaskLen (XI_LASTEVENT);
|
||||||
mask.mask = alloca (length);
|
mask.mask = alloca (length);
|
||||||
|
@ -4965,7 +4982,7 @@ XLSeatExplicitlyGrabSurface (Seat *seat, Surface *surface, uint32_t serial)
|
||||||
WhatEdge edge;
|
WhatEdge edge;
|
||||||
Time time;
|
Time time;
|
||||||
XIEventMask mask;
|
XIEventMask mask;
|
||||||
ptrdiff_t length;
|
size_t length;
|
||||||
Cursor cursor;
|
Cursor cursor;
|
||||||
|
|
||||||
if (seat->flags & IsInert
|
if (seat->flags & IsInert
|
||||||
|
@ -5017,6 +5034,8 @@ XLSeatExplicitlyGrabSurface (Seat *seat, Surface *surface, uint32_t serial)
|
||||||
XISetMask (mask.mask, XI_Motion);
|
XISetMask (mask.mask, XI_Motion);
|
||||||
XISetMask (mask.mask, XI_ButtonPress);
|
XISetMask (mask.mask, XI_ButtonPress);
|
||||||
XISetMask (mask.mask, XI_ButtonRelease);
|
XISetMask (mask.mask, XI_ButtonRelease);
|
||||||
|
XISetMask (mask.mask, XI_KeyPress);
|
||||||
|
XISetMask (mask.mask, XI_KeyRelease);
|
||||||
|
|
||||||
cursor = (seat->cursor ? seat->cursor->cursor : None);
|
cursor = (seat->cursor ? seat->cursor->cursor : None);
|
||||||
|
|
||||||
|
@ -5036,10 +5055,15 @@ XLSeatExplicitlyGrabSurface (Seat *seat, Surface *surface, uint32_t serial)
|
||||||
that keyboard focus cannot be changed, which is not very crucial,
|
that keyboard focus cannot be changed, which is not very crucial,
|
||||||
so it is allowed to fail. */
|
so it is allowed to fail. */
|
||||||
|
|
||||||
XIGrabDevice (compositor.display, seat->master_keyboard,
|
state = XIGrabDevice (compositor.display, seat->master_keyboard,
|
||||||
window, time, None, XIGrabModeAsync,
|
window, time, None, XIGrabModeAsync,
|
||||||
XIGrabModeAsync, True, &mask);
|
XIGrabModeAsync, True, &mask);
|
||||||
|
|
||||||
|
/* Cancel any external grab that might be applied if the keyboard
|
||||||
|
grab succeeded. */
|
||||||
|
if (state == Success)
|
||||||
|
seat->flags &= ~IsExternalGrabApplied;
|
||||||
|
|
||||||
/* And record the grab surface, so that owner_events can be
|
/* And record the grab surface, so that owner_events can be
|
||||||
implemented correctly. */
|
implemented correctly. */
|
||||||
SwapGrabSurface (seat, surface);
|
SwapGrabSurface (seat, surface);
|
||||||
|
@ -5332,7 +5356,7 @@ XLSeatBeginDrag (Seat *seat, DataSource *data_source, Surface *start_surface,
|
||||||
Window window;
|
Window window;
|
||||||
Time time;
|
Time time;
|
||||||
XIEventMask mask;
|
XIEventMask mask;
|
||||||
ptrdiff_t length;
|
size_t length;
|
||||||
WhatEdge edge;
|
WhatEdge edge;
|
||||||
Status state;
|
Status state;
|
||||||
|
|
||||||
|
@ -5737,3 +5761,59 @@ XLSeatDestroyRelativePointer (RelativePointer *relative_pointer)
|
||||||
|
|
||||||
XLFree (relative_pointer);
|
XLFree (relative_pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Bool
|
||||||
|
XLSeatApplyExternalGrab (Seat *seat, Surface *surface)
|
||||||
|
{
|
||||||
|
Window window;
|
||||||
|
Status state;
|
||||||
|
XIEventMask mask;
|
||||||
|
size_t length;
|
||||||
|
|
||||||
|
/* Grab the toplevel SURFACE on SEAT. */
|
||||||
|
|
||||||
|
window = XLWindowFromSurface (surface);
|
||||||
|
|
||||||
|
if (!window)
|
||||||
|
return None;
|
||||||
|
|
||||||
|
length = XIMaskLen (XI_LASTEVENT);
|
||||||
|
mask.mask = alloca (length);
|
||||||
|
mask.mask_len = length;
|
||||||
|
mask.deviceid = XIAllMasterDevices;
|
||||||
|
|
||||||
|
memset (mask.mask, 0, length);
|
||||||
|
|
||||||
|
/* Grab focus and key events. */
|
||||||
|
XISetMask (mask.mask, XI_FocusIn);
|
||||||
|
XISetMask (mask.mask, XI_FocusOut);
|
||||||
|
XISetMask (mask.mask, XI_KeyPress);
|
||||||
|
XISetMask (mask.mask, XI_KeyRelease);
|
||||||
|
|
||||||
|
state = XIGrabDevice (compositor.display, seat->master_keyboard,
|
||||||
|
window, seat->last_focus_time.milliseconds, None,
|
||||||
|
XIGrabModeAsync, XIGrabModeAsync, True, &mask);
|
||||||
|
if (state == Success)
|
||||||
|
{
|
||||||
|
/* Mark an external grab as having been applied. */
|
||||||
|
seat->flags |= IsExternalGrabApplied;
|
||||||
|
|
||||||
|
/* Record the time when it was applied. */
|
||||||
|
seat->external_grab_time = seat->last_focus_time.milliseconds;
|
||||||
|
|
||||||
|
return True;
|
||||||
|
}
|
||||||
|
|
||||||
|
return False;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
XLSeatCancelExternalGrab (Seat *seat)
|
||||||
|
{
|
||||||
|
if (!(seat->flags & IsExternalGrabApplied))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Cancel the external grab. */
|
||||||
|
XIUngrabDevice (compositor.display, seat->master_keyboard,
|
||||||
|
seat->external_grab_time);
|
||||||
|
}
|
||||||
|
|
|
@ -792,7 +792,8 @@ Teardown (Surface *surface, Role *role)
|
||||||
ViewUnparent (surface->under);
|
ViewUnparent (surface->under);
|
||||||
ViewSetSubcompositor (surface->under, NULL);
|
ViewSetSubcompositor (surface->under, NULL);
|
||||||
|
|
||||||
client = subsurface->parent->client_data[SubsurfaceData];
|
client = XLSurfaceFindClientData (subsurface->parent,
|
||||||
|
SubsurfaceData);
|
||||||
|
|
||||||
if (client)
|
if (client)
|
||||||
{
|
{
|
||||||
|
@ -986,7 +987,7 @@ XLSubsurfaceHandleParentCommit (Surface *parent)
|
||||||
{
|
{
|
||||||
SurfaceActionClientData *client;
|
SurfaceActionClientData *client;
|
||||||
|
|
||||||
client = parent->client_data[SubsurfaceData];
|
client = XLSurfaceFindClientData (parent, SubsurfaceData);
|
||||||
|
|
||||||
if (client)
|
if (client)
|
||||||
RunSurfaceActions (&client->actions);
|
RunSurfaceActions (&client->actions);
|
||||||
|
|
54
surface.c
54
surface.c
|
@ -1305,7 +1305,7 @@ static void
|
||||||
HandleSurfaceDestroy (struct wl_resource *resource)
|
HandleSurfaceDestroy (struct wl_resource *resource)
|
||||||
{
|
{
|
||||||
Surface *surface;
|
Surface *surface;
|
||||||
int i;
|
ClientData *data, *last;
|
||||||
|
|
||||||
surface = wl_resource_get_user_data (resource);
|
surface = wl_resource_get_user_data (resource);
|
||||||
|
|
||||||
|
@ -1322,13 +1322,18 @@ HandleSurfaceDestroy (struct wl_resource *resource)
|
||||||
NotifySubsurfaceDestroyed);
|
NotifySubsurfaceDestroyed);
|
||||||
|
|
||||||
/* Then release all client data. */
|
/* Then release all client data. */
|
||||||
for (i = 0; i < MaxClientData; ++i)
|
data = surface->client_data;
|
||||||
{
|
|
||||||
if (surface->client_data[i])
|
|
||||||
surface->free_client_data[i] (surface->client_data[i]);
|
|
||||||
XLFree (surface->client_data[i]);
|
|
||||||
|
|
||||||
surface->client_data[i] = NULL;
|
while (data)
|
||||||
|
{
|
||||||
|
/* Free the client data. */
|
||||||
|
data->free_function (data->data);
|
||||||
|
XLFree (data->data);
|
||||||
|
|
||||||
|
/* And its record. */
|
||||||
|
last = data;
|
||||||
|
data = data->next;
|
||||||
|
XLFree (last);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Release the output region. */
|
/* Release the output region. */
|
||||||
|
@ -1641,13 +1646,38 @@ void *
|
||||||
XLSurfaceGetClientData (Surface *surface, ClientDataType type,
|
XLSurfaceGetClientData (Surface *surface, ClientDataType type,
|
||||||
size_t size, void (*free_func) (void *))
|
size_t size, void (*free_func) (void *))
|
||||||
{
|
{
|
||||||
if (surface->client_data[type])
|
ClientData *data;
|
||||||
return surface->client_data[type];
|
|
||||||
|
|
||||||
surface->client_data[type] = XLCalloc (1, size);
|
/* First, look for existing client data. */
|
||||||
surface->free_client_data[type] = free_func;
|
for (data = surface->client_data; data; data = data->next)
|
||||||
|
{
|
||||||
|
if (data->type == type)
|
||||||
|
return data->data;
|
||||||
|
}
|
||||||
|
|
||||||
return surface->client_data[type];
|
/* Next, allocate some new client data. */
|
||||||
|
data = XLMalloc (sizeof *data);
|
||||||
|
data->next = surface->client_data;
|
||||||
|
surface->client_data = data;
|
||||||
|
data->data = XLCalloc (1, size);
|
||||||
|
data->free_function = free_func;
|
||||||
|
data->type = type;
|
||||||
|
|
||||||
|
return data->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
XLSurfaceFindClientData (Surface *surface, ClientDataType type)
|
||||||
|
{
|
||||||
|
ClientData *data;
|
||||||
|
|
||||||
|
for (data = surface->client_data; data; data = data->next)
|
||||||
|
{
|
||||||
|
if (data->type == type)
|
||||||
|
return data->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Window
|
Window
|
||||||
|
|
17
text_input.c
17
text_input.c
|
@ -3217,27 +3217,30 @@ FilterInputCallback (Seat *seat, Surface *surface, void *event,
|
||||||
|
|
||||||
/* Find the enabled text input. */
|
/* Find the enabled text input. */
|
||||||
if (info)
|
if (info)
|
||||||
|
{
|
||||||
input = FindEnabledTextInput (info);
|
input = FindEnabledTextInput (info);
|
||||||
|
|
||||||
/* If there is an enabled text input, start filtering the event. */
|
/* If there is an enabled text input, start filtering the
|
||||||
if (info && input && input->xic)
|
event. */
|
||||||
|
if (input && input->xic)
|
||||||
{
|
{
|
||||||
DebugPrint ("found enabled text input %p on client-seat info %p",
|
DebugPrint ("found enabled text input %p on client-seat info %p",
|
||||||
input, info);
|
input, info);
|
||||||
|
|
||||||
/* Convert the extension event into a fake core event that the
|
/* Convert the extension event into a fake core event that
|
||||||
input method can understand. */
|
the input method can understand. */
|
||||||
ConvertKeyEvent (xev, &xkey);
|
ConvertKeyEvent (xev, &xkey);
|
||||||
|
|
||||||
/* And return the result of filtering the event. */
|
/* And return the result of filtering the event. */
|
||||||
if (XFilterEvent (&xkey, XLWindowFromSurface (surface)))
|
if (XFilterEvent (&xkey, XLWindowFromSurface (surface)))
|
||||||
return True;
|
return True;
|
||||||
|
|
||||||
/* Otherwise, call XmbLookupString. If a keysym is returned,
|
/* Otherwise, call XmbLookupString. If a keysym is
|
||||||
return False. Otherwise, commit the string looked up and
|
returned, return False. Otherwise, commit the string
|
||||||
return True. */
|
looked up and return True. */
|
||||||
return LookupString (input, &xkey, keysym);
|
return LookupString (input, &xkey, keysym);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Otherwise, do nothing. */
|
/* Otherwise, do nothing. */
|
||||||
return False;
|
return False;
|
||||||
|
|
Loading…
Add table
Reference in a new issue