Example #1
0
static void
clientCycleFocusAndRaise (Client *c)
{
    ScreenInfo *screen_info;
    DisplayInfo *display_info;
    Client *sibling;

    g_return_if_fail (c != NULL);
    TRACE ("entering clientFocusAndRaise");

    screen_info = c->screen_info;
    display_info = screen_info->display_info;

    sibling = clientGetTransientFor(c);
    clientRaise (sibling, None);
    clientShow (sibling, TRUE);
    clientUnshade (c);
    clientSetFocus (screen_info, c, myDisplayGetCurrentTime (display_info), NO_FOCUS_FLAG);
    clientSetLastRaise (c);
}
Example #2
0
static void
clientCycleFocusAndRaise (Client *c)
{
    ScreenInfo *screen_info;
    DisplayInfo *display_info;
    Client *ancestor;

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

    screen_info = c->screen_info;
    display_info = screen_info->display_info;

    ancestor = clientGetTransientFor(c);
    clientRaise (c, None);
    clientShow (ancestor, TRUE);
    clientUnshade (c);
    clientSetFocus (screen_info, c, myDisplayGetCurrentTime (display_info), NO_FOCUS_FLAG);
    clientSetLastRaise (c);
}
Example #3
0
gboolean
clientFocusNew(Client * c)
{
    ScreenInfo *screen_info;
    DisplayInfo *display_info;
    gboolean give_focus;
    gboolean prevent_focus_stealing;
    gboolean prevented;

    g_return_val_if_fail (c != NULL, FALSE);

    screen_info = c->screen_info;
    display_info = screen_info->display_info;
    give_focus = (c-> type & WINDOW_REGULAR_FOCUSABLE) && (screen_info->params->focus_new);
    prevent_focus_stealing = screen_info->params->prevent_focus_stealing;
    prevented = FALSE;

    /*  Try to avoid focus stealing */
    if (!clientAcceptFocus (c) || (c->type & WINDOW_TYPE_DONT_FOCUS))
    {
        give_focus = FALSE;
    }
    else if (FLAG_TEST (c->flags, CLIENT_FLAG_HAS_USER_TIME) && (c->user_time == (guint32) 0))
    {
        /*
         *  _NET_WM_USER_TIME definition from http://standards.freedesktop.org/wm-spec
         * [...] "The special value of zero on a newly mapped window can be used to
         * request that the window not be initially focused when it is mapped."
         */
        TRACE ("given startup time is nil, not focusing \"%s\"", c->name);
        give_focus = FALSE;
        prevented = FALSE;
    }
    else if ((client_focus) && (prevent_focus_stealing))
    {
        if (client_focus->win_layer > c->win_layer)
        {
            TRACE ("not focusing \"%s\" because the current focused window is on a upper layer", c->name);
            give_focus = FALSE;
            prevented = TRUE;
        }
        else if (client_focus->win_layer < c->win_layer)
        {
            /* We don't use focus stealing prevention against upper layers */
            TRACE ("ignoring startup prevention because the current focused window is on a lower layer");
            give_focus = TRUE;
            prevented = FALSE;
        }
        else if (FLAG_TEST (client_focus->xfwm_flags, XFWM_FLAG_MOVING_RESIZING))
        {
            give_focus = FALSE;
            prevented = TRUE;
        }
        else if (FLAG_TEST (c->flags, CLIENT_FLAG_HAS_STARTUP_TIME | CLIENT_FLAG_HAS_USER_TIME))
        {
            TRACE ("current time is %u, time for \"%s\" is %u",
                   (unsigned int) client_focus->user_time,
                   c->name, (unsigned int) c->user_time);
            if (TIMESTAMP_IS_BEFORE (c->user_time, client_focus->user_time))
            {
                give_focus = FALSE;
                prevented = TRUE;
            }
        }
    }
    if (FLAG_TEST(c->flags, CLIENT_FLAG_STATE_MODAL))
    {
        give_focus = TRUE;
    }
    if (give_focus)
    {
        if (client_focus)
        {
            clientAdjustFullscreenLayer (client_focus, FALSE);
        }
        clientRaise (c, None);
        clientShow (c, TRUE);
        clientSetFocus (screen_info, c,
                        myDisplayGetCurrentTime (display_info),
                        FOCUS_IGNORE_MODAL);
    }
    else
    {
        Client *c2 = clientGetFocus();

        clientSortRing(c);
        if ((c2 != NULL) && (c2->win_layer == c->win_layer) && prevented)
        {
            /*
             * Place windows under the currently focused only if focus
             * stealing prevention had prevented the focus transition,
             * otherwise, leave the unfocused window on top.
             */
            clientLower (c, c2->frame);
        }
        else
        {
            clientRaise (c, None);
        }
        clientSortRing(c2);

        if (prevented)
        {
            TRACE ("setting WM_STATE_DEMANDS_ATTENTION flag on \"%s\" (0x%lx)", c->name, c->window);
            FLAG_SET (c->flags, CLIENT_FLAG_DEMANDS_ATTENTION);
        }

        clientShow (c, TRUE);
        clientSetNetState (c);
    }

    return (give_focus);
}
Example #4
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);
        }
    }
}