コード例 #1
0
ファイル: focus.c プロジェクト: iglosiggio/xfwm4
void
clientUpdateFocus (ScreenInfo *screen_info, Client * c, unsigned short flags)
{
    Client *c2;
    gboolean restacked;

    TRACE ("entering");

    c2 = ((client_focus != c) ? client_focus : NULL);
    if ((c) && !clientAcceptFocus (c))
    {
        TRACE ("SKIP_FOCUS set for client \"%s\" (0x%lx)", c->name, c->window);
        pending_focus = NULL;
        return;
    }

    if ((c) && (c == client_focus) && !(flags & FOCUS_FORCE))
    {
        TRACE ("client \"%s\" (0x%lx) is already focused, ignoring request", c->name, c->window);
        pending_focus = NULL;
        return;
    }

    client_focus = c;
    if (c2)
    {
        clientSetNetState (c2);
        clientAdjustFullscreenLayer (c2, FALSE);
        frameQueueDraw (c2, FALSE);
        clientUpdateOpacity (c2);
    }
    if (c)
    {
        user_focus = c;
        clientInstallColormaps (c);
        if (flags & FOCUS_SORT)
        {
            clientSortRing(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);
        restacked = clientAdjustFullscreenLayer (c, TRUE);

        if (!restacked && screen_info->params->click_to_focus)
        {
            clientRaise (c, None);
            clientSetLastRaise (c);
        }
        frameQueueDraw (c, FALSE);
        clientUpdateOpacity (c);
    }
    clientSetNetActiveWindow (screen_info, c, 0);
    pending_focus = NULL;
}
コード例 #2
0
ファイル: cycle.c プロジェクト: xfce-mirror/xfwm4
static gboolean
clientCycleUpdateWireframe (Client *c, ClientCycleData *passdata)
{
    if (c)
    {
        if (c->screen_info->params->cycle_raise)
        {
          clientRaise (c, None);
        }
        if (passdata->wireframe)
        {
            wireframeUpdate (c, passdata->wireframe);
        }
        return TRUE;
    }
    return FALSE;
}
コード例 #3
0
ファイル: cycle.c プロジェクト: xfce-mirror/xfwm4
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);
}
コード例 #4
0
ファイル: cycle.c プロジェクト: OperatingSystemU/Uwindowm
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);
}
コード例 #5
0
ファイル: focus.c プロジェクト: iglosiggio/xfwm4
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);
}
コード例 #6
0
ファイル: cycle.c プロジェクト: xfce-mirror/xfwm4
void
clientCycle (Client * c, XfwmEventKey *event)
{
    ScreenInfo *screen_info;
    DisplayInfo *display_info;
    ClientCycleData passdata;
    GList *client_list, *selected;
    int key, modifier;

    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;

    client_list = clientCycleCreateList (c);
    if (!client_list)
    {
        return;
    }

    modifier = 0;
    key = myScreenGetKeyPressed (screen_info, event);
    if (key == KEY_CYCLE_REVERSE_WINDOWS)
    {
        selected = g_list_last (client_list);
        modifier = screen_info->params->keys[KEY_CYCLE_REVERSE_WINDOWS].modifier;
    }
    else
    {
        selected = g_list_next (client_list);
        modifier = screen_info->params->keys[KEY_CYCLE_WINDOWS].modifier;
    }
    if (!selected)
    {
        /* Only one element in list */
        selected = client_list;
    }

    if (!modifier)
    {
        /*
         * The shortcut has no modifier so there's no point in entering
         * the cycle loop, just select the next or previous window and
         * that's it...
         */
        clientCycleActivate ((Client *) selected->data);
        g_list_free (client_list);
        return;
    }

    myScreenGrabPointer (screen_info, TRUE, EnterWindowMask | LeaveWindowMask, None, event->time);
    /* Grabbing the pointer may fail e.g. if the user is doing a drag'n drop */
    if (!myScreenGrabKeyboard (screen_info, KeyPressMask | KeyReleaseMask, event->time))
    {
        TRACE ("grab failed in clientCycle");
        myDisplayBeep (display_info);
        myScreenUngrabKeyboard (screen_info, myDisplayGetCurrentTime (display_info));
        myScreenUngrabPointer (screen_info, myDisplayGetCurrentTime (display_info));
        g_list_free (client_list);

        return;
    }

    passdata.wireframe = NULL;
    passdata.inside = FALSE;

    TRACE ("entering cycle loop");
    if (screen_info->params->cycle_raise)
    {
      clientRaise ((Client *) selected->data, None);
    }
    if (screen_info->params->cycle_draw_frame)
    {
        passdata.wireframe = wireframeCreate ((Client *) selected->data);
    }
    passdata.tabwin = tabwinCreate (&client_list, selected, screen_info->params->cycle_workspaces);
    eventFilterPush (display_info->xfilter, clientCycleEventFilter, &passdata);

    gtk_main ();
    eventFilterPop (display_info->xfilter);
    TRACE ("leaving cycle loop");
    if (passdata.wireframe)
    {
        wireframeDelete (passdata.wireframe);
    }
    updateXserverTime (display_info);

    c = tabwinGetSelected (passdata.tabwin);
    if (c)
    {
        clientCycleActivate (c);
    }

    tabwinDestroy (passdata.tabwin);
    g_free (passdata.tabwin);
    g_list_free (client_list);

    if (passdata.inside)
    {
        /* A bit of a hack, flush EnterNotify if the pointer is inside
         * the tabwin to defeat focus-follow-mouse tracking */
        eventFilterPush (display_info->xfilter, clientCycleFlushEventFilter, display_info);
        gtk_main ();
        eventFilterPop (display_info->xfilter);
    }

    myScreenUngrabKeyboard (screen_info, myDisplayGetCurrentTime (display_info));
    myScreenUngrabPointer (screen_info, myDisplayGetCurrentTime (display_info));
}
コード例 #7
0
ファイル: workspaces.c プロジェクト: Distrotech/xfwm4
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);
        }
    }
}