Skip to content
Snippets Groups Projects
events.c 89.2 KiB
Newer Older
        /*
           The event did not occur in one of our known good clients...
           Get the screen structure from the root of the event.
         */
        screen_info = myDisplayGetScreenFromRoot (display_info, ev->root);
        if (screen_info)
        {
            if ((ev->window == screen_info->xroot) && (screen_info->params->scroll_workspaces)
                    && ((ev->button == Button4) || (ev->button == Button5)))
            {
                rootScrollButton (display_info, ev);
            }
            else
            {
                XUngrabPointer (display_info->dpy, ev->time);
                XSendEvent (display_info->dpy, screen_info->xfwm4_win, FALSE, SubstructureNotifyMask, (XEvent *) ev);
            }
        }
Olivier Fourdan's avatar
Olivier Fourdan committed
    }
Olivier Fourdan's avatar
Olivier Fourdan committed
    /* Release pending events */
    XAllowEvents (display_info->dpy, replay ? ReplayPointer : SyncPointer, CurrentTime);
handleButtonRelease (DisplayInfo *display_info, XButtonEvent * ev)
Olivier Fourdan's avatar
Olivier Fourdan committed
{
Olivier Fourdan's avatar
Olivier Fourdan committed
    ScreenInfo *screen_info;

    TRACE ("entering handleButtonRelease");
Olivier Fourdan's avatar
Olivier Fourdan committed

    /* Get the screen structure from the root of the event */
    screen_info = myDisplayGetScreenFromRoot (display_info, ev->root);
        XSendEvent (display_info->dpy, screen_info->xfwm4_win, FALSE, SubstructureNotifyMask, (XEvent *) ev);
    /* Release pending events */
    XAllowEvents (display_info->dpy, SyncPointer, CurrentTime);
handleDestroyNotify (DisplayInfo *display_info, XDestroyWindowEvent * ev)
#ifdef ENABLE_KDE_SYSTRAY_PROXY
Olivier Fourdan's avatar
Olivier Fourdan committed
    ScreenInfo *screen_info;
    TRACE ("entering handleDestroyNotify");
    TRACE ("DestroyNotify on window (0x%lx)", ev->window);
    screen_info = myDisplayGetScreenFromSystray (display_info, ev->window);
Olivier Fourdan's avatar
Olivier Fourdan committed
    if (screen_info)
        /* systray window is gone */
        screen_info->systray = None;
    c = myDisplayGetClientFromWindow (display_info, ev->window, SEARCH_WINDOW);
        TRACE ("DestroyNotify for \"%s\" (0x%lx)", c->name, c->window);
        list_of_windows = clientListTransientOrModal (c);
        clientPassFocus (c->screen_info, c, list_of_windows);
        clientUnframe (c, FALSE);
        status = EVENT_FILTER_REMOVE;
handleMapRequest (DisplayInfo *display_info, XMapRequestEvent * ev)
Olivier Fourdan's avatar
Olivier Fourdan committed
{
Olivier Fourdan's avatar
Olivier Fourdan committed
    Client *c;
Olivier Fourdan's avatar
Olivier Fourdan committed

    TRACE ("entering handleMapRequest");
    TRACE ("MapRequest on window (0x%lx)", ev->window);
Olivier Fourdan's avatar
Olivier Fourdan committed

Olivier Fourdan's avatar
Olivier Fourdan committed
    {
        TRACE ("Mapping None ???");
Olivier Fourdan's avatar
Olivier Fourdan committed
    }
    c = myDisplayGetClientFromWindow (display_info, ev->window, SEARCH_WINDOW);
Olivier Fourdan's avatar
Olivier Fourdan committed
    {
        ScreenInfo *screen_info = c->screen_info;

Olivier Fourdan's avatar
Olivier Fourdan committed
        TRACE ("handleMapRequest: clientShow");
Olivier Fourdan's avatar
Olivier Fourdan committed
        if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_MAP_PENDING))
        {
            TRACE ("Ignoring MapRequest on window (0x%lx)", ev->window);
            status = EVENT_FILTER_REMOVE;
        if (FLAG_TEST (c->flags, CLIENT_FLAG_STICKY) ||
            (c->win_workspace == screen_info->current_ws))
        status = EVENT_FILTER_REMOVE;
Olivier Fourdan's avatar
Olivier Fourdan committed
        TRACE ("handleMapRequest: clientFrame");
        clientFrame (display_info, ev->window, FALSE);
        status = EVENT_FILTER_REMOVE;
Olivier Fourdan's avatar
Olivier Fourdan committed
    }
handleMapNotify (DisplayInfo *display_info, XMapEvent * ev)
Olivier Fourdan's avatar
Olivier Fourdan committed
    Client *c;
Olivier Fourdan's avatar
Olivier Fourdan committed

    TRACE ("entering handleMapNotify");
    TRACE ("MapNotify on window (0x%lx)", ev->window);
    c = myDisplayGetClientFromWindow (display_info, ev->window, SEARCH_WINDOW);
Olivier Fourdan's avatar
Olivier Fourdan committed
    if (c)
    {
        TRACE ("MapNotify for \"%s\" (0x%lx)", c->name, c->window);
Olivier Fourdan's avatar
Olivier Fourdan committed
        if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_MAP_PENDING))
Olivier Fourdan's avatar
Olivier Fourdan committed
            FLAG_UNSET (c->xfwm_flags, XFWM_FLAG_MAP_PENDING);
Olivier Fourdan's avatar
Olivier Fourdan committed
    }
handleUnmapNotify (DisplayInfo *display_info, XUnmapEvent * ev)
Olivier Fourdan's avatar
Olivier Fourdan committed
    ScreenInfo *screen_info;
Olivier Fourdan's avatar
Olivier Fourdan committed
    Client *c;

    TRACE ("entering handleUnmapNotify");
    TRACE ("UnmapNotify on window (0x%lx)", ev->window);
        TRACE ("Ignoring UnmapNotify caused by parent's resize");
    screen_info = myDisplayGetScreenFromWindow (display_info, ev->window);
    if (screen_info && (ev->event != ev->window) && (ev->event != screen_info->xroot || !ev->send_event))
        TRACE ("handleUnmapNotify (): Event ignored");
    c = myDisplayGetClientFromWindow (display_info, ev->window, SEARCH_WINDOW);
    if (c)
    {
        TRACE ("UnmapNotify for \"%s\" (0x%lx)", c->name, c->window);
        TRACE ("ignore_unmap for \"%s\" is %i", c->name, c->ignore_unmap);
        status = EVENT_FILTER_REMOVE;
Olivier Fourdan's avatar
Olivier Fourdan committed
        if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_MAP_PENDING))
             * This UnmapNotify event is caused by reparenting
             * so we just ignore it, so the window won't return
             * to withdrawn state by mistake.
             */
            TRACE ("Client \"%s\" is not mapped, event ignored", c->name);
Olivier Fourdan's avatar
Olivier Fourdan committed
        screen_info = c->screen_info;
        /*
         * ICCCM spec states that a client wishing to switch
         * to WithdrawnState should send a synthetic UnmapNotify
         * with the event field set to root if the client window
         * is already unmapped.
         * Therefore, bypass the ignore_unmap counter and
         * unframe the client.
         */
        if ((ev->event == screen_info->xroot) && (ev->send_event))
        {
            TRACE ("ICCCM UnmapNotify for \"%s\"", c->name);
            list_of_windows = clientListTransientOrModal (c);
            clientPassFocus (screen_info, c, list_of_windows);
            clientUnframe (c, FALSE);
        if (c->ignore_unmap)
        {
            c->ignore_unmap--;
            TRACE ("ignore_unmap for \"%s\" is now %i",
            TRACE ("unmapping \"%s\" as ignore_unmap is %i", c->name, c->ignore_unmap);
            list_of_windows = clientListTransientOrModal (c);
            clientPassFocus (screen_info, c, list_of_windows);
            clientUnframe (c, FALSE);
handleConfigureNotify (DisplayInfo *display_info, XConfigureEvent * ev)
Olivier Fourdan's avatar
Olivier Fourdan committed
{
    TRACE ("entering handleConfigureNotify");
handleConfigureRequest (DisplayInfo *display_info, XConfigureRequestEvent * ev)
Olivier Fourdan's avatar
Olivier Fourdan committed
{
Olivier Fourdan's avatar
Olivier Fourdan committed
    XWindowChanges wc;

    TRACE ("entering handleConfigureRequest");
    TRACE ("ConfigureRequest on window (0x%lx)", ev->window);
Olivier Fourdan's avatar
Olivier Fourdan committed

    wc.x = ev->x;
    wc.y = ev->y;
    wc.width = ev->width;
    wc.height = ev->height;
    wc.sibling = ev->above;
    wc.stack_mode = ev->detail;
    wc.border_width = ev->border_width;

    c = myDisplayGetClientFromWindow (display_info, ev->window, SEARCH_WINDOW);
        /* Some app tend or try to manipulate the wm frame to achieve fullscreen mode */
        c = myDisplayGetClientFromWindow (display_info, ev->window, SEARCH_FRAME);
            TRACE ("client %s (0x%lx) is attempting to manipulate its frame!", c->name, c->window);
            if (ev->value_mask & CWX)
            {
                wc.x += frameLeft (c);
            }
            if (ev->value_mask & CWY)
            {
                wc.y += frameTop (c);
            }
            if (ev->value_mask & CWWidth)
            {
                wc.width -= frameLeft (c) + frameRight (c);
            }
            if (ev->value_mask & CWHeight)
            {
                wc.height -= frameTop (c) + frameBottom (c);
            }
            /* We don't allow changing stacking order by accessing the frame
               window because that would break the layer management in xfwm4
             */
            ev->value_mask &= ~(CWSibling | CWStackMode);
        }
        TRACE ("handleConfigureRequest managed window \"%s\" (0x%lx)", c->name, c->window);
Olivier Fourdan's avatar
Olivier Fourdan committed
        if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_MOVING_RESIZING))
        {
            /* Sorry, but it's not the right time for configure request */
        clientMoveResizeWindow (c, &wc, ev->value_mask);
        TRACE ("unmanaged configure request for win 0x%lx", ev->window);
        XConfigureWindow (display_info->dpy, ev->window, ev->value_mask, &wc);
Olivier Fourdan's avatar
Olivier Fourdan committed
    }
handleEnterNotify (DisplayInfo *display_info, XCrossingEvent * ev)
Olivier Fourdan's avatar
Olivier Fourdan committed
{
    static Time lastresist = (Time) CurrentTime;
Olivier Fourdan's avatar
Olivier Fourdan committed
    ScreenInfo *screen_info;
    Client *c;
    gboolean warp_pointer, need_redraw;
Olivier Fourdan's avatar
Olivier Fourdan committed

    /* See http://rfc-ref.org/RFC-TEXTS/1013/chapter12.html for details */

    TRACE ("entering handleEnterNotify");
Olivier Fourdan's avatar
Olivier Fourdan committed

    if ((ev->mode == NotifyGrab) || (ev->mode == NotifyUngrab)
        || (ev->detail > NotifyNonlinearVirtual))
        /* We're not interested in such notifications */
Olivier Fourdan's avatar
Olivier Fourdan committed

    TRACE ("EnterNotify on window (0x%lx)", ev->window);
Olivier Fourdan's avatar
Olivier Fourdan committed

Olivier Fourdan's avatar
Olivier Fourdan committed
    warp_pointer = FALSE;
    c = myDisplayGetClientFromWindow (display_info, ev->window, SEARCH_FRAME | SEARCH_BUTTON);
    if (c)
Olivier Fourdan's avatar
Olivier Fourdan committed
    {
        screen_info = c->screen_info;
Olivier Fourdan's avatar
Olivier Fourdan committed

        TRACE ("EnterNotify window is \"%s\"", c->name);
        if (!(screen_info->params->click_to_focus) && clientAcceptFocus (c))
Olivier Fourdan's avatar
Olivier Fourdan committed
        {
            if (!(c->type & (WINDOW_DOCK | WINDOW_DESKTOP)))
            {
                if(screen_info->params->focus_delay)
                {
                    clientClearDelayedFocus ();
                    clientAddDelayedFocus (c);
                }
                else
                {
                    clientSetFocus (c->screen_info, c, ev->time, NO_FOCUS_FLAG);
                }
            }
            else
            {
                clientClearDelayedFocus ();
            }
        }
        if (c == clientGetFocus ())
        {
            for (b = 0; b < BUTTON_COUNT; b++)
            {
                if (MYWINDOW_XWINDOW(c->buttons[b]) == ev->window)
                {
                    if (!xfwmPixmapNone(clientGetButtonPixmap(c, b, PRELIGHT)))
                    {
                        c->button_status[b] = BUTTON_STATE_PRELIGHT;
                        need_redraw = TRUE;
                    }
                }
            }
            if (need_redraw)
            {
                frameQueueDraw (c, FALSE);
            }
        }
Olivier Fourdan's avatar
Olivier Fourdan committed

    if (display_info->nb_screens > 1)
    {
        /* Wrap workspace/wrap windows is disabled with multiscreen */
    /* Get the screen structure from the root of the event */
    screen_info = myDisplayGetScreenFromRoot (display_info, ev->root);

    if (!screen_info)
    {
    if (screen_info->workspace_count && screen_info->params->wrap_workspaces
        && screen_info->params->wrap_resistance)
    {
        int msx, msy, maxx, maxy;
        int rx, ry;

        maxx = screen_info->width - 1;
        maxy = screen_info->height - 1;
            if ((ev->time - lastresist) > 250)  /* ms */
            {
                edge_scroll_x = 0;
            }
            else
            {
                edge_scroll_x++;
            }
            warp_pointer = TRUE;
            lastresist = ev->time;
        }
        if ((msy == 0) || (msy == maxy))
        {
            if ((ev->time - lastresist) > 250)  /* ms */
            {
                edge_scroll_y = 0;
            }
            else
            {
                edge_scroll_y++;
            }
            warp_pointer = TRUE;
        if (edge_scroll_x > screen_info->params->wrap_resistance)
        {
                if (workspaceMove (screen_info, 0, -1, NULL, ev->time))
                    rx = 4 * maxx / 5;
                if (workspaceMove (screen_info, 0, 1, NULL, ev->time))
                    rx = -4 * maxx / 5;
        }
        if (edge_scroll_y > screen_info->params->wrap_resistance)
        {
            edge_scroll_y = 0;
                if (workspaceMove (screen_info, -1, 0, NULL, ev->time))
                    ry = 4 * maxy / 5;
                if (workspaceMove (screen_info, 1, 0, NULL, ev->time))
                    ry = -4 * maxy / 5;
            warp_pointer = TRUE;
        }
        if (warp_pointer)
        {
            XWarpPointer (display_info->dpy, None, None, 0, 0, 0, 0, rx, ry);
            XFlush (display_info->dpy);
Olivier Fourdan's avatar
Olivier Fourdan committed
    }
handleLeaveNotify (DisplayInfo *display_info, XCrossingEvent * ev)
Olivier Fourdan's avatar
Olivier Fourdan committed
    gboolean need_redraw;
    TRACE ("entering handleLeaveNotify");
    c = myDisplayGetClientFromWindow (display_info, ev->window, SEARCH_FRAME | SEARCH_BUTTON);
    if (c)
    {
        for (b = 0; b < BUTTON_COUNT; b++)
        {
            if ((c->button_status[b] == BUTTON_STATE_PRELIGHT) || (c->button_status[b] == BUTTON_STATE_PRESSED))
            {
                if (MYWINDOW_XWINDOW(c->buttons[b]) == ev->window)
                {
                    c->button_status[b] = BUTTON_STATE_NORMAL;
            frameQueueDraw (c, FALSE);
        }

        /* No need to process the event any further */
        return EVENT_FILTER_REMOVE;
    }


handleFocusIn (DisplayInfo *display_info, XFocusChangeEvent * ev)
Olivier Fourdan's avatar
Olivier Fourdan committed
{
Olivier Fourdan's avatar
Olivier Fourdan committed
    ScreenInfo *screen_info;
    Client *c, *user_focus, *current_focus;
    /* See http://rfc-ref.org/RFC-TEXTS/1013/chapter12.html for details */
Olivier Fourdan's avatar
Olivier Fourdan committed

    TRACE ("entering handleFocusIn");
    TRACE ("handleFocusIn (0x%lx) mode = %s",
Olivier Fourdan's avatar
Olivier Fourdan committed
                ev->window,
                (ev->mode == NotifyNormal) ?
                "NotifyNormal" :
                (ev->mode == NotifyWhileGrabbed) ?
                "NotifyWhileGrabbed" :
                (ev->mode == NotifyGrab) ?
                "NotifyGrab" :
                (ev->mode == NotifyUngrab) ?
                "NotifyUngrab" :
Olivier Fourdan's avatar
Olivier Fourdan committed
                "(unknown)");
    TRACE ("handleFocusIn (0x%lx) detail = %s",
Olivier Fourdan's avatar
Olivier Fourdan committed
                ev->window,
                (ev->detail == NotifyAncestor) ?
                "NotifyAncestor" :
                (ev->detail == NotifyVirtual) ?
                "NotifyVirtual" :
                (ev->detail == NotifyInferior) ?
                "NotifyInferior" :
                (ev->detail == NotifyNonlinear) ?
                "NotifyNonlinear" :
                (ev->detail == NotifyNonlinearVirtual) ?
                "NotifyNonlinearVirtual" :
                (ev->detail == NotifyPointer) ?
                "NotifyPointer" :
                (ev->detail == NotifyPointerRoot) ?
                "NotifyPointerRoot" :
                (ev->detail == NotifyDetailNone) ?
                "NotifyDetailNone" :
                "(unknown)");
    screen_info = myDisplayGetScreenFromWindow (display_info, ev->window);
    if (!screen_info)
    {
        /* Not for us */
Olivier Fourdan's avatar
Olivier Fourdan committed

    if ((ev->window == screen_info->xroot)
        && ((ev->detail == NotifyDetailNone)
            || ((ev->mode == NotifyNormal) && (ev->detail == NotifyInferior))))
           Handle unexpected focus transition to root (means that an unknown
           window has vanished and the focus is returned to the root).
        clientSetFocus (screen_info, c, getXServerTime (display_info), FOCUS_FORCE);
    if ((ev->mode == NotifyGrab) || (ev->mode == NotifyUngrab))
        /* We're not interested in such notifications */
    c = myDisplayGetClientFromWindow (display_info, ev->window, SEARCH_FRAME | SEARCH_WINDOW);
    user_focus = clientGetUserFocus ();
    TRACE ("FocusIn on window (0x%lx)", ev->window);
    if ((c) && (c != current_focus) && (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_VISIBLE)))
Olivier Fourdan's avatar
Olivier Fourdan committed
    {
        TRACE ("Focus transfered to \"%s\" (0x%lx)", c->name, c->window);
        screen_info = c->screen_info;
        clientUpdateFocus (screen_info, c, FOCUS_SORT);
        if ((user_focus != c) && (user_focus != NULL))
               Focus stealing prevention:
               Some apps tend to focus the window directly. If focus stealing prevention is enabled,
               we revert the user set focus to the window that we think has focus and then set the

               Note that focus stealing prevention is ignored between windows of the same group or
               between windows that have a transient relationship, as some apps tend to play with
               focus with their "own" windows.

            if (screen_info->params->prevent_focus_stealing &&
                !clientSameGroup (c, user_focus) &&
                !clientIsTransientOrModalFor (c, user_focus))
                TRACE ("Setting focus back to \"%s\" (0x%lx)", user_focus->name, user_focus->window);
                clientSetFocus (user_focus->screen_info, user_focus, getXServerTime (display_info), NO_FOCUS_FLAG);
                    TRACE ("Setting WM_STATE_DEMANDS_ATTENTION flag on \"%s\" (0x%lx)", c->name, c->window);
                    FLAG_SET (c->flags, CLIENT_FLAG_DEMANDS_ATTENTION);
                    clientSetNetState (c);
                }
        if (screen_info->params->raise_on_focus)
Olivier Fourdan's avatar
Olivier Fourdan committed
            clientResetDelayedRaise (screen_info);
handleFocusOut (DisplayInfo *display_info, XFocusChangeEvent * ev)
Olivier Fourdan's avatar
Olivier Fourdan committed
{
Olivier Fourdan's avatar
Olivier Fourdan committed
    Client *c;
    /* See http://rfc-ref.org/RFC-TEXTS/1013/chapter12.html for details */

    TRACE ("entering handleFocusOut");
Olivier Fourdan's avatar
Olivier Fourdan committed
    TRACE ("handleFocusOut (0x%lx) mode = %s",
                ev->window,
                (ev->mode == NotifyNormal) ?
                "NotifyNormal" :
                (ev->mode == NotifyWhileGrabbed) ?
                "NotifyWhileGrabbed" :
                "(unknown)");
    TRACE ("handleFocusOut (0x%lx) detail = %s",
                ev->window,
                (ev->detail == NotifyAncestor) ?
                "NotifyAncestor" :
                (ev->detail == NotifyVirtual) ?
                "NotifyVirtual" :
                (ev->detail == NotifyInferior) ?
                "NotifyInferior" :
                (ev->detail == NotifyNonlinear) ?
                "NotifyNonlinear" :
                (ev->detail == NotifyNonlinearVirtual) ?
                "NotifyNonlinearVirtual" :
                (ev->detail == NotifyPointer) ?
                "NotifyPointer" :
                (ev->detail == NotifyPointerRoot) ?
                "NotifyPointerRoot" :
                (ev->detail == NotifyDetailNone) ?
                "NotifyDetailNone" :
                "(unknown)");
    if ((ev->mode == NotifyGrab) || (ev->mode == NotifyUngrab) ||
        (ev->detail == NotifyInferior) || (ev->detail > NotifyNonlinearVirtual))
    {
        /* We're not interested in such notifications */
    if ((ev->mode == NotifyNormal)
        && ((ev->detail == NotifyNonlinear)
            || (ev->detail == NotifyNonlinearVirtual)))
        c = myDisplayGetClientFromWindow (display_info, ev->window, SEARCH_FRAME | SEARCH_WINDOW);
        TRACE ("FocusOut on window (0x%lx)", ev->window);
        {
            TRACE ("focus lost from \"%s\" (0x%lx)", c->name, c->window);
            clientUpdateFocus (c->screen_info, NULL, NO_FOCUS_FLAG);
Olivier Fourdan's avatar
Olivier Fourdan committed
            clientClearDelayedRaise ();
handlePropertyNotify (DisplayInfo *display_info, XPropertyEvent * ev)
Olivier Fourdan's avatar
Olivier Fourdan committed
{
Olivier Fourdan's avatar
Olivier Fourdan committed
    ScreenInfo *screen_info;
    Client *c;
Olivier Fourdan's avatar
Olivier Fourdan committed

    TRACE ("entering handlePropertyNotify");

    c = myDisplayGetClientFromWindow (display_info, ev->window, SEARCH_WINDOW | SEARCH_WIN_USER_TIME);
        status = EVENT_FILTER_REMOVE;
        screen_info = c->screen_info;
        if (ev->atom == XA_WM_NORMAL_HINTS)
        {
            TRACE ("client \"%s\" (0x%lx) has received a XA_WM_NORMAL_HINTS notify", c->name, c->window);
            clientGetWMNormalHints (c, TRUE);
        else if ((ev->atom == XA_WM_NAME) ||
                 (ev->atom == display_info->atoms[NET_WM_NAME]) ||
                 (ev->atom == display_info->atoms[WM_CLIENT_MACHINE]))
            TRACE ("client \"%s\" (0x%lx) has received a XA_WM_NAME/NET_WM_NAME/WM_CLIENT_MACHINE notify", c->name, c->window);
        else if (ev->atom == display_info->atoms[MOTIF_WM_HINTS])
            TRACE ("client \"%s\" (0x%lx) has received a MOTIF_WM_HINTS notify", c->name, c->window);
            clientGetMWMHints (c, TRUE);
        }
        else if (ev->atom == XA_WM_HINTS)
        {
            TRACE ("client \"%s\" (0x%lx) has received a XA_WM_HINTS notify", c->name, c->window);
            c->wmhints = XGetWMHints (display_info->dpy, c->window);
                if (c->wmhints->flags & WindowGroupHint)
                {
                    c->group_leader = c->wmhints->window_group;
                }
                if ((c->wmhints->flags & IconPixmapHint) && (screen_info->params->show_app_icon))
                {
                    clientUpdateIcon (c);
                }
                if (HINTS_ACCEPT_INPUT (c->wmhints))
                {
                    FLAG_SET (c->wm_flags, WM_FLAG_INPUT);
                }
                else
                {
                    FLAG_UNSET (c->wm_flags, WM_FLAG_INPUT);
                }
            clientUpdateUrgency (c);
        else if (ev->atom == display_info->atoms[WM_PROTOCOLS])
            TRACE ("client \"%s\" (0x%lx) has received a WM_PROTOCOLS notify", c->name, c->window);
Olivier Fourdan's avatar
Olivier Fourdan committed
            clientGetWMProtocols (c);
        }
        else if (ev->atom == display_info->atoms[WM_TRANSIENT_FOR])
            TRACE ("client \"%s\" (0x%lx) has received a WM_TRANSIENT_FOR notify", c->name, c->window);
            getTransientFor (display_info, c->screen_info->xroot, c->window, &w);
            if (clientCheckTransientWindow (c, w))
            {
                c->transient_for = w;
            }
        }
        else if (ev->atom == display_info->atoms[WIN_HINTS])
            TRACE ("client \"%s\" (0x%lx) has received a WIN_HINTS notify", c->name, c->window);
            getHint (display_info, c->window, WIN_HINTS, (long *) &c->win_hints);
        else if (ev->atom == display_info->atoms[NET_WM_WINDOW_TYPE])
            TRACE ("client \"%s\" (0x%lx) has received a NET_WM_WINDOW_TYPE notify", c->name, c->window);
            clientGetNetWmType (c);
            frameQueueDraw (c, TRUE);
        else if ((ev->atom == display_info->atoms[NET_WM_STRUT]) ||
                 (ev->atom == display_info->atoms[NET_WM_STRUT_PARTIAL]))
            TRACE ("client \"%s\" (0x%lx) has received a NET_WM_STRUT notify", c->name, c->window);
            if (clientGetNetStruts (c) && FLAG_TEST (c->xfwm_flags, XFWM_FLAG_VISIBLE))
            {
                workspaceUpdateArea (c->screen_info);
            }
        else if (ev->atom == display_info->atoms[WM_COLORMAP_WINDOWS])
            TRACE ("client \"%s\" (0x%lx) has received a WM_COLORMAP_WINDOWS notify", c->name, c->window);
            clientUpdateColormaps (c);
            if (c == clientGetFocus ())
            {
                clientInstallColormaps (c);
            }
        }
        else if (ev->atom == display_info->atoms[NET_WM_USER_TIME])
            TRACE ("client \"%s\" (0x%lx) has received a NET_WM_USER_TIME notify", c->name, c->window);
            if (getHint (display_info, c->window, NET_WM_USER_TIME, (long *) &c->user_time) && (c->user_time != 0))
                myDisplaySetLastUserTime (display_info, c->user_time);
                FLAG_SET (c->flags, CLIENT_FLAG_HAS_USER_TIME);
        else if (ev->atom == display_info->atoms[NET_WM_USER_TIME_WINDOW])
        {
            TRACE ("client \"%s\" (0x%lx) has received a NET_WM_USER_TIME_WINDOW notify", c->name, c->window);
            clientRemoveUserTimeWin (c);
            c->user_time_win = getNetWMUserTimeWindow(display_info, c->window);
            clientAddUserTimeWin (c);
        }
        else if (ev->atom == display_info->atoms[NET_WM_PID])
        {
            TRACE ("client \"%s\" (0x%lx) has received a NET_WM_PID notify", c->name, c->window);
            getHint (display_info, c->window, NET_WM_PID, (long *) &pid);
            c->pid = (GPid) pid;
            TRACE ("Client \"%s\" (0x%lx) updated PID = %i", c->name, c->window, c->pid);
        }
        else if (ev->atom == display_info->atoms[NET_WM_WINDOW_OPACITY])
            TRACE ("client \"%s\" (0x%lx) has received a NET_WM_OPACITY notify", c->name, c->window);
            if (!getOpacity (display_info, c->window, &c->opacity))
                c->opacity =  NET_WM_OPAQUE;
            compositorWindowSetOpacity (display_info, c->frame, c->opacity);
        else if (ev->atom == display_info->atoms[NET_WM_WINDOW_OPACITY_LOCKED])
        {
            TRACE ("client \"%s\" (0x%lx) has received a NET_WM_OPACITY_LOCKED notify", c->name, c->window);
            if (getOpacityLock (display_info, c->window))
            {
                FLAG_SET (c->xfwm_flags, XFWM_FLAG_OPACITY_LOCKED);
            }
            else
            {
                FLAG_UNSET (c->xfwm_flags, XFWM_FLAG_OPACITY_LOCKED);
            }
        else if ((screen_info->params->show_app_icon) &&
                 ((ev->atom == display_info->atoms[NET_WM_ICON]) ||
                  (ev->atom == display_info->atoms[KWM_WIN_ICON])))
        {
            clientUpdateIcon (c);
        }
#ifdef HAVE_STARTUP_NOTIFICATION
        else if (ev->atom == display_info->atoms[NET_STARTUP_ID])
            getWindowStartupId (display_info, c->window, &c->startup_id);
#endif /* HAVE_STARTUP_NOTIFICATION */
#ifdef HAVE_XSYNC
        else if (ev->atom == display_info->atoms[NET_WM_SYNC_REQUEST_COUNTER])
        {
            getXSyncCounter (display_info, c->window, &c->xsync_counter);
            TRACE ("Window 0x%lx has NET_WM_SYNC_REQUEST_COUNTER set to 0x%lx", c->window, c->xsync_counter);
        }
#endif /* HAVE_XSYNC */

    screen_info = myDisplayGetScreenFromWindow (display_info, ev->window);
    if (!screen_info)
    {
Olivier Fourdan's avatar
Olivier Fourdan committed
    }
    if (ev->atom == display_info->atoms[NET_DESKTOP_NAMES])
        TRACE ("root has received a NET_DESKTOP_NAMES notify");
        if (getUTF8StringList (display_info, screen_info->xroot, NET_DESKTOP_NAMES, &names, &items))
            workspaceSetNames (screen_info, names, items);
    else if (ev->atom == display_info->atoms[GNOME_PANEL_DESKTOP_AREA])
Olivier Fourdan's avatar
Olivier Fourdan committed
    {
        TRACE ("root has received a GNOME_PANEL_DESKTOP_AREA notify");
        getGnomeDesktopMargins (display_info, screen_info->xroot, screen_info->gnome_margins);
        workspaceUpdateArea (screen_info);
Olivier Fourdan's avatar
Olivier Fourdan committed
    }
    else if (ev->atom == display_info->atoms[NET_DESKTOP_LAYOUT])
        TRACE ("root has received a NET_DESKTOP_LAYOUT notify");
        getDesktopLayout(display_info, screen_info->xroot, screen_info->workspace_count, &screen_info->desktop_layout);
        placeSidewalks(screen_info, screen_info->params->wrap_workspaces);
handleClientMessage (DisplayInfo *display_info, XClientMessageEvent * ev)
Olivier Fourdan's avatar
Olivier Fourdan committed
{
Olivier Fourdan's avatar
Olivier Fourdan committed
    ScreenInfo *screen_info;
    Client *c;
    gboolean is_transient;
Olivier Fourdan's avatar
Olivier Fourdan committed

    TRACE ("entering handleClientMessage");

    c = myDisplayGetClientFromWindow (display_info, ev->window, SEARCH_WINDOW);
        status = EVENT_FILTER_REMOVE;
        screen_info = c->screen_info;
Olivier Fourdan's avatar
Olivier Fourdan committed
        is_transient = clientIsValidTransientOrModal (c);
        if ((ev->message_type == display_info->atoms[WM_CHANGE_STATE]) && (ev->format == 32) && (ev->data.l[0] == IconicState))
            TRACE ("client \"%s\" (0x%lx) has received a WM_CHANGE_STATE event", c->name, c->window);
            if (!FLAG_TEST (c->flags, CLIENT_FLAG_ICONIFIED))
                clientWithdraw (c, c->win_workspace, TRUE);
        else if ((ev->message_type == display_info->atoms[WIN_STATE]) && (ev->format == 32))
            TRACE ("client \"%s\" (0x%lx) has received a WIN_STATE event", c->name, c->window);
            clientUpdateWinState (c, ev);
        }
        else if ((ev->message_type == display_info->atoms[WIN_LAYER]) && (ev->format == 32))
            TRACE ("client \"%s\" (0x%lx) has received a WIN_LAYER event", c->name, c->window);
Olivier Fourdan's avatar
Olivier Fourdan committed
            if ((ev->data.l[0] != c->win_layer) && !is_transient)
            {
                clientSetLayer (c, ev->data.l[0]);
            }
        }
        else if ((ev->message_type == display_info->atoms[WIN_WORKSPACE]) && (ev->format == 32))
            TRACE ("client \"%s\" (0x%lx) has received a WIN_WORKSPACE event", c->name, c->window);
Olivier Fourdan's avatar
Olivier Fourdan committed
            if ((ev->data.l[0] != c->win_workspace) && !is_transient)
            {
                clientSetWorkspace (c, ev->data.l[0], TRUE);
            }
        }
        else if ((ev->message_type == display_info->atoms[NET_WM_DESKTOP]) && (ev->format == 32))
            TRACE ("client \"%s\" (0x%lx) has received a NET_WM_DESKTOP event", c->name, c->window);
Olivier Fourdan's avatar
Olivier Fourdan committed
            if (!is_transient)
            {
                if (ev->data.l[0] == ALL_WORKSPACES)
                {
                    if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_HAS_STICK) && !FLAG_TEST (c->flags, CLIENT_FLAG_STICKY))
                        frameQueueDraw (c, FALSE);
                    if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_HAS_STICK) && FLAG_TEST (c->flags, CLIENT_FLAG_STICKY))
                        frameQueueDraw (c, FALSE);
                    }
                    if (ev->data.l[0] != c->win_workspace)
                    {
                        clientSetWorkspace (c, ev->data.l[0], TRUE);
                    }
                }
            }
        }
        else if ((ev->message_type == display_info->atoms[NET_CLOSE_WINDOW]) && (ev->format == 32))