forked from 12to11/12to11

* 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.
306 lines
8.7 KiB
C
306 lines
8.7 KiB
C
/* Wayland compositor running on top of an X server.
|
|
|
|
Copyright (C) 2022 to various contributors.
|
|
|
|
This file is part of 12to11.
|
|
|
|
12to11 is free software: you can redistribute it and/or modify it
|
|
under the terms of the GNU General Public License as published by the
|
|
Free Software Foundation, either version 3 of the License, or (at your
|
|
option) any later version.
|
|
|
|
12to11 is distributed in the hope that it will be useful, but WITHOUT
|
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with 12to11. If not, see <https://www.gnu.org/licenses/>. */
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#include "compositor.h"
|
|
|
|
#define AtomTableSize 256
|
|
|
|
typedef struct _AtomTable AtomTable;
|
|
|
|
/* This is automatically generated by mime4.awk. */
|
|
Atom DirectTransferAtoms;
|
|
|
|
/* Simple hash table for atoms. */
|
|
|
|
struct _AtomTable
|
|
{
|
|
/* Atom array indexed by table size. */
|
|
Atom *atoms[AtomTableSize];
|
|
|
|
/* Atom name array indexed by table size. */
|
|
char **names[AtomTableSize];
|
|
|
|
/* Size of each array. */
|
|
ptrdiff_t atoms_length[AtomTableSize];
|
|
};
|
|
|
|
/* Array of all atom names. */
|
|
static const char *names[] =
|
|
{
|
|
"_NET_WM_OPAQUE_REGION",
|
|
"_XL_BUFFER_RELEASE",
|
|
"_NET_WM_SYNC_REQUEST_COUNTER",
|
|
"_NET_WM_FRAME_DRAWN",
|
|
"WM_DELETE_WINDOW",
|
|
"WM_PROTOCOLS",
|
|
"_NET_SUPPORTING_WM_CHECK",
|
|
"_NET_SUPPORTED",
|
|
"_NET_WM_SYNC_REQUEST",
|
|
"_MOTIF_WM_HINTS",
|
|
"_NET_WM_STATE_MAXIMIZED_VERT",
|
|
"_NET_WM_STATE_MAXIMIZED_HORZ",
|
|
"_NET_WM_STATE_FOCUSED",
|
|
"_NET_WM_STATE_FULLSCREEN",
|
|
"_NET_WM_STATE",
|
|
"_NET_WM_MOVERESIZE",
|
|
"_GTK_FRAME_EXTENTS",
|
|
"WM_TRANSIENT_FOR",
|
|
"_XL_DMA_BUF_CREATED",
|
|
"_GTK_SHOW_WINDOW_MENU",
|
|
"_NET_WM_ALLOWED_ACTIONS",
|
|
"_NET_WM_ACTION_FULLSCREEN",
|
|
"_NET_WM_ACTION_MAXIMIZE_HORZ",
|
|
"_NET_WM_ACTION_MAXIMIZE_VERT",
|
|
"_NET_WM_ACTION_MINIMIZE",
|
|
"INCR",
|
|
"CLIPBOARD",
|
|
"TARGETS",
|
|
"UTF8_STRING",
|
|
"_XL_SERVER_TIME_ATOM",
|
|
"MULTIPLE",
|
|
"TIMESTAMP",
|
|
"ATOM_PAIR",
|
|
"_NET_WM_NAME",
|
|
"WM_NAME",
|
|
"MANAGER",
|
|
"_XSETTINGS_SETTINGS",
|
|
"libinput Scroll Methods Available",
|
|
"XdndAware",
|
|
"XdndSelection",
|
|
"XdndTypeList",
|
|
"XdndActionCopy",
|
|
"XdndActionMove",
|
|
"XdndActionLink",
|
|
"XdndActionAsk",
|
|
"XdndActionPrivate",
|
|
"XdndActionList",
|
|
"XdndActionDescription",
|
|
"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",
|
|
"_NET_ACTIVE_WINDOW",
|
|
|
|
/* These are automatically generated from mime.txt. */
|
|
DirectTransferAtomNames
|
|
};
|
|
|
|
Atom _NET_WM_OPAQUE_REGION, _XL_BUFFER_RELEASE, _NET_WM_SYNC_REQUEST_COUNTER,
|
|
_NET_WM_FRAME_DRAWN, WM_DELETE_WINDOW, WM_PROTOCOLS,
|
|
_NET_SUPPORTING_WM_CHECK, _NET_SUPPORTED, _NET_WM_SYNC_REQUEST,
|
|
_MOTIF_WM_HINTS, _NET_WM_STATE_MAXIMIZED_VERT, _NET_WM_STATE_MAXIMIZED_HORZ,
|
|
_NET_WM_STATE_FOCUSED, _NET_WM_STATE_FULLSCREEN, _NET_WM_STATE,
|
|
_NET_WM_MOVERESIZE, _GTK_FRAME_EXTENTS, WM_TRANSIENT_FOR,
|
|
_XL_DMA_BUF_CREATED, _GTK_SHOW_WINDOW_MENU, _NET_WM_ALLOWED_ACTIONS,
|
|
_NET_WM_ACTION_FULLSCREEN, _NET_WM_ACTION_MAXIMIZE_HORZ,
|
|
_NET_WM_ACTION_MAXIMIZE_VERT, _NET_WM_ACTION_MINIMIZE, INCR, CLIPBOARD,
|
|
TARGETS, UTF8_STRING, _XL_SERVER_TIME_ATOM, MULTIPLE, TIMESTAMP, ATOM_PAIR,
|
|
_NET_WM_NAME, WM_NAME, MANAGER, _XSETTINGS_SETTINGS,
|
|
libinput_Scroll_Methods_Available, XdndAware, XdndSelection, XdndTypeList,
|
|
XdndActionCopy, XdndActionMove, XdndActionLink, XdndActionAsk,
|
|
XdndActionPrivate, XdndActionList, XdndActionDescription, 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,
|
|
_NET_ACTIVE_WINDOW;
|
|
|
|
XrmQuark resource_quark, app_quark, QString;
|
|
|
|
/* Hash table containing atoms. */
|
|
|
|
static AtomTable atom_table;
|
|
|
|
static unsigned int
|
|
HashAtomString (const char *string)
|
|
{
|
|
unsigned int i;
|
|
|
|
i = 3323198485ul;
|
|
for (; *string; ++string)
|
|
{
|
|
i ^= *string;
|
|
i *= 0x5bd1e995;
|
|
i ^= i >> 15;
|
|
}
|
|
return i;
|
|
}
|
|
|
|
Atom
|
|
InternAtom (const char *name)
|
|
{
|
|
Atom atom;
|
|
unsigned int hash;
|
|
ptrdiff_t bucket_length, i;
|
|
|
|
hash = HashAtomString (name) % AtomTableSize;
|
|
bucket_length = atom_table.atoms_length[hash];
|
|
|
|
for (i = 0; i < bucket_length; ++i)
|
|
{
|
|
if (!strcmp (atom_table.names[hash][i], name))
|
|
return atom_table.atoms[hash][i];
|
|
}
|
|
|
|
atom = XInternAtom (compositor.display, name, False);
|
|
|
|
atom_table.atoms_length[hash] = ++bucket_length;
|
|
atom_table.names[hash]
|
|
= XLRealloc (atom_table.names[hash],
|
|
bucket_length * sizeof *atom_table.names);
|
|
atom_table.atoms[hash]
|
|
= XLRealloc (atom_table.atoms[hash],
|
|
bucket_length * sizeof *atom_table.atoms);
|
|
atom_table.names[hash][bucket_length - 1] = XLStrdup (name);
|
|
atom_table.atoms[hash][bucket_length - 1] = atom;
|
|
return atom;
|
|
}
|
|
|
|
void
|
|
ProvideAtom (const char *name, Atom atom)
|
|
{
|
|
unsigned int hash;
|
|
ptrdiff_t bucket_length, i;
|
|
|
|
hash = HashAtomString (name) % AtomTableSize;
|
|
bucket_length = atom_table.atoms_length[hash];
|
|
|
|
for (i = 0; i < bucket_length; ++i)
|
|
{
|
|
if (!strcmp (atom_table.names[hash][i], name))
|
|
/* The atom already exists; there is no need to update it. */
|
|
return;
|
|
}
|
|
|
|
atom_table.atoms_length[hash] = ++bucket_length;
|
|
atom_table.names[hash]
|
|
= XLRealloc (atom_table.names[hash],
|
|
bucket_length * sizeof *atom_table.names);
|
|
atom_table.atoms[hash]
|
|
= XLRealloc (atom_table.atoms[hash],
|
|
bucket_length * sizeof *atom_table.atoms);
|
|
atom_table.names[hash][bucket_length - 1] = XLStrdup (name);
|
|
atom_table.atoms[hash][bucket_length - 1] = atom;
|
|
}
|
|
|
|
void
|
|
XLInitAtoms (void)
|
|
{
|
|
Atom atoms[ArrayElements (names)];
|
|
|
|
if (!XInternAtoms (compositor.display, (char **) names,
|
|
ArrayElements (names), False,
|
|
atoms))
|
|
{
|
|
fprintf (stderr, "Failed to intern X atoms\n");
|
|
exit (1);
|
|
}
|
|
|
|
_NET_WM_OPAQUE_REGION = atoms[0];
|
|
_XL_BUFFER_RELEASE = atoms[1];
|
|
_NET_WM_SYNC_REQUEST_COUNTER = atoms[2];
|
|
_NET_WM_FRAME_DRAWN = atoms[3];
|
|
WM_DELETE_WINDOW = atoms[4];
|
|
WM_PROTOCOLS = atoms[5];
|
|
_NET_SUPPORTING_WM_CHECK = atoms[6];
|
|
_NET_SUPPORTED = atoms[7];
|
|
_NET_WM_SYNC_REQUEST = atoms[8];
|
|
_MOTIF_WM_HINTS = atoms[9];
|
|
_NET_WM_STATE_MAXIMIZED_VERT = atoms[10];
|
|
_NET_WM_STATE_MAXIMIZED_HORZ = atoms[11];
|
|
_NET_WM_STATE_FOCUSED = atoms[12];
|
|
_NET_WM_STATE_FULLSCREEN = atoms[13];
|
|
_NET_WM_STATE = atoms[14];
|
|
_NET_WM_MOVERESIZE = atoms[15];
|
|
_GTK_FRAME_EXTENTS = atoms[16];
|
|
WM_TRANSIENT_FOR = atoms[17];
|
|
_XL_DMA_BUF_CREATED = atoms[18];
|
|
_GTK_SHOW_WINDOW_MENU = atoms[19];
|
|
_NET_WM_ALLOWED_ACTIONS = atoms[20];
|
|
_NET_WM_ACTION_FULLSCREEN = atoms[21];
|
|
_NET_WM_ACTION_MAXIMIZE_HORZ = atoms[22];
|
|
_NET_WM_ACTION_MAXIMIZE_VERT = atoms[23];
|
|
_NET_WM_ACTION_MINIMIZE = atoms[24];
|
|
INCR = atoms[25];
|
|
CLIPBOARD = atoms[26];
|
|
TARGETS = atoms[27];
|
|
UTF8_STRING = atoms[28];
|
|
_XL_SERVER_TIME_ATOM = atoms[29];
|
|
MULTIPLE = atoms[30];
|
|
TIMESTAMP = atoms[31];
|
|
ATOM_PAIR = atoms[32];
|
|
_NET_WM_NAME = atoms[33];
|
|
WM_NAME = atoms[34];
|
|
MANAGER = atoms[35];
|
|
_XSETTINGS_SETTINGS = atoms[36];
|
|
libinput_Scroll_Methods_Available = atoms[37];
|
|
XdndAware = atoms[38];
|
|
XdndSelection = atoms[39];
|
|
XdndTypeList = atoms[40];
|
|
XdndActionCopy = atoms[41];
|
|
XdndActionMove = atoms[42];
|
|
XdndActionLink = atoms[43];
|
|
XdndActionAsk = atoms[44];
|
|
XdndActionPrivate = atoms[45];
|
|
XdndActionList = atoms[46];
|
|
XdndActionDescription = atoms[47];
|
|
XdndProxy = atoms[48];
|
|
XdndEnter = atoms[49];
|
|
XdndPosition = atoms[50];
|
|
XdndStatus = atoms[51];
|
|
XdndLeave = atoms[52];
|
|
XdndDrop = atoms[53];
|
|
XdndFinished = atoms[54];
|
|
_NET_WM_FRAME_TIMINGS = atoms[55];
|
|
_NET_WM_BYPASS_COMPOSITOR = atoms[56];
|
|
WM_STATE = atoms[57];
|
|
_NET_WM_WINDOW_TYPE = atoms[58];
|
|
_NET_WM_WINDOW_TYPE_MENU = atoms[59];
|
|
_NET_WM_WINDOW_TYPE_DND = atoms[60];
|
|
CONNECTOR_ID = atoms[61];
|
|
_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, 66);
|
|
|
|
/* Now, initialize quarks. */
|
|
resource_quark = XrmPermStringToQuark (compositor.resource_name);
|
|
app_quark = XrmPermStringToQuark (compositor.app_name);
|
|
QString = XrmPermStringToQuark ("String");
|
|
}
|