Пример #1
0
Client *
clientGetTransient (Client * c)
{
    g_return_val_if_fail (c != NULL, NULL);

    TRACE ("entering clientGetTransient");

    if ((c->transient_for) && (c->transient_for != c->screen_info->xroot))
    {
        return myScreenGetClientFromWindow (c->screen_info, c->transient_for, SEARCH_WINDOW);
    }
    return NULL;
}
Пример #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));
}
Пример #3
0
static eventFilterStatus
clientCycleEventFilter (XfwmEvent *event, gpointer data)
{
    ScreenInfo *screen_info;
    DisplayInfo *display_info;
    ClientCycleData *passdata;
    Client *c, *removed;
    Client *c2 = NULL;
    eventFilterStatus status;
    KeyCode cancel, left, right, up, down;
    int key, modifiers;
    gboolean cycling;
    GList *li;

    TRACE ("entering");

    passdata = (ClientCycleData *) data;
    c = tabwinGetSelected(passdata->tabwin);
    if (c == NULL)
    {
        return EVENT_FILTER_CONTINUE;
    }

    screen_info = c->screen_info;
    display_info = screen_info->display_info;
    cancel = screen_info->params->keys[KEY_CANCEL].keycode;
    left = screen_info->params->keys[KEY_LEFT].keycode;
    right = screen_info->params->keys[KEY_RIGHT].keycode;
    up = screen_info->params->keys[KEY_UP].keycode;
    down = screen_info->params->keys[KEY_DOWN].keycode;
    modifiers = (screen_info->params->keys[KEY_CYCLE_WINDOWS].modifier |
                 screen_info->params->keys[KEY_CYCLE_REVERSE_WINDOWS].modifier);
    status = EVENT_FILTER_CONTINUE;
    removed = NULL;
    cycling = TRUE;

    /* Update the display time */
    myDisplayUpdateCurrentTime (display_info, event);

    switch (event->meta.type)
    {
        case XFWM_EVENT_KEY:
            if (event->key.pressed)
            {
                key = myScreenGetKeyPressed (screen_info, &event->key);
                /*
                 * We cannot simply check for key == KEY_CANCEL here because of the
                 * modidier being pressed, so we need to look at the keycode directly.
                 */
                if (event->key.keycode == cancel)
                {
                    c2 = tabwinSelectHead (passdata->tabwin);
                    cycling = FALSE;
                }
                else if (event->key.keycode == up)
                {
                    c2 = tabwinSelectDelta(passdata->tabwin, -1, 0);
                }
                else if (event->key.keycode == down)
                {
                    c2 = tabwinSelectDelta(passdata->tabwin, 1, 0);
                }
                else if (event->key.keycode == left)
                {
                    c2 = tabwinSelectDelta(passdata->tabwin, 0, -1);
                }
                else if (event->key.keycode == right)
                {
                    c2 = tabwinSelectDelta(passdata->tabwin, -0, 1);
                }
                else if (key == KEY_CYCLE_REVERSE_WINDOWS)
                {
                    TRACE ("cycle: previous");
                    c2 = tabwinSelectPrev(passdata->tabwin);
                }
                else if (key == KEY_CYCLE_WINDOWS)
                {
                    TRACE ("cycle: next");
                    c2 = tabwinSelectNext(passdata->tabwin);
                }
                if (c2)
                {
                    clientCycleUpdateWireframe (c2, passdata);
                }

                /* If last key press event had not our modifiers pressed, finish cycling */
                if (!(event->key.state & modifiers))
                {
                    cycling = FALSE;
                }
                status = EVENT_FILTER_STOP;
            }
            else
            {
                int keysym = XkbKeycodeToKeysym (event->meta.xevent->xany.display, event->key.keycode, 0, 0);

                if (IsModifierKey(keysym))
                {
                    if (!(myScreenGetModifierPressed (screen_info) & modifiers))
                    {
                        cycling = FALSE;
                    }
                }
            }
            status = EVENT_FILTER_STOP;
            break;
        case XFWM_EVENT_BUTTON:
            if (event->button.pressed)
            {
                /* only accept events for the tab windows */
                for (li = passdata->tabwin->tabwin_list; li != NULL; li = li->next)
                {
                    if (GDK_WINDOW_XID (gtk_widget_get_window (li->data)) == event->meta.window)
                    {
                        if  (event->button.button == Button1)
                        {
                            c2 = tabwinSelectHovered (passdata->tabwin);
                            cycling = FALSE;
                            break;
                        }
                        else if (event->button.button == Button4)
                        {
                            /* Mouse wheel scroll up */
                            TRACE ("cycle: previous");
                            c2 = tabwinSelectPrev(passdata->tabwin);
                        }
                        else if (event->button.button == Button5)
                        {
                            /* Mouse wheel scroll down */
                            TRACE ("cycle: next");
                            c2 = tabwinSelectNext(passdata->tabwin);
                        }
                    }
                    if (c2)
                    {
                        clientCycleUpdateWireframe (c2, passdata);
                    }
                }
            }
            status = EVENT_FILTER_STOP;
            break;
        case XFWM_EVENT_MOTION:
            break;
        case XFWM_EVENT_CROSSING:
            /* Track whether the pointer is inside one of the tab-windows */
            for (li = passdata->tabwin->tabwin_list; li != NULL; li = li->next)
            {
                if (GDK_WINDOW_XID (gtk_widget_get_window (li->data)) == event->meta.window)
                {
                    passdata->inside = event->crossing.enter;
                }
            }
            status = EVENT_FILTER_STOP;
            break;
        case XFWM_EVENT_XEVENT:
            switch (event->meta.xevent->type)
            {
                case DestroyNotify:
                    status = EVENT_FILTER_CONTINUE;
                    removed = myScreenGetClientFromWindow (screen_info,
                                                           ((XDestroyWindowEvent *) event->meta.xevent)->window,
                                                           SEARCH_WINDOW);
                    if (removed == NULL)
                    {
                        break; /* No need to go any further */
                    }
                    FALLTHROUGH;
                case UnmapNotify:
                    status = EVENT_FILTER_CONTINUE;
                    if (!removed)
                    {
                        removed = myScreenGetClientFromWindow (screen_info,
                                                               ((XUnmapEvent *) event->meta.xevent)->window,
                                                               SEARCH_WINDOW);
                        if (removed == NULL)
                        {
                            break; /* No need to go any further */
                        }
                    }
                    c = tabwinRemoveClient(passdata->tabwin, removed);
                    cycling = clientCycleUpdateWireframe (c, passdata);
                    break;
            }
            break;
    }

    if (!cycling)
    {
        TRACE ("event loop now finished");
        gtk_main_quit ();
    }

    return status;
}
Пример #4
0
static eventFilterStatus
clientCycleEventFilter (XEvent * xevent, gpointer data)
{
    ScreenInfo *screen_info;
    DisplayInfo *display_info;
    ClientCycleData *passdata;
    Client *c, *removed;
    Client *c2 = NULL;
    eventFilterStatus status;
    KeyCode cancel, left, right, up, down;
    int key, modifiers;
    gboolean key_pressed, cycling, gone;
    GList *li;
    Window mouse_window = 0;
    XButtonEvent ev;

    TRACE ("entering clientCycleEventFilter");

    passdata = (ClientCycleData *) data;
    c = tabwinGetSelected(passdata->tabwin);
    if (c == NULL)
    {
        return EVENT_FILTER_CONTINUE;
    }

    screen_info = c->screen_info;
    display_info = screen_info->display_info;
    cancel = screen_info->params->keys[KEY_CANCEL].keycode;
    left = screen_info->params->keys[KEY_LEFT].keycode;
    right = screen_info->params->keys[KEY_RIGHT].keycode;
    up = screen_info->params->keys[KEY_UP].keycode;
    down = screen_info->params->keys[KEY_DOWN].keycode;
    modifiers = (screen_info->params->keys[KEY_CYCLE_WINDOWS].modifier |
                 screen_info->params->keys[KEY_CYCLE_REVERSE_WINDOWS].modifier);
    status = EVENT_FILTER_STOP;
    removed = NULL;
    cycling = TRUE;
    gone = FALSE;

    /* Update the display time */
    myDisplayUpdateCurrentTime (display_info, xevent);

    switch (xevent->type)
    {
        case DestroyNotify:
            status = EVENT_FILTER_CONTINUE;
            if ((removed = myScreenGetClientFromWindow (screen_info, ((XDestroyWindowEvent *) xevent)->window, SEARCH_WINDOW)) == NULL)
                break; /* No need to go any further */
            gone |= (c == removed);
            /* Walk through */
        case UnmapNotify:
            status = EVENT_FILTER_CONTINUE;
            if (!removed && (removed = myScreenGetClientFromWindow (screen_info, ((XUnmapEvent *) xevent)->window, SEARCH_WINDOW)) == NULL)
                break; /* No need to go any further */
            gone |= (c == removed);
            c = tabwinRemoveClient(passdata->tabwin, removed);
            /* Walk through */
        case KeyPress:
            key_pressed = (xevent->type == KeyPress);
            if (gone || key_pressed)
            {
                if (key_pressed)
                {
                    key = myScreenGetKeyPressed (screen_info, (XKeyEvent *) xevent);
                    /*
                     * We cannot simply check for key == KEY_CANCEL here because of the
                     * modidier being pressed, so we need to look at the keycode directly.
                     */
                    if (xevent->xkey.keycode == cancel)
                    {
                        c2 = tabwinSelectHead (passdata->tabwin);
                        cycling = FALSE;
                    }
                    else if (xevent->xkey.keycode == up)
                    {
                        c2 = tabwinSelectDelta(passdata->tabwin, -1, 0);
                    }
                    else if (xevent->xkey.keycode == down)
                    {
                        c2 = tabwinSelectDelta(passdata->tabwin, 1, 0);
                    }
                    else if (xevent->xkey.keycode == left)
                    {
                        c2 = tabwinSelectDelta(passdata->tabwin, 0, -1);
                    }
                    else if (xevent->xkey.keycode == right)
                    {
                        c2 = tabwinSelectDelta(passdata->tabwin, -0, 1);
                    }
                    else if (key == KEY_CYCLE_REVERSE_WINDOWS)
                    {
                        TRACE ("Cycle: previous");
                        c2 = tabwinSelectPrev(passdata->tabwin);
                    }
                    else if (key == KEY_CYCLE_WINDOWS)
                    {
                        TRACE ("Cycle: next");
                        c2 = tabwinSelectNext(passdata->tabwin);
                    }
                    if (c2)
                    {
                        c = c2;
                    }

                    /* If last key press event had not our modifiers pressed, finish cycling */
                    if (!(xevent->xkey.state & modifiers))
                    {
                        cycling = FALSE;
                    }
                }
            }
            break;
        case KeyRelease:
            {
                int keysym = XLookupKeysym (&xevent->xkey, 0);

                if (IsModifierKey(keysym))
                {
                    if (!(myScreenGetModifierPressed (screen_info) & modifiers))
                    {
                        cycling = FALSE;
                    }
                }
            }
            break;
        case ButtonPress:
            status = EVENT_FILTER_STOP;
            ev = xevent->xbutton;
            /* window of the event, we might accept it later */
            mouse_window = xevent->xbutton.window;
            if (mouse_window != 0)
            {
                /* only accept events for the tab windows */
                for (li = passdata->tabwin->tabwin_list; li != NULL; li = li->next)
                {
                    if (GDK_WINDOW_XID (gtk_widget_get_window (li->data)) == mouse_window)
                    {
                        if  (ev.button == Button1)
                        {
                            cycling = FALSE;
                            c = tabwinSelectHoveredWidget (passdata->tabwin);
                            break;
                        }
                        else if  (ev.button == Button4)
                        {
                            /* Mouse wheel scroll up */
                            TRACE ("Cycle: previous");
                            c2 = tabwinSelectPrev(passdata->tabwin);
                        }
                        else if (ev.button == Button5)
                        {
                            /* Mouse wheel scroll down */
                            TRACE ("Cycle: next");
                            c2 = tabwinSelectNext(passdata->tabwin);
                        }
                    }
                }
                if (c2)
                {
                    c = c2;
                }
            }
            break;
        default:
            status = EVENT_FILTER_CONTINUE;
            break;
    }

    if (!cycling)
    {
        TRACE ("event loop now finished");
        gtk_main_quit ();
    }

    if (status == EVENT_FILTER_STOP)
    {
        if (cycling)
        {
            if (c)
            {
                if (passdata->wireframe)
                {
                    wireframeUpdate (c, passdata->wireframe);
                }
            }
            else
            {
                cycling = FALSE;
            }
        }
    }

    return status;
}