37#include <KDecoration2/Decoration>
39#include <QApplication>
47#include <kkeyserver.h>
49#include <xcb/damage.h>
51#include <xcb/xcb_icccm.h>
57#define XCB_GE_GENERIC 35
77static xcb_window_t findEventWindow(xcb_generic_event_t *event)
79 const uint8_t eventType =
event->response_type & ~0x80;
83 return reinterpret_cast<xcb_key_press_event_t *
>(event)->event;
84 case XCB_BUTTON_PRESS:
85 case XCB_BUTTON_RELEASE:
86 return reinterpret_cast<xcb_button_press_event_t *
>(event)->event;
87 case XCB_MOTION_NOTIFY:
88 return reinterpret_cast<xcb_motion_notify_event_t *
>(event)->event;
89 case XCB_ENTER_NOTIFY:
90 case XCB_LEAVE_NOTIFY:
91 return reinterpret_cast<xcb_enter_notify_event_t *
>(event)->event;
94 return reinterpret_cast<xcb_focus_in_event_t *
>(event)->event;
96 return reinterpret_cast<xcb_expose_event_t *
>(event)->window;
97 case XCB_GRAPHICS_EXPOSURE:
98 return reinterpret_cast<xcb_graphics_exposure_event_t *
>(event)->drawable;
100 return reinterpret_cast<xcb_no_exposure_event_t *
>(event)->drawable;
101 case XCB_VISIBILITY_NOTIFY:
102 return reinterpret_cast<xcb_visibility_notify_event_t *
>(event)->window;
103 case XCB_CREATE_NOTIFY:
104 return reinterpret_cast<xcb_create_notify_event_t *
>(event)->window;
105 case XCB_DESTROY_NOTIFY:
106 return reinterpret_cast<xcb_destroy_notify_event_t *
>(event)->window;
107 case XCB_UNMAP_NOTIFY:
108 return reinterpret_cast<xcb_unmap_notify_event_t *
>(event)->window;
110 return reinterpret_cast<xcb_map_notify_event_t *
>(event)->window;
111 case XCB_MAP_REQUEST:
112 return reinterpret_cast<xcb_map_request_event_t *
>(event)->window;
113 case XCB_REPARENT_NOTIFY:
114 return reinterpret_cast<xcb_reparent_notify_event_t *
>(event)->window;
115 case XCB_CONFIGURE_NOTIFY:
116 return reinterpret_cast<xcb_configure_notify_event_t *
>(event)->window;
117 case XCB_CONFIGURE_REQUEST:
118 return reinterpret_cast<xcb_configure_request_event_t *
>(event)->window;
119 case XCB_GRAVITY_NOTIFY:
120 return reinterpret_cast<xcb_gravity_notify_event_t *
>(event)->window;
121 case XCB_RESIZE_REQUEST:
122 return reinterpret_cast<xcb_resize_request_event_t *
>(event)->window;
123 case XCB_CIRCULATE_NOTIFY:
124 case XCB_CIRCULATE_REQUEST:
125 return reinterpret_cast<xcb_circulate_notify_event_t *
>(event)->window;
126 case XCB_PROPERTY_NOTIFY:
127 return reinterpret_cast<xcb_property_notify_event_t *
>(event)->window;
128 case XCB_COLORMAP_NOTIFY:
129 return reinterpret_cast<xcb_colormap_notify_event_t *
>(event)->window;
130 case XCB_CLIENT_MESSAGE:
131 return reinterpret_cast<xcb_client_message_event_t *
>(event)->window;
135 return reinterpret_cast<xcb_shape_notify_event_t *
>(event)->affected_window;
138 return reinterpret_cast<xcb_damage_notify_event_t *
>(event)->drawable;
140 return XCB_WINDOW_NONE;
149 const uint8_t eventType = e->response_type & ~0x80;
151 const xcb_window_t eventWindow = findEventWindow(e);
152 if (eventWindow != XCB_WINDOW_NONE) {
154 if (window->windowEvent(e)) {
158 if (window->windowEvent(e)) {
162 if (window->windowEvent(e)) {
166 if (window->windowEvent(e)) {
170 if (window->windowEvent(e)) {
177 case XCB_CREATE_NOTIFY: {
178 const auto *
event =
reinterpret_cast<xcb_create_notify_event_t *
>(e);
179 if (event->parent == kwinApp()->x11RootWindow() && !QWidget::find(event->window) && !
event->override_redirect) {
181 kwinApp()->updateXTime();
182 const xcb_timestamp_t t =
xTime();
187 case XCB_UNMAP_NOTIFY: {
188 const auto *
event =
reinterpret_cast<xcb_unmap_notify_event_t *
>(e);
189 return (event->event != event->window);
191 case XCB_REPARENT_NOTIFY: {
196 case XCB_MAP_REQUEST: {
197 kwinApp()->updateXTime();
199 const auto *
event =
reinterpret_cast<xcb_map_request_event_t *
>(e);
203 window->windowEvent(e);
213 if (!createX11Window(event->window,
false)) {
214 xcb_map_window(kwinApp()->x11Connection(), event->window);
215 const uint32_t values[] = {XCB_STACK_MODE_ABOVE};
216 xcb_configure_window(kwinApp()->x11Connection(), event->window, XCB_CONFIG_WINDOW_STACK_MODE, values);
221 case XCB_MAP_NOTIFY: {
222 const auto *
event =
reinterpret_cast<xcb_map_notify_event_t *
>(e);
223 if (event->override_redirect) {
225 if (window ==
nullptr) {
226 window = createUnmanaged(event->window);
234 window = createUnmanaged(event->window);
241 return (event->event != event->window);
244 case XCB_CONFIGURE_REQUEST: {
245 const auto *
event =
reinterpret_cast<xcb_configure_request_event_t *
>(e);
246 if (event->parent == kwinApp()->x11RootWindow()) {
247 uint32_t values[5] = {0, 0, 0, 0, 0};
248 const uint32_t value_mask =
event->value_mask
249 & (XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT | XCB_CONFIG_WINDOW_BORDER_WIDTH);
251 if (value_mask & XCB_CONFIG_WINDOW_X) {
252 values[i++] =
event->x;
254 if (value_mask & XCB_CONFIG_WINDOW_Y) {
255 values[i++] =
event->y;
257 if (value_mask & XCB_CONFIG_WINDOW_WIDTH) {
258 values[i++] =
event->width;
260 if (value_mask & XCB_CONFIG_WINDOW_HEIGHT) {
261 values[i++] =
event->height;
263 if (value_mask & XCB_CONFIG_WINDOW_BORDER_WIDTH) {
264 values[i++] =
event->border_width;
266 xcb_configure_window(kwinApp()->x11Connection(), event->window, value_mask, values);
271 case XCB_CONFIGURE_NOTIFY: {
272 const auto configureNotifyEvent =
reinterpret_cast<xcb_configure_notify_event_t *
>(e);
273 if (configureNotifyEvent->override_redirect && configureNotifyEvent->event == kwinApp()->x11RootWindow()) {
274 updateXStackingOrder();
279 const auto *
event =
reinterpret_cast<xcb_focus_in_event_t *
>(e);
280 if (event->event == kwinApp()->x11RootWindow()
281 && (
event->detail == XCB_NOTIFY_DETAIL_NONE ||
event->detail == XCB_NOTIFY_DETAIL_POINTER_ROOT ||
event->detail == XCB_NOTIFY_DETAIL_INFERIOR)) {
283 kwinApp()->updateXTime();
286 const bool lostFocusPointerToRoot = currentInput->focus == kwinApp()->x11RootWindow() &&
event->detail == XCB_NOTIFY_DETAIL_INFERIOR;
287 if (!currentInput.
isNull() && (currentInput->focus == XCB_WINDOW_NONE || currentInput->focus == XCB_INPUT_FOCUS_POINTER_ROOT || lostFocusPointerToRoot)) {
290 if (window !=
nullptr) {
319 NET::Properties dirtyProperties;
320 NET::Properties2 dirtyProperties2;
321 info->event(e, &dirtyProperties, &dirtyProperties2);
322 if (dirtyProperties2 & NET::WM2Opacity) {
327 if (dirtyProperties2 & NET::WM2OpaqueRegion) {
330 if (dirtyProperties2.testFlag(NET::WM2WindowRole)) {
333 if (dirtyProperties2.testFlag(NET::WM2WindowClass)) {
336 const uint8_t eventType = e->response_type & ~0x80;
338 case XCB_DESTROY_NOTIFY:
341 case XCB_UNMAP_NOTIFY: {
351 kwinApp()->updateXTime();
359 m_releaseTimer.start(1);
362 case XCB_CONFIGURE_NOTIFY:
363 configureNotifyEvent(
reinterpret_cast<xcb_configure_notify_event_t *
>(e));
365 case XCB_PROPERTY_NOTIFY:
366 propertyNotifyEvent(
reinterpret_cast<xcb_property_notify_event_t *
>(e));
368 case XCB_CLIENT_MESSAGE:
369 clientMessageEvent(
reinterpret_cast<xcb_client_message_event_t *
>(e));
385 if (findEventWindow(e) ==
window()) {
386 NET::Properties dirtyProperties;
387 NET::Properties2 dirtyProperties2;
388 info->event(e, &dirtyProperties, &dirtyProperties2);
390 if ((dirtyProperties & NET::WMName) != 0) {
393 if ((dirtyProperties & NET::WMIconName) != 0) {
396 if ((dirtyProperties & NET::WMStrut) != 0
397 || (dirtyProperties2 & NET::WM2ExtendedStrut) != 0) {
400 if ((dirtyProperties & NET::WMIcon) != 0) {
406 if ((dirtyProperties2 & NET::WM2UserTime) != 0) {
410 if ((dirtyProperties2 & NET::WM2StartupId) != 0) {
413 if (dirtyProperties2 & NET::WM2Opacity) {
418 NETWinInfo i(kwinApp()->x11Connection(),
frameId(), kwinApp()->x11RootWindow(), NET::Properties(), NET::Properties2());
419 i.setOpacity(info->opacity());
422 if (dirtyProperties2.testFlag(NET::WM2WindowRole)) {
425 if (dirtyProperties2.testFlag(NET::WM2WindowClass)) {
428 if (dirtyProperties2.testFlag(NET::WM2BlockCompositing)) {
431 if (dirtyProperties2.testFlag(NET::WM2GroupLeader)) {
433 updateAllowedActions();
435 if (dirtyProperties2.testFlag(NET::WM2Urgency)) {
438 if (dirtyProperties2 & NET::WM2OpaqueRegion) {
441 if (dirtyProperties2 & NET::WM2DesktopFileName) {
444 if (dirtyProperties2 & NET::WM2GTKFrameExtents) {
445 setClientFrameExtents(info->gtkFrameExtents());
449 const uint8_t eventType = e->response_type & ~0x80;
451 case XCB_UNMAP_NOTIFY:
452 unmapNotifyEvent(
reinterpret_cast<xcb_unmap_notify_event_t *
>(e));
454 case XCB_DESTROY_NOTIFY:
455 destroyNotifyEvent(
reinterpret_cast<xcb_destroy_notify_event_t *
>(e));
457 case XCB_MAP_REQUEST:
459 return mapRequestEvent(
reinterpret_cast<xcb_map_request_event_t *
>(e));
460 case XCB_CONFIGURE_REQUEST:
461 configureRequestEvent(
reinterpret_cast<xcb_configure_request_event_t *
>(e));
463 case XCB_PROPERTY_NOTIFY:
464 propertyNotifyEvent(
reinterpret_cast<xcb_property_notify_event_t *
>(e));
467 updateUserTime(
reinterpret_cast<xcb_key_press_event_t *
>(e)->time);
469 case XCB_BUTTON_PRESS: {
470 const auto *
event =
reinterpret_cast<xcb_button_press_event_t *
>(e);
472 buttonPressEvent(event->event, event->detail, event->state,
473 event->event_x, event->event_y, event->root_x, event->root_y, event->time);
476 case XCB_KEY_RELEASE:
481 case XCB_BUTTON_RELEASE: {
482 const auto *
event =
reinterpret_cast<xcb_button_release_event_t *
>(e);
486 buttonReleaseEvent(event->event, event->detail, event->state,
487 event->event_x, event->event_y, event->root_x, event->root_y);
490 case XCB_MOTION_NOTIFY: {
491 const auto *
event =
reinterpret_cast<xcb_motion_notify_event_t *
>(e);
498 motionNotifyEvent(event->event, event->state,
499 x,
y, root_x, root_y);
503 case XCB_ENTER_NOTIFY: {
504 auto *
event =
reinterpret_cast<xcb_enter_notify_event_t *
>(e);
505 enterNotifyEvent(event);
516 motionNotifyEvent(event->event, event->state,
517 x,
y, root_x, root_y);
521 case XCB_LEAVE_NOTIFY: {
522 auto *
event =
reinterpret_cast<xcb_leave_notify_event_t *
>(e);
528 motionNotifyEvent(event->event, event->state,
529 x,
y, root_x, root_y);
530 leaveNotifyEvent(event);
536 focusInEvent(
reinterpret_cast<xcb_focus_in_event_t *
>(e));
539 focusOutEvent(
reinterpret_cast<xcb_focus_out_event_t *
>(e));
541 case XCB_REPARENT_NOTIFY:
543 case XCB_CLIENT_MESSAGE:
544 clientMessageEvent(
reinterpret_cast<xcb_client_message_event_t *
>(e));
547 xcb_expose_event_t *
event =
reinterpret_cast<xcb_expose_event_t *
>(e);
555 if (eventType ==
Xcb::Extensions::self()->shapeNotifyEvent() &&
reinterpret_cast<xcb_shape_notify_event_t *
>(e)->affected_window ==
window()) {
559 if (eventType ==
Xcb::Extensions::self()->damageNotifyEvent() &&
reinterpret_cast<xcb_damage_notify_event_t *
>(e)->drawable ==
frameId()) {
570bool X11Window::mapRequestEvent(xcb_map_request_event_t *e)
572 if (e->window !=
window()) {
610void X11Window::unmapNotifyEvent(xcb_unmap_notify_event_t *e)
612 if (e->window !=
window()) {
618 if (e->event == kwinApp()->x11RootWindow() && (e->response_type & 0x80)) {
629 Xcb::Tree tree(m_client);
630 xcb_window_t daddy = tree.parent();
631 if (daddy == m_wrapper) {
638void X11Window::destroyNotifyEvent(xcb_destroy_notify_event_t *e)
640 if (e->window !=
window()) {
649void X11Window::clientMessageEvent(xcb_client_message_event_t *e)
652 m_surfaceSerial = (uint64_t(e->data.data32[1]) << 32) | e->data.data32[0];
654 if (XwaylandSurfaceV1Interface *xwaylandSurface = w->xwaylandShell()->findSurface(m_surfaceSerial)) {
659 m_pendingSurfaceId = e->data.data32[0];
667 if (e->window !=
window()) {
672 if (e->data.data32[0] == XCB_ICCCM_WM_STATE_ICONIC) {
679void X11Window::configureNotifyEvent(xcb_configure_notify_event_t *e)
703void X11Window::configureRequestEvent(xcb_configure_request_event_t *e)
705 if (e->window !=
window()) {
712 if (m_fullscreenMode == FullScreenNormal) {
714 sendSyntheticConfigureNotify();
718 sendSyntheticConfigureNotify();
722 if (e->value_mask & XCB_CONFIG_WINDOW_BORDER_WIDTH) {
727 if (e->value_mask & (XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_HEIGHT | XCB_CONFIG_WINDOW_WIDTH)) {
731 if (e->value_mask & XCB_CONFIG_WINDOW_STACK_MODE) {
740 sendSyntheticConfigureNotify();
749void X11Window::propertyNotifyEvent(xcb_property_notify_event_t *e)
751 if (e->window !=
window()) {
755 case XCB_ATOM_WM_NORMAL_HINTS:
758 case XCB_ATOM_WM_NAME:
761 case XCB_ATOM_WM_ICON_NAME:
764 case XCB_ATOM_WM_TRANSIENT_FOR:
767 case XCB_ATOM_WM_HINTS:
780 updateShowOnScreenEdge();
790 getSkipCloseAnimation();
796void X11Window::enterNotifyEvent(xcb_enter_notify_event_t *e)
806 if (e->mode == XCB_NOTIFY_MODE_NORMAL || (e->mode == XCB_NOTIFY_MODE_UNGRAB && mouseDrivenFocus)) {
812void X11Window::leaveNotifyEvent(xcb_leave_notify_event_t *e)
820 if (e->mode == XCB_NOTIFY_MODE_NORMAL) {
825 bool lostMouse = !exclusiveContains(
rect(), QPointF(e->event_x, e->event_y));
833 if (!lostMouse && e->detail != XCB_NOTIFY_DETAIL_INFERIOR) {
834 Xcb::Pointer pointer(
frameId());
835 if (!pointer || !pointer->same_screen || pointer->child == XCB_WINDOW_NONE) {
844 QHoverEvent leaveEvent(QEvent::HoverMove, QPointF(-1, -1), QPointF(-1, -1), Qt::NoModifier);
845 QCoreApplication::sendEvent(
decoration(), &leaveEvent);
855static uint16_t x11CommandAllModifier()
858 case Qt::MetaModifier:
859 return KKeyServer::modXMeta();
860 case Qt::AltModifier:
861 return KKeyServer::modXAlt();
867#define XCapL KKeyServer::modXLock()
868#define XNumL KKeyServer::modXNumLock()
869#define XScrL KKeyServer::modXScrollLock()
870void X11Window::establishCommandWindowGrab(uint8_t button)
876 m_wrapper.
grabButton(XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC, XCB_MOD_MASK_ANY, button);
878 uint16_t x11Modifier = x11CommandAllModifier();
880 unsigned int mods[8] = {
884 for (
int i = 0; i < 8; ++i) {
889void X11Window::establishCommandAllGrab(uint8_t button)
891 uint16_t x11Modifier = x11CommandAllModifier();
893 unsigned int mods[8] = {
897 for (
int i = 0; i < 8; ++i) {
898 m_wrapper.
grabButton(XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC, x11Modifier | mods[i], button);
911 xcb_ungrab_button(kwinApp()->x11Connection(), XCB_BUTTON_INDEX_ANY, m_wrapper, XCB_MOD_MASK_ANY);
914 if (
workspace()->tabbox()->forcedGlobalMouseGrab()) {
915 m_wrapper.
grabButton(XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC);
929 establishCommandWindowGrab(XCB_BUTTON_INDEX_1);
932 establishCommandWindowGrab(XCB_BUTTON_INDEX_2);
935 establishCommandWindowGrab(XCB_BUTTON_INDEX_3);
938 establishCommandWindowGrab(XCB_BUTTON_INDEX_4);
939 establishCommandWindowGrab(XCB_BUTTON_INDEX_5);
947 if (!
workspace()->globalShortcutsDisabled()) {
949 establishCommandAllGrab(XCB_BUTTON_INDEX_1);
952 establishCommandAllGrab(XCB_BUTTON_INDEX_2);
955 establishCommandAllGrab(XCB_BUTTON_INDEX_3);
958 establishCommandAllGrab(XCB_BUTTON_INDEX_4);
959 establishCommandAllGrab(XCB_BUTTON_INDEX_5);
964static bool modKeyDown(
int state)
966 const uint keyModX = (
options->
keyCmdAllModKey() == Qt::Key_Meta) ? KKeyServer::modXMeta() : KKeyServer::modXAlt();
967 return keyModX && (state & KKeyServer::accelModMaskX()) == keyModX;
971bool X11Window::buttonPressEvent(xcb_window_t w,
int button,
int state,
int x,
int y,
int x_root,
int y_root, xcb_timestamp_t time)
978 xcb_allow_events(kwinApp()->x11Connection(), XCB_ALLOW_SYNC_POINTER, XCB_TIME_CURRENT_TIME);
986 const bool bModKeyHeld = modKeyDown(state);
989 && button == XCB_BUTTON_INDEX_1 && !bModKeyHeld) {
993 xcb_allow_events(kwinApp()->x11Connection(), XCB_ALLOW_SYNC_POINTER, XCB_TIME_CURRENT_TIME);
999 bool was_action =
false;
1003 case XCB_BUTTON_INDEX_1:
1006 case XCB_BUTTON_INDEX_2:
1009 case XCB_BUTTON_INDEX_3:
1012 case XCB_BUTTON_INDEX_4:
1013 case XCB_BUTTON_INDEX_5:
1021 }
else if (button < 6) {
1034 xcb_allow_events(kwinApp()->x11Connection(), replay ? XCB_ALLOW_REPLAY_POINTER : XCB_ALLOW_SYNC_POINTER, XCB_TIME_CURRENT_TIME);
1041 xcb_allow_events(kwinApp()->x11Connection(), XCB_ALLOW_REPLAY_POINTER, XCB_TIME_CURRENT_TIME);
1048 QMouseEvent ev(QMouseEvent::MouseButtonPress,
1050 QPoint(x_root, y_root),
1053 Qt::KeyboardModifiers());
1057 if (button >= 4 && button <= 7) {
1060 const int delta = 120 * ((button == 4 || button == 6) ? 1 : -1);
1061 const bool hor = (((button == 4 || button == 5) && (modifiers & Qt::AltModifier))
1062 || (button == 6 || button == 7));
1064 const QPoint angle = hor ? QPoint(delta, 0) : QPoint(0, delta);
1065 QWheelEvent event(QPointF(
x,
y),
1066 QPointF(x_root, y_root),
1073 event.setAccepted(
false);
1074 QCoreApplication::sendEvent(
decoration(), &event);
1075 if (!event.isAccepted() && !hor) {
1081 QMouseEvent event(QEvent::MouseButtonPress,
1083 QPointF(x_root, y_root),
1087 event.setTimestamp(time);
1088 event.setAccepted(
false);
1089 QCoreApplication::sendEvent(
decoration(), &event);
1090 if (!event.isAccepted()) {
1100bool X11Window::buttonReleaseEvent(xcb_window_t w,
int button,
int state,
int x,
int y,
int x_root,
int y_root)
1107 if (button < 4 || button > 7) {
1108 QMouseEvent event(QEvent::MouseButtonRelease,
1110 QPointF(x_root, y_root),
1114 event.setAccepted(
false);
1115 QCoreApplication::sendEvent(
decoration(), &event);
1122 xcb_allow_events(kwinApp()->x11Connection(), XCB_ALLOW_SYNC_POINTER, XCB_TIME_CURRENT_TIME);
1135 int buttonMask = XCB_BUTTON_MASK_1 | XCB_BUTTON_MASK_2 | XCB_BUTTON_MASK_3;
1136 if (button == XCB_BUTTON_INDEX_1) {
1137 buttonMask &= ~XCB_BUTTON_MASK_1;
1138 }
else if (button == XCB_BUTTON_INDEX_2) {
1139 buttonMask &= ~XCB_BUTTON_MASK_2;
1140 }
else if (button == XCB_BUTTON_INDEX_3) {
1141 buttonMask &= ~XCB_BUTTON_MASK_3;
1144 if ((state & buttonMask) == 0) {
1151bool X11Window::motionNotifyEvent(xcb_window_t w,
int state,
int x,
int y,
int x_root,
int y_root)
1158 QHoverEvent event(QEvent::HoverMove, QPointF(
x,
y), QPointF(
x,
y));
1159 QCoreApplication::instance()->sendEvent(
decoration(), &event);
1170 QHoverEvent event(QEvent::HoverMove, QPointF(
x,
y), QPointF(
x,
y));
1171 QCoreApplication::instance()->sendEvent(
decoration(), &event);
1194void X11Window::focusInEvent(xcb_focus_in_event_t *e)
1196 if (e->event !=
window()) {
1199 if (e->mode == XCB_NOTIFY_MODE_UNGRAB) {
1202 if (e->detail == XCB_NOTIFY_DETAIL_POINTER) {
1209 window->cancelFocusOutTimer();
1220 qCWarning(KWIN_CORE,
"Failed to restore focus. Activating 0x%x",
window());
1226void X11Window::focusOutEvent(xcb_focus_out_event_t *e)
1228 if (e->event !=
window()) {
1231 if (e->mode == XCB_NOTIFY_MODE_GRAB) {
1237 if (e->detail != XCB_NOTIFY_DETAIL_NONLINEAR
1238 && e->detail != XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL) {
1242 if (QApplication::activePopupWidget()) {
1261 if (!m_focusOutTimer) {
1262 m_focusOutTimer =
new QTimer(
this);
1263 m_focusOutTimer->setSingleShot(
true);
1264 m_focusOutTimer->setInterval(0);
1265 connect(m_focusOutTimer, &QTimer::timeout,
this, [
this]() {
1269 m_focusOutTimer->start();
1275 if (direction == NET::Move) {
1285 }
else if (direction >= NET::TopLeft && direction <= NET::Left) {
1286 static const Gravity convert[] = {
1310 }
else if (direction == NET::KeyboardMove) {
1314 }
else if (direction == NET::KeyboardSize) {
Xcb::Atom kde_skip_close_animation
Xcb::Atom wm_change_state
Xcb::Atom kde_net_wm_appmenu_object_path
Xcb::Atom wm_client_leader
Xcb::Atom kde_color_sheme
Xcb::Atom wl_surface_serial
Xcb::Atom kde_net_wm_shadow
Xcb::Atom kde_net_wm_appmenu_service_name
Xcb::Atom net_wm_sync_request_counter
Xcb::Atom kde_net_wm_user_creation_time
Xcb::Atom kde_screen_edge_show
static bool compositing()
Static check to test whether the Compositor is available and active.
static Compositor * self()
void setPos(const QPointF &pos)
void checkInputWindowStacking()
MouseWheelCommand commandAllWheel() const
MouseCommand commandWindowWheel
@ MouseUnrestrictedResize
Qt::KeyboardModifier commandAllModifier() const
bool isClickRaise() const
MouseCommand commandWindow2
MouseCommand operationWindowMouseWheel(int delta) const
MouseCommand operationTitlebarMouseWheel(int delta) const
MouseCommand commandWindow3
bool focusPolicyIsReasonable
bool isNextFocusPrefersMouse() const
@ FocusStrictlyUnderMouse
MouseCommand commandWindow1
void check(const QPoint &pos, const QDateTime &now, bool forceNoPushBack=false)
static SurfaceInterface * get(wl_resource *native)
void setOpacity(qreal opacity)
QPointF interactiveMoveOffset() const
void triggerDecorationRepaint()
Gravity mouseGravity() const
void setMinimized(bool set)
void setDesktopFileName(const QString &name)
void frameGeometryAboutToChange()
void invalidateDecorationDoubleClickTimer()
void setSurface(SurfaceInterface *surface)
bool isInteractiveMoveResizePointerButtonDown() const
bool isInteractiveMove() const
void setInteractiveMoveResizePointerButtonDown(bool down)
void keyPressEvent(uint key_code)
bool startInteractiveMoveResize()
void endInteractiveMoveResize()
bool isMostRecentlyRaised() const
bool isInteractiveMoveResize() const
virtual void pointerEnterEvent(const QPointF &globalPos)
void demandAttention(bool set=true)
std::shared_ptr< KDecoration2::Decoration > decoration
void setInteractiveMoveResizeGravity(Gravity gravity)
void handleInteractiveMoveResize(qreal x, qreal y, qreal x_root, qreal y_root)
void clientGeometryChanged(const QRectF &oldGeometry)
Options::MouseCommand getMouseCommand(Qt::MouseButton button, bool *handled) const
bool isInteractiveResize() const
Options::MouseCommand getWheelCommand(Qt::Orientation orientation, bool *handled) const
void finishInteractiveMoveResize(bool cancel)
virtual void pointerLeaveEvent()
bool isOnCurrentDesktop() const
void setUnrestrictedInteractiveMoveResize(bool set)
void setInteractiveMoveOffset(const QPointF &offset)
void setHidden(bool hidden)
bool performMouseCommand(Options::MouseCommand, const QPointF &globalPos)
void bufferGeometryChanged(const QRectF &oldGeometry)
void frameGeometryChanged(const QRectF &oldGeometry)
void setInvertedInteractiveMoveOffset(const QPointF &offset)
bool isSpecialWindow() const
bool processDecorationButtonPress(QMouseEvent *event, bool ignoreMenu=false)
bool titlebarPositionUnderMouse() const
Gravity interactiveMoveResizeGravity() const
X11Window * findUnmanaged(std::function< bool(const X11Window *)> func) const
Window * mostRecentlyActivatedWindow() const
ScreenEdges * screenEdges() const
X11Window * findClient(std::function< bool(const X11Window *)> func) const
Finds the first Client matching the condition expressed by passed in func.
void activateWindow(Window *window, bool force=false)
void gotFocusIn(const Window *window)
UserActionsMenu * userActionsMenu() const
void updateFocusMousePosition(const QPointF &pos)
bool activateNextWindow(Window *window)
bool requestFocus(Window *window, bool force=false)
bool workspaceEvent(xcb_generic_event_t *)
void forEachClient(std::function< void(X11Window *)> func)
void setWasUserInteraction()
void requestDelayFocus(Window *)
void checkGroup(Group *gr=nullptr, bool force=false)
void checkActivities() override
xcb_window_t inputId() const
xcb_window_t moveResizeGrabWindow() const
void checkApplicationMenuObjectPath()
xcb_window_t frameId() const
void NETMoveResize(qreal x_root, qreal y_root, NET::Direction direction, xcb_button_t button)
bool hasScheduledRelease() const
void restackWindow(xcb_window_t above, int detail, NET::RequestSource source, xcb_timestamp_t timestamp, bool send_event=false)
void updateMouseGrab() override
void destroyWindow() override
void keyPressEvent(uint key_code, xcb_timestamp_t time)
void checkApplicationMenuServiceName()
bool isUnmanaged() const override
bool windowEvent(xcb_generic_event_t *e)
void updateUserTime(xcb_timestamp_t time=XCB_TIME_CURRENT_TIME)
xcb_window_t window() const
bool allowWindowActivation(xcb_timestamp_t time=-1U, bool focus_in=false)
bool isResizable() const override
xcb_timestamp_t userTime() const override
void releaseWindow(bool on_shutdown=false)
xcb_window_t wrapperId() const
void setBlockingCompositing(bool block)
int damageNotifyEvent() const
int shapeNotifyEvent() const
static Extensions * self()
void setBorderWidth(uint32_t width)
void grabButton(uint8_t pointerMode, uint8_t keyboardmode, uint16_t modifiers=XCB_MOD_MASK_ANY, uint8_t button=XCB_BUTTON_INDEX_ANY, uint16_t eventMask=XCB_EVENT_MASK_BUTTON_PRESS, xcb_window_t confineTo=XCB_WINDOW_NONE, xcb_cursor_t cursor=XCB_CURSOR_NONE, bool ownerEvents=false)
void ungrabButton(uint16_t modifiers=XCB_MOD_MASK_ANY, uint8_t button=XCB_BUTTON_INDEX_ANY)
struct xcb_ge_generic_event_t xcb_ge_generic_event_t
qreal fromXNative(int value)
Qt::MouseButtons x11ToQtMouseButtons(int state)
Qt::MouseButton x11ToQtMouseButton(int button)
KWIN_EXPORT xcb_timestamp_t xTime()
WaylandServer * waylandServer()
Qt::KeyboardModifiers x11ToQtKeyboardModifiers(int state)
KWIN_EXPORT Atoms * atoms