예제 #1
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));
}
예제 #2
0
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));
}