コード例 #1
0
ファイル: cycle.c プロジェクト: xfce-mirror/xfwm4
static void
clientCycleActivate (Client *c)
{
    ScreenInfo *screen_info;
    DisplayInfo *display_info;
    Client *focused;
    guint workspace;

    if (c == NULL)
    {
        return;
    }

    screen_info = c->screen_info;
    display_info = screen_info->display_info;
    workspace = c->win_workspace;
    focused = clientGetFocus ();

    if ((focused) && (c != focused))
    {
        /* We might be able to avoid this if we are about to switch workspace */
        clientAdjustFullscreenLayer (focused, FALSE);
    }
    if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_WAS_SHOWN))
    {
        /* We are explicitely activating a window that was shown before show-desktop */
        clientClearAllShowDesktop (screen_info);
    }
    if (workspace != screen_info->current_ws)
    {
        workspaceSwitch (screen_info, workspace, c, FALSE, myDisplayGetCurrentTime (display_info));
    }

    clientCycleFocusAndRaise (c);
}
コード例 #2
0
ファイル: focus.c プロジェクト: canatella/xfwm4
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);
    }
}
コード例 #3
0
ファイル: focus.c プロジェクト: iglosiggio/xfwm4
void
clientPassFocus (ScreenInfo *screen_info, Client *c, GList *exclude_list)
{
    DisplayInfo *display_info;
    ClientPair top_most;
    Client *new_focus;
    Client *current_focus;
    Window dr, window;
    unsigned int mask;
    int rx, ry, wx, wy;
    int look_in_layer;

    TRACE ("entering");

    look_in_layer = (c ? c->win_layer : WIN_LAYER_NORMAL);
    new_focus = NULL;
    current_focus = client_focus;

    if (pending_focus)
    {
        current_focus = pending_focus;
    }

    if ((c || current_focus) && (c != current_focus))
    {
        return;
    }

    display_info = screen_info->display_info;
    top_most = clientGetTopMostFocusable (screen_info, look_in_layer, exclude_list);

    if (!(screen_info->params->click_to_focus) &&
        XQueryPointer (myScreenGetXDisplay (screen_info), screen_info->xroot, &dr, &window, &rx, &ry, &wx, &wy, &mask))
    {
        new_focus = clientAtPosition (screen_info, rx, ry, exclude_list);
    }
    if (!new_focus)
    {
        new_focus = top_most.prefered ? top_most.prefered : top_most.highest;
    }
    clientSetFocus (screen_info, new_focus,
                    myDisplayGetCurrentTime (display_info),
                    FOCUS_IGNORE_MODAL | FOCUS_FORCE | FOCUS_TRANSITION);
}
コード例 #4
0
ファイル: workspaces.c プロジェクト: Distrotech/xfwm4
void
workspaceSetCount (ScreenInfo * screen_info, guint count)
{
    DisplayInfo *display_info;
    Client *c;
    GList *list;

    g_return_if_fail (screen_info != NULL);

    TRACE ("entering workspaceSetCount");

    if (count < 1)
    {
        count = 1;
    }
    if (count == screen_info->workspace_count)
    {
        return;
    }

    display_info = screen_info->display_info;
    setHint (display_info, screen_info->xroot, NET_NUMBER_OF_DESKTOPS, count);
    screen_info->workspace_count = count;

    for (list = screen_info->windows_stack; list; list = g_list_next (list))
    {
        c = (Client *) list->data;
        if (c->win_workspace > count - 1)
        {
            clientSetWorkspace (c, count - 1, TRUE);
        }
    }
    if (screen_info->current_ws > count - 1)
    {
        workspaceSwitch (screen_info, count - 1, NULL, TRUE, myDisplayGetCurrentTime (display_info));
    }
    setNetWorkarea (display_info, screen_info->xroot, screen_info->workspace_count,
                    screen_info->logical_width, screen_info->logical_height, screen_info->margins);
    /* Recompute the layout based on the (changed) number of desktops */
    getDesktopLayout (display_info, screen_info->xroot, screen_info->workspace_count,
                     &screen_info->desktop_layout);
}
コード例 #5
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);
}
コード例 #6
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);
}
コード例 #7
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);
}
コード例 #8
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));
}
コード例 #9
0
ファイル: cycle.c プロジェクト: OperatingSystemU/Uwindowm
void
clientCycle (Client * c, XKeyEvent * ev)
{
    ScreenInfo *screen_info;
    DisplayInfo *display_info;
    ClientCycleData passdata;
    GList *client_list, *selected;
    gboolean g1, g2;
    int key, modifier;
    Client *c2;

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

    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, ev);
    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;
    }

    g1 = myScreenGrabKeyboard (screen_info, ev->time);
    g2 = myScreenGrabPointer (screen_info, TRUE, LeaveWindowMask, None, ev->time);


    if (!g1 || !g2)
    {
        TRACE ("grab failed in clientCycle");

        gdk_beep ();
        myScreenUngrabKeyboard (screen_info, myDisplayGetCurrentTime (display_info));
        myScreenUngrabPointer (screen_info, myDisplayGetCurrentTime (display_info));
        g_list_free (client_list);

        return;
    }

    passdata.wireframe = None;

    TRACE ("entering cycle loop");
    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);

    c2 = myScreenGetClientFromWindow (screen_info, GDK_WINDOW_XID (gtk_widget_get_window ( passdata.tabwin->tabwin_list->data)), SEARCH_FRAME);
    g_message ("%p", c2);
    clientSetFocus (screen_info, c2, ev->time, NO_FOCUS_FLAG);
    
    gtk_main ();
    eventFilterPop (display_info->xfilter);
    TRACE ("leaving cycle loop");
    if (passdata.wireframe)
    {
        wireframeDelete (screen_info, 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);

    myScreenUngrabKeyboard (screen_info, myDisplayGetCurrentTime (display_info));
    myScreenUngrabPointer (screen_info, myDisplayGetCurrentTime (display_info));
}