Skip to content
Snippets Groups Projects
events.c 63.8 KiB
Newer Older
        if ((ev->event == screen_info->xroot) && (ev->send_event))
        {
            TRACE ("ICCCM UnmapNotify for \"%s\"", c->name);
            clientUnframe (c, FALSE);
            return;
        }
        if (c->ignore_unmap)
        {
            c->ignore_unmap--;
            TRACE ("ignore_unmaps for \"%s\" is  now %i", 
                 c->name, c->ignore_unmap);
        }
        else
        {
            clientUnframe (c, FALSE);
static void
handleConfigureNotify (DisplayInfo *display_info, XConfigureEvent * ev)
Olivier Fourdan's avatar
Olivier Fourdan committed
{
    ScreenInfo *screen_info;

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

    screen_info = myDisplayGetScreenFromWindow (display_info, ev->window);
    if (!screen_info)
    {
        return;
    }
    
    if (ev->window == screen_info->xroot)
Olivier Fourdan's avatar
Olivier Fourdan committed
    {
        TRACE ("ConfigureNotify on the screen_info->xroot win (0x%lx)", ev->window);
Olivier Fourdan's avatar
Olivier Fourdan committed
#ifdef HAVE_RANDR
        XRRUpdateConfiguration (ev);
#else
        screen_info->xscreen->width   = ev->width;
        screen_info->xscreen->height  = ev->height;
Olivier Fourdan's avatar
Olivier Fourdan committed
#endif
        placeSidewalks (screen_info, screen_info->params->wrap_workspaces);
        clientScreenResize (screen_info);
static void
handleConfigureRequest (DisplayInfo *display_info, XConfigureRequestEvent * ev)
Olivier Fourdan's avatar
Olivier Fourdan committed
{
Olivier Fourdan's avatar
Olivier Fourdan committed
    XWindowChanges wc;
Olivier Fourdan's avatar
Olivier Fourdan committed
    XEvent otherEvent;
Olivier Fourdan's avatar
Olivier Fourdan committed

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

Olivier Fourdan's avatar
Olivier Fourdan committed
    /* Compress events - logic taken from kwin */
    while (XCheckTypedWindowEvent (display_info->dpy, ev->window, ConfigureRequest, &otherEvent))
Olivier Fourdan's avatar
Olivier Fourdan committed
    {
        if (otherEvent.xconfigurerequest.value_mask == ev->value_mask)
        {
            ev = &otherEvent.xconfigurerequest;
        }
        else
        {
            XPutBackEvent (display_info->dpy, &otherEvent);
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, WINDOW);
        /* Some app tend or try to manipulate the wm frame to achieve fullscreen mode */
        c = myDisplayGetClientFromWindow (display_info, ev->window, 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);
        }
        gboolean constrained = FALSE;
        ScreenInfo *screen_info = c->screen_info;
        TRACE ("handleConfigureRequest managed window \"%s\" (0x%lx)", c->name, c->window);
        if (FLAG_TEST (c->flags, CLIENT_FLAG_MOVING_RESIZING))
        {
            /* Sorry, but it's not the right time for configure request */
            return;
        }
        if (c->type == WINDOW_DESKTOP)
        {
            /* Ignore stacking request for DESKTOP windows */
            ev->value_mask &= ~(CWSibling | CWStackMode);
        }
        clientCoordGravitate (c, APPLY, &wc.x, &wc.y);
        if (FLAG_TEST (c->flags, CLIENT_FLAG_FULLSCREEN))
Jasper Huijsmans's avatar
 
Jasper Huijsmans committed
        {
Jasper Huijsmans's avatar
 
Jasper Huijsmans committed
            int cx, cy;

            /* size request from fullscreen windows get fullscreen */
Jasper Huijsmans's avatar
 
Jasper Huijsmans committed
            cx = frameX (c) + (frameWidth (c) / 2);
            cy = frameY (c) + (frameHeight (c) / 2);

            monitor_nbr = gdk_screen_get_monitor_at_point (screen_info->gscr, cx, cy);
            gdk_screen_get_monitor_geometry (screen_info->gscr, monitor_nbr, &rect);

            wc.x = rect.x;
            wc.y = rect.y;
            wc.width = rect.width;
            wc.height = rect.height;
Jasper Huijsmans's avatar
 
Jasper Huijsmans committed

            ev->value_mask |= (CWX | CWY | CWWidth | CWHeight);
        }
        /* Clean up buggy requests that set all flags */
        if ((ev->value_mask & CWX) && (wc.x == c->x))
        {
            ev->value_mask &= ~CWX;
        }
        if ((ev->value_mask & CWY) && (wc.y == c->y))
        {
            ev->value_mask &= ~CWY;
        }
        if ((ev->value_mask & CWWidth) && (wc.width == c->width))
        {
            ev->value_mask &= ~CWWidth;
        }
        if ((ev->value_mask & CWHeight) && (wc.height == c->height))
        {
            ev->value_mask &= ~CWHeight;
        }
        /* Still a move/resize after cleanup? */
        if (ev->value_mask & (CWX | CWY | CWWidth | CWHeight))
        {
            if (FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED))
            {
                clientRemoveMaximizeFlag (c);
            }
            constrained = TRUE;
        }
        if (ev->value_mask & CWStackMode)
        {
        /* Let's say that if the client performs a XRaiseWindow, we show the window if hidden */
        if ((ev->value_mask & CWStackMode) && (wc.stack_mode == Above))
        {
            if ((c->win_workspace == screen_info->current_ws) || 
                (FLAG_TEST (c->flags, CLIENT_FLAG_STICKY)))
                if (FLAG_TEST (c->flags, CLIENT_FLAG_HIDDEN))
        clientConfigure (c, &wc, ev->value_mask, (constrained ? CFG_CONSTRAINED : 0) | CFG_REQUEST);
        TRACE ("unmanaged configure request for win 0x%lx", ev->window);
        XConfigureWindow (display_info->dpy, ev->window, ev->value_mask, &wc);
static void
handleEnterNotify (DisplayInfo *display_info, XCrossingEvent * ev)
Olivier Fourdan's avatar
Olivier Fourdan committed
{
Olivier Fourdan's avatar
Olivier Fourdan committed

    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 */
        return;
Olivier Fourdan's avatar
Olivier Fourdan committed

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

    c = myDisplayGetClientFromWindow (display_info, ev->window, FRAME);
    if (c)
Olivier Fourdan's avatar
Olivier Fourdan committed
    {
        ScreenInfo *screen_info;
        
        screen_info = c->screen_info;
        
        if (!(screen_info->params->click_to_focus) && clientAcceptFocus (c))
            TRACE ("EnterNotify window is \"%s\"", c->name);
            if (!(c->type & (WINDOW_DOCK | WINDOW_DESKTOP)))
                clientSetFocus (c->screen_info, c, ev->time, FOCUS_FORCE);
                if (!(screen_info->params->raise_on_click))
                {
                    clientPassGrabButton1 (c);
                }
static void
handleLeaveNotify (DisplayInfo *display_info, XCrossingEvent * ev)
    ScreenInfo *screen_info;

    TRACE ("entering handleLeaveNotify");
    if ((ev->mode == NotifyGrab) || (ev->mode == NotifyUngrab)
        || (ev->detail > NotifyNonlinearVirtual))
    {
        /* We're not interested in such notifications */
        return;
    }

    screen_info = myDisplayGetScreenFromRoot (display_info, ev->root);
    if (!screen_info)
    {
        return;
    }
    
    if ((ev->window == MYWINDOW_XWINDOW (screen_info->sidewalk[0])) || 
        (ev->window == MYWINDOW_XWINDOW (screen_info->sidewalk[1])))
static void
handleFocusIn (DisplayInfo *display_info, XFocusChangeEvent * ev)
Olivier Fourdan's avatar
Olivier Fourdan committed
{
    ScreenInfo *screen_info;
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" :
                "(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 && (ev->window == screen_info->xroot) && (ev->mode == NotifyNormal) && 
        /* Handle focus transition to root (means that an unknown
           window has vanished and the focus is returned to the root
            clientSetFocus (c->screen_info, c, GDK_CURRENT_TIME, FOCUS_FORCE);
    
    if ((ev->mode == NotifyGrab) || (ev->mode == NotifyUngrab) ||
        /* We're not interested in such notifications */
        return;
Olivier Fourdan's avatar
Olivier Fourdan committed

    c = myDisplayGetClientFromWindow (display_info, ev->window, WINDOW);
    TRACE ("FocusIn on window (0x%lx)", ev->window);
Olivier Fourdan's avatar
Olivier Fourdan committed
    {
        TRACE ("focus set to \"%s\" (0x%lx)", c->name, c->window);
        screen_info = screen_info;
        clientUpdateFocus (screen_info, c, FOCUS_SORT);
        if (screen_info->params->raise_on_focus && !screen_info->params->click_to_focus)
            reset_timeout (screen_info);
static void
handleFocusOut (DisplayInfo *display_info, XFocusChangeEvent * ev)
Olivier Fourdan's avatar
Olivier Fourdan committed
{
    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 == NotifyNormal)
        && ((ev->detail == NotifyNonlinear) 
            || (ev->detail == NotifyNonlinearVirtual)))
        c = myDisplayGetClientFromWindow (display_info, ev->window, 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);
            /* Clear timeout */
            clear_timeout ();
        }
static void
handlePropertyNotify (DisplayInfo *display_info, XPropertyEvent * ev)
Olivier Fourdan's avatar
Olivier Fourdan committed
{
    ScreenInfo *screen_info;
Olivier Fourdan's avatar
Olivier Fourdan committed

    TRACE ("entering handlePropertyNotify");

    c = myDisplayGetClientFromWindow (display_info, ev->window, WINDOW);
        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 == net_wm_name))
        {
            TRACE ("client \"%s\" (0x%lx) has received a XA_WM_NAME notify" c->name, c->window);
            getWindowName (display_info->dpy, c->window, &c->name);
            FLAG_SET (c->flags, CLIENT_FLAG_NAME_CHANGED);
            frameDraw (c, TRUE, FALSE);
        }
        else if (ev->atom == 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;
                }
Olivier Fourdan's avatar
Olivier Fourdan committed
        else if (ev->atom == 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 == win_hints)
        {
            TRACE ("client \"%s\" (0x%lx) has received a win_hints notify", c->name, c->window);
            getHint (display_info->dpy, c->window, win_hints, &c->win_hints);
        }
        else if (ev->atom == net_wm_window_type)
        {
            TRACE ("client \"%s\" (0x%lx) has received a net_wm_window_type notify", c->name, c->window);
            clientGetNetWmType (c);
            frameDraw (c, TRUE, FALSE);
        }
Olivier Fourdan's avatar
Olivier Fourdan committed
        else if ((ev->atom == net_wm_strut) || (ev->atom == net_wm_strut_partial))
            TRACE ("client \"%s\" (0x%lx) has received a net_wm_strut notify", c->name, c->window);
            clientGetNetStruts (c);
        }
        else if (ev->atom == wm_colormap_windows)
        {
            clientUpdateColormaps (c);
            if (c == clientGetFocus ())
            {
                clientInstallColormaps (c);
            }
        }
            if (getNetWMUserTime (display_info->dpy, c->window, &c->user_time))
                FLAG_SET (c->flags, CLIENT_FLAG_HAS_USER_TIME);
#ifdef HAVE_STARTUP_NOTIFICATION
        else if (ev->atom == net_startup_id)
        {
            if (c->startup_id)
            {
                free (c->startup_id);
                c->startup_id = NULL;
            }
            getWindowStartupId (display_info->dpy, c->window, &c->startup_id);
        return;
    }
    
    screen_info = myDisplayGetScreenFromWindow (display_info, ev->window);
    if (!screen_info)
    {
        return;
Olivier Fourdan's avatar
Olivier Fourdan committed
    }

    if (ev->atom == net_desktop_names)
    {
        TRACE ("root has received a net_desktop_names notify");
        if (getUTF8String (display_info->dpy, screen_info->xroot, net_desktop_names, &names, &length))
            workspaceSetNames (screen_info, names, length);
    else if (ev->atom == gnome_panel_desktop_area)
Olivier Fourdan's avatar
Olivier Fourdan committed
    {
        TRACE ("root has received a gnome_panel_desktop_area notify");
        getGnomeDesktopMargins (display_info->dpy, screen_info->screen, screen_info->gnome_margins);
        workspaceUpdateArea (screen_info);
static void
handleClientMessage (DisplayInfo *display_info, XClientMessageEvent * ev)
Olivier Fourdan's avatar
Olivier Fourdan committed
{
    ScreenInfo *screen_info = NULL;
Olivier Fourdan's avatar
Olivier Fourdan committed

    TRACE ("entering handleClientMessage");

Olivier Fourdan's avatar
Olivier Fourdan committed
    /* Don't get surprised with the multiple "if (!clientIsTransientOrModal(c))" tests
       xfwm4 really treats transient differently
     */

    c = myDisplayGetClientFromWindow (display_info, ev->window, WINDOW);
        screen_info = c->screen_info;
        
        if ((ev->message_type == 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_HIDDEN) && 
                 CLIENT_CAN_HIDE_WINDOW (c))
            {
                clientHide (c, c->win_workspace, TRUE);
            }
        }
        else if ((ev->message_type == 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 == 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) && !clientIsTransientOrModal (c))
            {
                clientSetLayer (c, ev->data.l[0]);
                clientSetNetState (c);
            }
        }
        else if ((ev->message_type == 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) && !clientIsTransientOrModal (c))
            {
                clientSetWorkspace (c, ev->data.l[0], TRUE);
            }
        }
        else if ((ev->message_type == 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 (!clientIsTransientOrModal (c))
            {
                if (ev->data.l[0] == ALL_WORKSPACES)
                {
                    if (FLAG_TEST_AND_NOT (c->flags, CLIENT_FLAG_HAS_STICK,
                            CLIENT_FLAG_STICKY))
                    {
                        clientStick (c, TRUE);
                        frameDraw (c, FALSE, FALSE);
                    }
                }
                else
                {
                    if (FLAG_TEST_ALL (c->flags,
                            CLIENT_FLAG_HAS_STICK | CLIENT_FLAG_STICKY))
                    {
                        clientUnstick (c, TRUE);
                        frameDraw (c, FALSE, FALSE);
                    }
                    if (ev->data.l[0] != c->win_workspace)
                    {
                        clientSetWorkspace (c, ev->data.l[0], TRUE);
                    }
                }
            }
        }
        else if ((ev->message_type == net_close_window) && (ev->format == 32))
        {
            TRACE ("client \"%s\" (0x%lx) has received a net_close_window event", c->name, c->window);
            clientClose (c);
        }
        else if ((ev->message_type == net_wm_state) && (ev->format == 32))
        {
            TRACE ("client \"%s\" (0x%lx) has received a net_wm_state event", c->name, c->window);
            clientUpdateNetState (c, ev);
        }
        else if ((ev->message_type == net_wm_moveresize) && (ev->format == 32))
            TRACE ("client \"%s\" (0x%lx) has received a net_wm_moveresize event", c->name, c->window);
            g_message (_("%s: Operation not supported (yet)\n"), g_get_prgname ());
        else if ((ev->message_type == net_active_window) && (ev->format == 32))
            TRACE ("client \"%s\" (0x%lx) has received a net_active_window event", c->name, c->window);
            clientSetWorkspace (c, screen_info->current_ws, TRUE);
            clientShow (c, TRUE);
            clientRaise (c);
            clientSetFocus (screen_info, c, GDK_CURRENT_TIME, NO_FOCUS_FLAG);
            clientPassGrabButton1 (c);
        screen_info = myDisplayGetScreenFromWindow (display_info, ev->window);
        if (!screen_info)
        {
            return;
        }
        
        if (((ev->message_type == win_workspace) || (ev->message_type == net_current_desktop)) && (ev->format == 32))
            TRACE ("root has received a win_workspace or a net_current_desktop event");
            if (ev->data.l[0] != screen_info->current_ws)
                workspaceSwitch (screen_info, ev->data.l[0], NULL);
        else if (((ev->message_type == win_workspace_count) || (ev->message_type == net_number_of_desktops)) && (ev->format == 32))
        {
            TRACE ("root has received a win_workspace_count event");
            if (ev->data.l[0] != screen_info->workspace_count)
                workspaceSetCount (screen_info, ev->data.l[0]);
        else if ((ev->message_type == net_system_tray_manager) && (ev->data.l[1] == screen_info->net_system_tray_selection)  && (ev->format == 32))
        {
            TRACE ("root has received a net_system_tray_manager event");
            screen_info->systray = getSystrayWindow (display_info->dpy,
                                            screen_info->net_system_tray_selection);
        else if ((ev->message_type == net_showing_desktop) && (ev->format == 32))
        {
            TRACE ("root has received a net_showing_desktop event");
            clientToggleShowDesktop (screen_info, ev->data.l[0]);
            setHint (display_info->dpy, screen_info->xroot, net_showing_desktop, ev->data.l[0]);
            TRACE ("unidentified client message for window 0x%lx", ev->window);
static void
handleShape (DisplayInfo *display_info, XShapeEvent * ev)
Olivier Fourdan's avatar
Olivier Fourdan committed
{
Olivier Fourdan's avatar
Olivier Fourdan committed

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

    c = myDisplayGetClientFromWindow (display_info, ev->window, WINDOW);
Olivier Fourdan's avatar
Olivier Fourdan committed
    {
        frameDraw (c, FALSE, TRUE);
static void
handleColormapNotify (DisplayInfo *display_info, XColormapEvent * ev)
    TRACE ("entering handleColormapNotify");
    c = myDisplayGetClientFromWindow (display_info, ev->window, WINDOW);
    if ((c) && (ev->window == c->window) && (ev->new))
        if (c == clientGetFocus ())
        {
            clientInstallColormaps (c);
        }
handleEvent (DisplayInfo *display_info, XEvent * ev)
Olivier Fourdan's avatar
Olivier Fourdan committed
{
    TRACE ("entering handleEvent");
Olivier Fourdan's avatar
Olivier Fourdan committed

Olivier Fourdan's avatar
Olivier Fourdan committed
    switch (ev->type)
    {
            handleMotionNotify (display_info, (XMotionEvent *) ev);
            handleKeyPress (display_info, (XKeyEvent *) ev);
            handleButtonPress (display_info, (XButtonEvent *) ev);
            handleButtonRelease (display_info, (XButtonEvent *) ev);
            handleDestroyNotify (display_info, (XDestroyWindowEvent *) ev);
            handleUnmapNotify (display_info, (XUnmapEvent *) ev);
            handleMapRequest (display_info, (XMapRequestEvent *) ev);
Olivier Fourdan's avatar
Olivier Fourdan committed
        case MapNotify:
            handleMapNotify (display_info, (XMapEvent *) ev);
Olivier Fourdan's avatar
Olivier Fourdan committed
            break;
Olivier Fourdan's avatar
Olivier Fourdan committed
        case ConfigureNotify:
            handleConfigureNotify (display_info, (XConfigureEvent *) ev);
Olivier Fourdan's avatar
Olivier Fourdan committed
            break;
            handleConfigureRequest (display_info, (XConfigureRequestEvent *) ev);
            handleEnterNotify (display_info, (XCrossingEvent *) ev);
            handleLeaveNotify (display_info, (XCrossingEvent *) ev);
            handleFocusIn (display_info, (XFocusChangeEvent *) ev);
            handleFocusOut (display_info, (XFocusChangeEvent *) ev);
            handlePropertyNotify (display_info, (XPropertyEvent *) ev);
            handleClientMessage (display_info, (XClientMessageEvent *) ev);
            handleColormapNotify (display_info, (XColormapEvent *) ev);
            if (display_info->shape && (ev->type == display_info->shape_event))
                handleShape (display_info, (XShapeEvent *) ev);
    if (!gdk_events_pending () && !XPending (display_info->dpy))
            reloadSettings (display_info, UPDATE_ALL);
xfwm4_event_filter (XEvent * xevent, gpointer data)
Olivier Fourdan's avatar
Olivier Fourdan committed
{
    DisplayInfo *display_info = (DisplayInfo *) data;
    g_assert (display_info);
    TRACE ("entering xfwm4_event_filter");
    handleEvent (display_info, xevent);
    TRACE ("leaving xfwm4_event_filter");
Olivier Fourdan's avatar
Olivier Fourdan committed
    return XEV_FILTER_STOP;
}

Olivier Fourdan's avatar
Olivier Fourdan committed

menu_callback (Menu * menu, MenuOp op, Window client_xwindow, gpointer menu_data, gpointer item_data)
Olivier Fourdan's avatar
Olivier Fourdan committed
{
Olivier Fourdan's avatar
Olivier Fourdan committed
    Client *c = NULL;
    TRACE ("entering menu_callback");
    if (!xfwmWindowDeleted(&menu_event_window))
        xfwmWindowDelete (&menu_event_window);
Olivier Fourdan's avatar
Olivier Fourdan committed
    {
        c = (Client *) menu_data;
        if (!c)
        {
            menu_free (menu);
            return;
        }
        c->button_pressed[MENU_BUTTON] = FALSE;
Olivier Fourdan's avatar
Olivier Fourdan committed
    }
Olivier Fourdan's avatar
Olivier Fourdan committed
    switch (op)
    {
        case MENU_OP_QUIT:
            gtk_main_quit ();
            break;
        case MENU_OP_MAXIMIZE:
        case MENU_OP_UNMAXIMIZE:
            if (CLIENT_CAN_MAXIMIZE_WINDOW (c))
            {
                clientToggleMaximized (c, WIN_STATE_MAXIMIZED);
            }
            break;
        case MENU_OP_MINIMIZE:
            if (CLIENT_CAN_HIDE_WINDOW (c))
            {
                clientHide (c, c->win_workspace, TRUE);
            }
            frameDraw (c, FALSE, FALSE);
            break;
        case MENU_OP_MINIMIZE_ALL:
            clientHideAll (c, c->win_workspace);
            frameDraw (c, FALSE, FALSE);
            break;
        case MENU_OP_UNMINIMIZE:
            clientShow (c, TRUE);
            break;
        case MENU_OP_SHADE:
        case MENU_OP_UNSHADE:
            clientToggleShaded (c);
            break;
        case MENU_OP_STICK:
        case MENU_OP_UNSTICK:
            clientToggleSticky (c, TRUE);
            frameDraw (c, FALSE, FALSE);
            break;
Olivier Fourdan's avatar
Olivier Fourdan committed
        case MENU_OP_WORKSPACES:
            clientSetWorkspace (c, GPOINTER_TO_INT (item_data), TRUE);
            frameDraw (c, FALSE, FALSE);
            break;
        case MENU_OP_DELETE:
            frameDraw (c, FALSE, FALSE);
            clientClose (c);
            break;
        case MENU_OP_CONTEXT_HELP:
            clientEnterContextMenuState (c);
            frameDraw (c, FALSE, FALSE);
            break;
        case MENU_OP_ABOVE:
        case MENU_OP_NORMAL:
        default:
            frameDraw (c, FALSE, FALSE);
            break;
    xfwmWindowInit (&menu_event_window);
static gboolean
show_popup_cb (GtkWidget * widget, GdkEventButton * ev, gpointer data)
Olivier Fourdan's avatar
Olivier Fourdan committed
{
    ScreenInfo *screen_info = NULL;
    DisplayInfo *display_info = NULL;
    Client *c = (Client *) data;
    TRACE ("entering show_popup_cb");

    if ((c) && ((ev->button == 1) || (ev->button == 3)))
        c->button_pressed[MENU_BUTTON] = TRUE;
        frameDraw (c, FALSE, FALSE);
        y = c->y;
Olivier Fourdan's avatar
Olivier Fourdan committed
        ops = MENU_OP_DELETE | MENU_OP_MINIMIZE_ALL | MENU_OP_WORKSPACES;
        if (!FLAG_TEST (c->flags, CLIENT_FLAG_HAS_CLOSE))
        if (FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED))
        {
            ops |= MENU_OP_UNMAXIMIZE;
            if (!CLIENT_CAN_MAXIMIZE_WINDOW (c))
            {
                insensitive |= MENU_OP_UNMAXIMIZE;
            }
        }
        else
        {
            ops |= MENU_OP_MAXIMIZE;
            if (!CLIENT_CAN_MAXIMIZE_WINDOW (c))
            {
                insensitive |= MENU_OP_MAXIMIZE;
            }
        }

        if (FLAG_TEST (c->flags, CLIENT_FLAG_HIDDEN))
        {
            ops |= MENU_OP_UNMINIMIZE;
            if (!CLIENT_CAN_HIDE_WINDOW (c))
            {
                insensitive |= MENU_OP_UNMINIMIZE;
            }
        }
        else
        {
            ops |= MENU_OP_MINIMIZE;
            if (!CLIENT_CAN_HIDE_WINDOW (c))
            {
                insensitive |= MENU_OP_MINIMIZE;
            }
        }

        if (FLAG_TEST (c->flags, CLIENT_FLAG_SHADED))
        {
            ops |= MENU_OP_UNSHADE;
        }
        else
        {
            ops |= MENU_OP_SHADE;
        }

        if (FLAG_TEST (c->flags, CLIENT_FLAG_STICKY))
            if (!CLIENT_CAN_STICK_WINDOW(c))
            {
                insensitive |= MENU_OP_UNSTICK;
            }
        }
        else
        {
            ops |= MENU_OP_STICK;
            if (!CLIENT_CAN_STICK_WINDOW(c))
    
        /* KDE extension */
        clientGetWMProtocols(c);
        if (FLAG_TEST (c->wm_flags, WM_FLAG_CONTEXT_HELP))
        {
            ops |= MENU_OP_CONTEXT_HELP;
        }
        if (FLAG_TEST(c->flags, CLIENT_FLAG_ABOVE))
                FLAG_TEST (c->flags, CLIENT_FLAG_BELOW | CLIENT_FLAG_FULLSCREEN))
                FLAG_TEST (c->flags, CLIENT_FLAG_BELOW | CLIENT_FLAG_FULLSCREEN))
Olivier Fourdan's avatar
Olivier Fourdan committed
        if (clientIsTransientOrModal (c)
            || !FLAG_TEST (c->flags, CLIENT_FLAG_HAS_STICK)
            || FLAG_TEST (c->flags, CLIENT_FLAG_STICKY))
Olivier Fourdan's avatar
Olivier Fourdan committed
        {
            insensitive |= MENU_OP_WORKSPACES;
        }
    
    /* c is not null here */
    screen_info = c->screen_info;
    display_info = screen_info->display_info;
    
    if (screen_info->button_handler_id)
        g_signal_handler_disconnect (GTK_OBJECT (myScreenGetGtkWidget (screen_info)), screen_info->button_handler_id);
    screen_info->button_handler_id = g_signal_connect (GTK_OBJECT (myScreenGetGtkWidget (screen_info)),
                                              "button_press_event", GTK_SIGNAL_FUNC (show_popup_cb), (gpointer) NULL);
    if (!xfwmWindowDeleted(&menu_event_window))