Esempio n. 1
0
void 
clientFocusDirection (Client * c, int dir)
{
    Client *c2, *n = NULL;
    guint i;
    gint diff = 0, cur = 1024 * 1024;

    g_return_if_fail (c);
    TRACE ("entering focus direction");

    for (c2 = c->next, i = 1; c && i < c->screen_info->client_count; i++, c2 = c2->next)
    {
        if (!clientSelectMask (c2, NULL, 0, WINDOW_REGULAR_FOCUSABLE))
        {
            TRACE ("%s not in select mask", c2->name);
            continue;
        }

        switch (dir) 
        {
        case FOCUS_UP:
            diff = c->y - c2->y;
            break;
        case FOCUS_DOWN:
            diff = c2->y - c->y;
            break;
        case FOCUS_LEFT:
            diff = c->x - c2->x;
            break;
        case FOCUS_RIGHT:
            diff = c2->x - c->x;
            break;
        }

        if (diff > 0 && cur > diff) 
        {
            cur = diff;
            n = c2;
        }
    }

    if (n) 
    {
        clientSetFocus (c->screen_info, n, myDisplayGetCurrentTime (c->screen_info->display_info),
                        NO_FOCUS_FLAG);
    }
}
Esempio n. 2
0
static ClientPair
clientGetTopMostFocusable (ScreenInfo *screen_info, guint layer, GList * exclude_list)
{
    ClientPair top_client;
    Client *c;
    GList *list;

    TRACE ("entering");

    top_client.prefered = top_client.highest = NULL;
    for (list = screen_info->windows_stack; list; list = g_list_next (list))
    {
        c = (Client *) list->data;
        TRACE ("stack window \"%s\" (0x%lx), layer %i", c->name,
            c->window, (int) c->win_layer);

        if (!clientAcceptFocus (c) || (c->type & WINDOW_TYPE_DONT_FOCUS))
        {
            continue;
        }

        if (!g_list_find (exclude_list, (gconstpointer) c))
        {
            if (c->win_layer > layer)
            {
                break;
            }
            else if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_VISIBLE))
            {
                if (clientSelectMask (c, NULL, 0, WINDOW_REGULAR_FOCUSABLE))
                {
                    top_client.prefered = c;
                }
                top_client.highest = c;
            }
        }
    }

    return top_client;
}
Esempio n. 3
0
Client *
clientGetPrevious (Client * c, guint mask, guint type)
{
    Client *c2;
    unsigned int i;

    TRACE ("entering");

    if (c)
    {
        ScreenInfo *screen_info = c->screen_info;
        for (c2 = c->prev, i = 0; (c2) && (i < screen_info->client_count);
            c2 = c2->prev, i++)
        {
            if (clientSelectMask (c2, c, mask, type))
            {
                return c2;
            }
        }
    }
    return NULL;
}
Esempio n. 4
0
static GList *
clientCycleCreateList (Client *c)
{
    ScreenInfo *screen_info;
    Client *c2;
    guint range, search_range,   i;
    GList *client_list;

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

    screen_info = c->screen_info;
    range = clientGetCycleRange (screen_info);
    client_list = NULL;

    for (c2 = c, i = 0; c && i < screen_info->client_count; i++, c2 = c2->next)
    {
        search_range = range;
        /*
         *  We want to include modals even if skip pager/taskbar because
         *  modals are supposed to be focused
         */
        if (clientIsModal(c2))
        {
            search_range |= (SEARCH_INCLUDE_SKIP_TASKBAR | SEARCH_INCLUDE_SKIP_PAGER);
        }
        if (!clientSelectMask (c2, NULL, search_range, WINDOW_REGULAR_FOCUSABLE))
        {
            TRACE ("%s not in select mask", c2->name);
            continue;
        }
        if (screen_info->params->cycle_apps_only)
        {
            /*
             *  For apps only cycling, it's a tad more complicated
             * - We want "fake" dialogs, ie without a parent window
             * - We do not want dialogs but we want modals
             * - If a modal was added,we do not want to add
             *   its parent again
             */

            if (c2->type & WINDOW_TYPE_DIALOG)
            {
                if (clientIsValidTransientOrModal (c2))
                {
                    if (!clientIsModal(c2))
                    {
                        TRACE ("%s is not modal", c2->name);
                        continue;
                    }
                }
            }
            else if (!(c2->type & WINDOW_NORMAL))
            {
                {
                    TRACE ("%s is not normal", c2->name);
                    continue;
                }
            }
            else
            {
                if (g_list_find_custom (client_list, c2, clientCompareModal))
                {
                    TRACE ("%s found as modal list", c2->name);
                    continue;
                }
            }
        }

        TRACE ("adding %s", c2->name);
        client_list = g_list_append (client_list, c2);
    }

    return client_list;
}
Esempio n. 5
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);
        }
    }
}