Example #1
0
gboolean
myScreenGrabPointer (ScreenInfo *screen_info, gboolean owner_events, unsigned int event_mask, Cursor cursor, guint32 timestamp)
{
    gboolean grab;

    g_return_val_if_fail (screen_info, FALSE);
    TRACE ("entering myScreenGrabPointer");

    grab = TRUE;
    if (screen_info->pointer_grabs == 0)
    {
        grab = (XGrabPointer (myScreenGetXDisplay (screen_info),
                              screen_info->xroot,
                              owner_events, event_mask,
                              GrabModeAsync, GrabModeAsync,
                              screen_info->xroot,
                              cursor,
                              (Time) timestamp) == GrabSuccess);
    }
    screen_info->pointer_grabs++;
    TRACE ("global pointer grabs %i", screen_info->pointer_grabs);

    return grab;
}
Example #2
0
void
clientSetFocus (ScreenInfo *screen_info, Client *c, guint32 timestamp, unsigned short flags)
{
    Client *c2;

    TRACE ("entering");

    c2 = NULL;
    if ((c) && !(flags & FOCUS_IGNORE_MODAL))
    {
        c2 = clientGetModalFor (c);

        if (c2)
        {
            c = c2;
        }
    }
    c2 = ((client_focus != c) ? client_focus : NULL);
    if ((c) && FLAG_TEST (c->xfwm_flags, XFWM_FLAG_VISIBLE))
    {
        TRACE ("setting focus to client \"%s\" (0x%lx) with timestamp %u", c->name, c->window, (unsigned int) timestamp);
        user_focus = c;
        if (FLAG_TEST(c->flags, CLIENT_FLAG_DEMANDS_ATTENTION))
        {
            TRACE ("un-setting WM_STATE_DEMANDS_ATTENTION flag on \"%s\" (0x%lx)", c->name, c->window);
            FLAG_UNSET (c->flags, CLIENT_FLAG_DEMANDS_ATTENTION);
            clientSetNetState (c);
        }
        if ((c == client_focus) && !(flags & FOCUS_FORCE))
        {
            TRACE ("client \"%s\" (0x%lx) is already focused, ignoring request", c->name, c->window);
            return;
        }
        if (!clientAcceptFocus (c))
        {
            TRACE ("SKIP_FOCUS set for client \"%s\" (0x%lx)", c->name, c->window);
            return;
        }
        if (FLAG_TEST (c->wm_flags, WM_FLAG_INPUT) || !(screen_info->params->focus_hint))
        {
            pending_focus = c;
            /*
             * When shaded, the client window is unmapped, so it can not be focused.
             * Instead, we focus the frame that is still mapped.
             */
            if (FLAG_TEST (c->flags, CLIENT_FLAG_SHADED))
            {
                XSetInputFocus (myScreenGetXDisplay (screen_info), c->frame, RevertToPointerRoot, timestamp);
            }
            else
            {
                XSetInputFocus (myScreenGetXDisplay (screen_info), c->window, RevertToPointerRoot, timestamp);
            }
        }
        else if (flags & FOCUS_TRANSITION)
        {
            /*
             * If we are relying only on the client application to take focus, we need to set the focus
             * explicitely on our own fallback window otherwise there is a race condition between the
             * application and the window manager. If the application does not take focus before the
             * the previously focused window is unmapped (when iconifying or closing for example), the focus
             * will be reverted to the root window and focus transition will fail.
             */
            clientFocusNone (screen_info, c2, timestamp);
        }

        if (FLAG_TEST(c->wm_flags, WM_FLAG_TAKEFOCUS))
        {
            pending_focus = c;
            sendClientMessage (c->screen_info, c->window, WM_TAKE_FOCUS, timestamp);
        }
    }
    else
    {
        TRACE ("setting focus to none");

        client_focus = NULL;
        clientFocusNone (screen_info, c2, timestamp);
        clientClearDelayedFocus ();
    }
}
Example #3
0
void
xfwmWindowShow (xfwmWindow * win, int x, int y, int width, int height,
    gboolean refresh)
{
    TRACE ("entering xfwmWindowShow");

    if (!(win->window))
    {
        return;
    }
    if ((width < 1) || (height < 1))
    {
        xfwmWindowHide (win);
        return;
    }
    if (!(win->map))
    {
        XMapWindow (myScreenGetXDisplay (win->screen_info),
                    win->window);
        win->map = TRUE;
    }
    TRACE ("Showing XID 0x%lx", win->window);
    if (((x != win->x) || (y != win->y)) && ((width != win->width)
            || (height != win->height)))
    {
        XMoveResizeWindow (myScreenGetXDisplay (win->screen_info),
                           win->window, x, y,
                           (unsigned int) width,
                           (unsigned int) height);
        win->x = x;
        win->y = y;
        win->width = width;
        win->height = height;
    }
    else if ((x != win->x) || (y != win->y))
    {
        XMoveWindow (myScreenGetXDisplay (win->screen_info),
                     win->window,
                     x, y);
        if (refresh)
        {
            XClearWindow (myScreenGetXDisplay (win->screen_info),
                          win->window);
        }
        win->x = x;
        win->y = y;
    }
    else if ((width != win->width) || (height != win->height))
    {
        XResizeWindow (myScreenGetXDisplay (win->screen_info),
                       win->window,
                       (unsigned int) width,
                       (unsigned int) height);
        win->width = width;
        win->height = height;
    }
    else if (refresh)
    {
        XClearWindow (myScreenGetXDisplay (win->screen_info),
                      win->window);
    }
}
Example #4
0
static void
wireframeDrawXlib (WireFrame *wireframe, int width, int height)
{
    ScreenInfo *screen_info = wireframe->screen_info;

    wireframe->mapped = FALSE;
    XUnmapWindow (myScreenGetXDisplay (screen_info), wireframe->xwindow);
    XMoveResizeWindow (myScreenGetXDisplay (screen_info), wireframe->xwindow,
                       wireframe->x, wireframe->y, width, height);

    wireframe->width = width;
    wireframe->height = height;

    if ((wireframe->width > OUTLINE_WIDTH * 2) && (wireframe->height > OUTLINE_WIDTH * 2))
    {
        XRectangle xrect;
        Region inner_xregion;
        Region outer_xregion;

        inner_xregion = XCreateRegion ();
        outer_xregion = XCreateRegion ();

        xrect.x = 0;
        xrect.y = 0;
        xrect.width = wireframe->width;
        xrect.height = wireframe->height;
        XUnionRectWithRegion (&xrect, outer_xregion, outer_xregion);

        xrect.x += OUTLINE_WIDTH;
        xrect.y += OUTLINE_WIDTH;
        xrect.width -= OUTLINE_WIDTH * 2;
        xrect.height -= OUTLINE_WIDTH * 2;

        XUnionRectWithRegion (&xrect, inner_xregion, inner_xregion);

        XSubtractRegion (outer_xregion, inner_xregion, outer_xregion);

        XShapeCombineRegion (myScreenGetXDisplay (screen_info), wireframe->xwindow, ShapeBounding,
                             0, 0, outer_xregion, ShapeSet);

        XDestroyRegion (outer_xregion);
        XDestroyRegion (inner_xregion);
        XMapWindow (myScreenGetXDisplay (screen_info), wireframe->xwindow);
        wireframe->mapped = TRUE;

        XDrawRectangle (myScreenGetXDisplay (screen_info), wireframe->xwindow,
                        screen_info->box_gc,
                        0, 0, wireframe->width - 1, wireframe->height - 1);

        XDrawRectangle (myScreenGetXDisplay (screen_info), wireframe->xwindow,
                        screen_info->box_gc,
                        OUTLINE_WIDTH - 1, OUTLINE_WIDTH - 1,
                        wireframe->width - 2 * (OUTLINE_WIDTH - 1) - 1,
                        wireframe->height- 2 * (OUTLINE_WIDTH - 1) - 1);
    }
    else
    {
        /* Unset the shape */
        XShapeCombineMask (myScreenGetXDisplay (screen_info), wireframe->xwindow,
                           ShapeBounding, 0, 0, None, ShapeSet);
        XMapWindow (myScreenGetXDisplay (screen_info), wireframe->xwindow);
        wireframe->mapped = TRUE;

        XDrawRectangle (myScreenGetXDisplay (screen_info), wireframe->xwindow,
                        screen_info->box_gc,
                        0, 0, wireframe->width - 1, wireframe->height - 1);
    }
}
Example #5
0
WireFrame *
wireframeCreate (Client *c)
{
    ScreenInfo *screen_info;
    WireFrame *wireframe;
    XSetWindowAttributes attrs;
    XVisualInfo xvisual_info;
    Visual *xvisual;
    int depth;

    g_return_val_if_fail (c != NULL, None);

    TRACE ("client \"%s\" (0x%lx)", c->name, c->window);

    screen_info = c->screen_info;
    wireframe = g_new0 (WireFrame, 1);
    wireframe->screen_info = screen_info;
    wireframe->mapped = FALSE;
    wireframe->width = 0;
    wireframe->height = 0;
    wireframe->cr = NULL;
    wireframe->surface = NULL;
    wireframe->alpha = (compositorIsActive (screen_info) ? 0.5 : 1.0);

    if (compositorIsActive (screen_info) &&
        XMatchVisualInfo (myScreenGetXDisplay (screen_info), screen_info->screen,
                          32, TrueColor, &xvisual_info))
    {
        xvisual = xvisual_info.visual;
        depth = xvisual_info.depth;
        wireframe->xcolormap = XCreateColormap (myScreenGetXDisplay (screen_info),
                                                screen_info->xroot,
                                                xvisual, AllocNone);
    }
    else
    {
        xvisual = screen_info->visual;
        depth = screen_info->depth;
        wireframe->xcolormap = screen_info->cmap;
    }

    attrs.override_redirect = True;
    attrs.colormap = wireframe->xcolormap;
    attrs.background_pixel = BlackPixel (myScreenGetXDisplay (screen_info),
                                         screen_info->screen);
    attrs.border_pixel = BlackPixel (myScreenGetXDisplay (screen_info),
                                     screen_info->screen);
    wireframe->xwindow = XCreateWindow (myScreenGetXDisplay (screen_info), screen_info->xroot,
                                        frameExtentX (c), frameExtentY (c),
                                        frameExtentWidth (c), frameExtentHeight (c),
                                        0, depth, InputOutput, xvisual,
                                        CWOverrideRedirect | CWColormap | CWBackPixel | CWBorderPixel,
                                        &attrs);

    if (compositorIsActive (screen_info))
    {
        /* Cairo */
        wireframeInitColor (wireframe);
        wireframe->surface = cairo_xlib_surface_create (myScreenGetXDisplay (screen_info),
                                                        wireframe->xwindow, xvisual,
                                                        frameExtentWidth (c), frameExtentHeight (c));
        wireframe->cr = cairo_create (wireframe->surface);
        cairo_set_line_width (wireframe->cr, OUTLINE_WIDTH_CAIRO);
        cairo_set_line_join (wireframe->cr, CAIRO_LINE_JOIN_MITER);
    }

    wireframeUpdate (c, wireframe);

    return (wireframe);
}
Example #6
0
void
workspaceSwitch (ScreenInfo *screen_info, gint new_ws, Client * c2, gboolean update_focus, guint32 timestamp)
{
    DisplayInfo *display_info;
    Client *c, *new_focus;
    Client *previous;
    GList *list;
    Window dr, window;
    gint rx, ry, wx, wy;
    unsigned int mask;

    g_return_if_fail (screen_info != NULL);

    TRACE ("entering workspaceSwitch");

    display_info = screen_info->display_info;
    if ((new_ws == (gint) screen_info->current_ws) && (screen_info->params->toggle_workspaces))
    {
        new_ws = (gint) screen_info->previous_ws;
    }

    if (new_ws == (gint) screen_info->current_ws)
    {
        return;
    }

    if (screen_info->params->wrap_cycle)
    {
        if (new_ws > (gint) screen_info->workspace_count - 1)
        {
            new_ws = 0;
        }
        if (new_ws < 0)
        {
            new_ws = (gint) screen_info->workspace_count - 1;
        }
    }
    else if ((new_ws > (gint) screen_info->workspace_count - 1) || (new_ws < 0))
    {
        return;
    }

    screen_info->previous_ws = screen_info->current_ws;
    screen_info->current_ws = new_ws;

    new_focus = NULL;
    previous  = NULL;
    c = clientGetFocus ();

    if (c2)
    {
        clientSetWorkspace (c2, new_ws, FALSE);
    }

    if (c)
    {
        if (c->type & WINDOW_REGULAR_FOCUSABLE)
        {
            previous = c;
        }
        if (c2 == c)
        {
            new_focus = c2;
        }
    }

    /* First pass: Show, from top to bottom */
    for (list = g_list_last(screen_info->windows_stack); list; list = g_list_previous (list))
    {
        c = (Client *) list->data;
        if (FLAG_TEST (c->flags, CLIENT_FLAG_STICKY))
        {
            clientSetWorkspace (c, new_ws, TRUE);
        }
        else if (new_ws == (gint) c->win_workspace)
        {
            if (!FLAG_TEST (c->flags, CLIENT_FLAG_ICONIFIED) && !FLAG_TEST (c->xfwm_flags, XFWM_FLAG_VISIBLE))
            {
                if (!clientIsTransientOrModal (c) || !clientTransientOrModalHasAncestor (c, new_ws))
                {
                    clientShow (c, FALSE);
                }
            }
        }
    }

    /* Second pass: Hide from bottom to top */
    for (list = screen_info->windows_stack; list; list = g_list_next (list))
    {
        c = (Client *) list->data;

        if (new_ws != (gint) c->win_workspace)
        {
            if (c == previous)
            {
                FLAG_SET (previous->xfwm_flags, XFWM_FLAG_FOCUS);
                clientSetFocus (screen_info, NULL, timestamp, FOCUS_IGNORE_MODAL);
            }
            if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_VISIBLE) && !FLAG_TEST (c->flags, CLIENT_FLAG_STICKY))
            {
                if (!clientIsTransientOrModal (c) || !clientTransientOrModalHasAncestor (c, new_ws))
                {
                    clientWithdraw (c, new_ws, FALSE);
                }
            }
        }
    }

    /* Third pass: Check for focus, from top to bottom */
    for (list = g_list_last(screen_info->windows_stack); list; list = g_list_previous (list))
    {
        c = (Client *) list->data;

        if (FLAG_TEST (c->flags, CLIENT_FLAG_STICKY))
        {
            if ((!new_focus) && (c == previous) && clientSelectMask (c, NULL, 0, WINDOW_REGULAR_FOCUSABLE))
            {
                new_focus = c;
            }
            FLAG_UNSET (c->xfwm_flags, XFWM_FLAG_FOCUS);
        }
        else if (new_ws == (gint) c->win_workspace)
        {
            if ((!new_focus) && FLAG_TEST (c->xfwm_flags, XFWM_FLAG_FOCUS))
            {
                new_focus = c;
            }
            FLAG_UNSET (c->xfwm_flags, XFWM_FLAG_FOCUS);
        }
    }

    setNetCurrentDesktop (display_info, screen_info->xroot, new_ws);
    if (!(screen_info->params->click_to_focus))
    {
        if (!(c2) && (XQueryPointer (myScreenGetXDisplay (screen_info), screen_info->xroot, &dr, &window, &rx, &ry, &wx, &wy, &mask)))
        {
            c = clientAtPosition (screen_info, rx, ry, NULL);
            if (c)
            {
                new_focus = c;
            }
        }
    }

    if (update_focus)
    {
        if (new_focus)
        {
            if ((screen_info->params->click_to_focus) && (screen_info->params->raise_on_click))
            {
                if (!(screen_info->params->raise_on_focus) && !clientIsTopMost (new_focus))
                {
                    clientRaise (new_focus, None);
                }
            }
            clientSetFocus (screen_info, new_focus, timestamp, FOCUS_SORT);
        }
        else
        {
            clientFocusTop (screen_info, WIN_LAYER_FULLSCREEN, timestamp);
        }
    }
}