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