Implement xdg-activation-v1

* 12to11-test.xml (test_surface): <activated>: New event.
* 12to11.c (XLMain): Initialize XDG activation.
* Imakefile (SRCS, OBJS): Add xdg_activation.c and
xdg_activation.o.
(xdg-activation-v1): New scanner target.
* atoms.c (names, XLInitAtoms): New atom `_NET_ACTIVE_WINDOW'.
Adjust accordingly.
* compositor.h (struct _RoleFuncs): New function `activate'.
(struct _XdgRoleImplementationFuncs): Likewise.
* seat.c (XLSeatCheckActivationSerial): New function.
* test.c (Activate): New function.
(GetTestSurface): Attach new hook.
* tests/Imakefile (OBJS13, SRCS13): Add xdg_activation_test.c/o.
(xdg-activation-v1): New scanner target.
(PROGRAMS): Add xdg_activation_test.
(xdg_activation_test): New program target.
* tests/run_tests.sh (standard_tests): Add xdg_activation_test.
* tests/svnignore.txt: Add xdg_activation_test.
* xdg_surface.c (Activate): New function.
(XLGetXdgSurface): Attach hook.
* xdg_toplevel.c (Activate): New function.
(XLGetXdgToplevel): Attach hook.
This commit is contained in:
hujianwei 2022-11-14 06:05:23 +00:00
parent 556cf6dbcc
commit 2979979633
12 changed files with 127 additions and 6 deletions

View file

@ -159,6 +159,17 @@
<arg name="xid" type="uint"/>
<arg name="display_string" type="string"/>
</event>
<event name="activated">
<description summary="role activated">
The activated is sent when the xdg_activation protocol causes
the surface associated with the role to be activated. Its
parameters constitute the timestamp at which the activation
occurred.
</description>
<arg name="months" type="uint"/>
<arg name="milliseconds" type="uint"/>
</event>
</interface>
<interface name="test_scale_lock" version="1">

View file

@ -248,6 +248,7 @@ XLMain (int argc, char **argv)
XLInitKeyboardShortcutsInhibit ();
XLInitIdleInhibit ();
XLInitPointerGestures ();
XLInitXdgActivation ();
XLInitTest ();
/* This has to come after the rest of the initialization. */

View file

@ -18,8 +18,8 @@ MakeSubdirs($(SUBDIRS))
DependSubdirs($(SUBDIRS))
#endif
SRCS = 12to11.c run.c alloc.c fns.c output.c compositor.c surface.c region.c shm.c atoms.c subcompositor.c positioner.c xdg_wm.c xdg_surface.c xdg_toplevel.c frame_clock.c xerror.c ewmh.c timer.c subsurface.c seat.c data_device.c xdg_popup.c dmabuf.c buffer.c select.c xdata.c xsettings.c dnd.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 pointer_constraints.c time.c relative_pointer.c keyboard_shortcuts_inhibit.c idle_inhibit.c process.c fence_ring.c pointer_gestures.c test.c buffer_release.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 xdg_wm.o xdg_surface.o xdg_toplevel.o frame_clock.o xerror.o ewmh.o timer.o subsurface.o seat.o data_device.o xdg_popup.o dmabuf.o buffer.o select.o xdata.o xsettings.o dnd.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 pointer_constraints.o time.o relative_pointer.o keyboard_shortcuts_inhibit.o idle_inhibit.o process.o fence_ring.o pointer_gestures.o test.o buffer_release.o
SRCS = 12to11.c run.c alloc.c fns.c output.c compositor.c surface.c region.c shm.c atoms.c subcompositor.c positioner.c xdg_wm.c xdg_surface.c xdg_toplevel.c frame_clock.c xerror.c ewmh.c timer.c subsurface.c seat.c data_device.c xdg_popup.c dmabuf.c buffer.c select.c xdata.c xsettings.c dnd.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 pointer_constraints.c time.c relative_pointer.c keyboard_shortcuts_inhibit.c idle_inhibit.c process.c fence_ring.c pointer_gestures.c test.c buffer_release.c xdg_activation.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 xdg_wm.o xdg_surface.o xdg_toplevel.o frame_clock.o xerror.o ewmh.o timer.o subsurface.o seat.o data_device.o xdg_popup.o dmabuf.o buffer.o select.o xdata.o xsettings.o dnd.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 pointer_constraints.o time.o relative_pointer.o keyboard_shortcuts_inhibit.o idle_inhibit.o process.o fence_ring.o pointer_gestures.o test.o buffer_release.o xdg_activation.o
GENHEADERS = transfer_atoms.h drm_modifiers.h
HEADER = $(GENHEADERS) compositor.h
@ -105,6 +105,7 @@ ScannerTarget(keyboard-shortcuts-inhibit-unstable-v1)
ScannerTarget(idle-inhibit-unstable-v1)
ScannerTarget(pointer-gestures-unstable-v1)
ScannerTarget(12to11-test)
ScannerTarget(xdg-activation-v1)
/* Make seat.o depend on test_seat.c, as it includes that. Both files
are rather special. */

View file

@ -112,6 +112,7 @@ static const char *names[] =
"_NET_WM_PID",
"_NET_WM_PING",
"libinput Scrolling Pixel Distance",
"_NET_ACTIVE_WINDOW",
/* These are automatically generated from mime.txt. */
DirectTransferAtomNames
@ -134,7 +135,8 @@ Atom _NET_WM_OPAQUE_REGION, _XL_BUFFER_RELEASE, _NET_WM_SYNC_REQUEST_COUNTER,
XdndEnter, XdndPosition, XdndStatus, XdndLeave, XdndDrop, XdndFinished,
_NET_WM_FRAME_TIMINGS, _NET_WM_BYPASS_COMPOSITOR, WM_STATE,
_NET_WM_WINDOW_TYPE, _NET_WM_WINDOW_TYPE_MENU, _NET_WM_WINDOW_TYPE_DND,
CONNECTOR_ID, _NET_WM_PID, _NET_WM_PING, libinput_Scrolling_Pixel_Distance;
CONNECTOR_ID, _NET_WM_PID, _NET_WM_PING, libinput_Scrolling_Pixel_Distance,
_NET_ACTIVE_WINDOW;
XrmQuark resource_quark, app_quark, QString;
@ -292,9 +294,10 @@ XLInitAtoms (void)
_NET_WM_PID = atoms[62];
_NET_WM_PING = atoms[63];
libinput_Scrolling_Pixel_Distance = atoms[64];
_NET_ACTIVE_WINDOW = atoms[65];
/* This is automatically generated. */
DirectTransferAtomInit (atoms, 65);
DirectTransferAtomInit (atoms, 66);
/* Now, initialize quarks. */
resource_quark = XrmPermStringToQuark (compositor.resource_name);

View file

@ -1145,6 +1145,7 @@ struct _RoleFuncs
void (*select_extra_events) (Surface *, Role *, unsigned long);
void (*note_focus) (Surface *, Role *, FocusMode);
void (*outputs_changed) (Surface *, Role *);
void (*activate) (Surface *, Role *, int, Timestamp);
};
struct _Role
@ -1238,7 +1239,8 @@ extern Atom _NET_WM_OPAQUE_REGION, _XL_BUFFER_RELEASE,
XdndProxy, XdndEnter, XdndPosition, XdndStatus, XdndLeave, XdndDrop,
XdndFinished, _NET_WM_FRAME_TIMINGS, _NET_WM_BYPASS_COMPOSITOR, WM_STATE,
_NET_WM_WINDOW_TYPE, _NET_WM_WINDOW_TYPE_MENU, _NET_WM_WINDOW_TYPE_DND,
CONNECTOR_ID, _NET_WM_PID, _NET_WM_PING, libinput_Scrolling_Pixel_Distance;
CONNECTOR_ID, _NET_WM_PID, _NET_WM_PING, libinput_Scrolling_Pixel_Distance,
_NET_ACTIVE_WINDOW;
extern XrmQuark resource_quark, app_quark, QString;
@ -1340,6 +1342,7 @@ struct _XdgRoleImplementationFuncs
void (*note_focus) (Role *, XdgRoleImplementation *, FocusMode);
void (*outputs_changed) (Role *, XdgRoleImplementation *);
void (*after_commit) (Role *, Surface *, XdgRoleImplementation *);
void (*activate) (Role *, XdgRoleImplementation *, int, Time);
};
struct _XdgRoleImplementation
@ -1616,6 +1619,7 @@ extern PinchGesture *XLSeatGetPinchGesture (Seat *, struct wl_resource *);
extern void XLSeatDestroySwipeGesture (SwipeGesture *);
extern void XLSeatDestroyPinchGesture (PinchGesture *);
extern KeyCode XLKeysymToKeycode (KeySym, XEvent *);
extern Bool XLSeatCheckActivationSerial (Seat *, uint32_t);
extern Cursor InitDefaultCursor (void);
@ -1857,6 +1861,10 @@ extern void ReleaseBufferWithHelper (BufferReleaseHelper *, ExtBuffer *,
extern void XLGetTestSeat (struct wl_client *, struct wl_resource *,
uint32_t);
/* Defined in xdg_activation.c. */
extern void XLInitXdgActivation (void);
/* Utility functions that don't belong in a specific file. */
#define ArrayElements(arr) (sizeof (arr) / sizeof (arr)[0])

14
seat.c
View file

@ -6387,6 +6387,20 @@ XLKeysymToKeycode (KeySym keysym, XEvent *event)
return 0;
}
Bool
XLSeatCheckActivationSerial (Seat *seat, uint32_t serial)
{
/* Check if the specified serial can be used to activate surfaces on
behalf of seat. */
return ((seat->last_button_press_serial
&& serial >= seat->last_button_press_serial)
|| (seat->last_button_serial
&& serial >= seat->last_button_press_serial)
|| (seat->last_keyboard_serial
&& serial >= seat->last_keyboard_serial));
}
/* This is a particularly ugly hack, but there is no other way to
expose all the internals needed by test_seat.c. */

15
test.c
View file

@ -336,6 +336,20 @@ GetWindow (Surface *surface, Role *role)
return test->window;
}
static void
Activate (Surface *surface, Role *role, int deviceid,
Timestamp timestamp)
{
TestSurface *test;
test = TestSurfaceFromRole (role);
if (test->role.resource)
test_surface_send_activated (test->role.resource,
timestamp.months,
timestamp.milliseconds);
}
static const struct test_surface_interface test_surface_impl =
{
.destroy = Destroy,
@ -489,6 +503,7 @@ GetTestSurface (struct wl_client *client, struct wl_resource *resource,
test->role.funcs.release_buffer = ReleaseBuffer;
test->role.funcs.subsurface_update = SubsurfaceUpdate;
test->role.funcs.get_window = GetWindow;
test->role.funcs.activate = Activate;
/* Add the resource implementation. */
wl_resource_set_implementation (test->role.resource, &test_surface_impl,

View file

@ -26,6 +26,7 @@ name.c: $(12TO11ROOT)/name.xml name.h @@\
ScannerTarget(12to11-test)
ScannerTarget(viewporter)
ScannerTarget(linux-dmabuf-unstable-v1)
ScannerTarget(xdg-activation-v1)
/* Not actually a test. */
SRCS1 = $(COMMONSRCS) imgview.c
@ -52,7 +53,9 @@ ScannerTarget(linux-dmabuf-unstable-v1)
OBJS11 = select_helper.o
SRCS12 = select_helper_multiple.c
OBJS12 = select_helper_multiple.o
PROGRAMS = imgview simple_test damage_test transform_test viewporter_test subsurface_test scale_test seat_test dmabuf_test select_test select_helper select_helper_multiple
SRCS13 = $(COMMONSRCS) xdg_activation_test.c
OBJS13 = $(COMMONSRCS) xdg_activation_test.o
PROGRAMS = imgview simple_test damage_test transform_test viewporter_test subsurface_test scale_test seat_test dmabuf_test select_test select_helper select_helper_multiple xdg_activation_test
/* Make all objects depend on HEADER. */
$(OBJS1): $(HEADER)
@ -72,10 +75,12 @@ NormalProgramTarget(dmabuf_test,$(OBJS9),NullParameter,$(LOCAL_LIBRARIES) $(GBM)
NormalProgramTarget(select_test,$(OBJS10),NullParameter,$(LOCAL_LIBRARIES) ThreadsLibraries,NullParameter);
NormalProgramTarget(select_helper,$(OBJS11),NullParameter,$(XLIB),NullParameter);
NormalProgramTarget(select_helper_multiple,$(OBJS12),NullParameter,$(XLIB),NullParameter);
NormalProgramTarget(xdg_activation_test,$(OBJS13),NullParameter,$(LOCAL_LIBRARIES),NullParameter)
DependTarget3($(SRCS1),$(SRCS2),$(SRCS3))
DependTarget3($(SRCS4),$(SRCS5),$(SRCS6))
DependTarget3($(SRCS7),$(SRCS8),$(SRCS9))
DependTarget3($(SRCS10),$(SRCS11),$(SRCS12))
DependTarget3($(SRCS13),NullParameter,NullParameter)
all:: $(PROGRAMS)

View file

@ -22,6 +22,7 @@ pushd "$(dirname $0)"
declare -a standard_tests=(
simple_test damage_test transform_test viewporter_test
subsurface_test scale_test seat_test dmabuf_test
xdg_activation_test
)
make -C . "${standard_tests[@]}"

View file

@ -12,6 +12,7 @@ dmabuf_test
select_test
select_helper
select_helper_multiple
xdg_activation_test
imgview
reject.dump
Makefile

View file

@ -1392,6 +1392,20 @@ OutputsChanged (Surface *surface, Role *role)
xdg_role->impl->funcs.outputs_changed (role, xdg_role->impl);
}
static void
Activate (Surface *surface, Role *role, int deviceid,
Timestamp timestamp)
{
XdgRole *xdg_role;
xdg_role = XdgRoleFromRole (role);
if (xdg_role->impl && xdg_role->impl->funcs.activate)
xdg_role->impl->funcs.activate (role, xdg_role->impl,
deviceid,
timestamp.milliseconds);
}
void
XLGetXdgSurface (struct wl_client *client, struct wl_resource *resource,
uint32_t id, struct wl_resource *surface_resource)
@ -1464,6 +1478,7 @@ XLGetXdgSurface (struct wl_client *client, struct wl_resource *resource,
role->role.funcs.select_extra_events = SelectExtraEvents;
role->role.funcs.note_focus = NoteFocus;
role->role.funcs.outputs_changed = OutputsChanged;
role->role.funcs.activate = Activate;
attrs.colormap = compositor.colormap;
attrs.border_pixel = border_pixel;

View file

@ -31,6 +31,8 @@ along with 12to11. If not, see <https://www.gnu.org/licenses/>. */
#include "xdg-shell.h"
#include "xdg-decoration-unstable-v1.h"
#include <X11/extensions/XInput2.h>
#define ToplevelFromRoleImpl(impl) ((XdgToplevel *) (impl))
typedef struct _XdgToplevel XdgToplevel;
@ -2253,6 +2255,49 @@ OutputsChanged (Role *role, XdgRoleImplementation *impl)
}
}
static void
Activate (Role *role, XdgRoleImplementation *impl, int deviceid,
Time time)
{
XEvent message;
XdgToplevel *toplevel;
Window window;
toplevel = ToplevelFromRoleImpl (impl);
window = XLWindowFromXdgRole (toplevel->role);
if (XLWmSupportsHint (_NET_ACTIVE_WINDOW))
{
/* Use a _NET_ACTIVE_WINDOW request. */
message.xclient.type = ClientMessage;
message.xclient.window = window;
message.xclient.message_type = _NET_ACTIVE_WINDOW;
message.xclient.format = 32;
message.xclient.data.l[0] = 1;
message.xclient.data.l[1] = time;
message.xclient.data.l[2] = None;
message.xclient.data.l[3] = 0;
message.xclient.data.l[4] = 0;
fprintf (stderr, "activate at: %d\n", (int) time);
XSendEvent (compositor.display,
DefaultRootWindow (compositor.display),
False, (SubstructureRedirectMask
| SubstructureNotifyMask),
&message);
}
else
{
/* Catch errors as we cannot be sure that the window is viewable
or that the device still exists. */
CatchXErrors ();
XISetFocus (compositor.display, deviceid,
window, time);
UncatchXErrors (NULL);
}
}
static const struct xdg_toplevel_interface xdg_toplevel_impl =
{
.destroy = Destroy,
@ -2319,6 +2364,7 @@ XLGetXdgToplevel (struct wl_client *client, struct wl_resource *resource,
toplevel->impl.funcs.is_window_mapped = IsWindowMapped;
toplevel->impl.funcs.outputs_changed = OutputsChanged;
toplevel->impl.funcs.after_commit = AfterCommit;
toplevel->impl.funcs.activate = Activate;
if (!XLWmSupportsHint (_NET_WM_STATE_FOCUSED))
/* If _NET_WM_STATE_FOCUSED is unsupported, fall back to utilizing