Example #1
0
boolean TrayEventHandler(void *arg, XEvent* event)
{
    TrayWindow *trayWindow = arg;
    FcitxClassicUI *classicui = trayWindow->owner;
    FcitxInstance* instance = classicui->owner;
    Display *dpy = classicui->dpy;
    if (!classicui->bUseTrayIcon)
        return false;
    switch (event->type) {
    case ClientMessage:
        if (event->xclient.message_type == trayWindow->atoms[ATOM_MANAGER]
                && event->xclient.data.l[1] == trayWindow->atoms[ATOM_SELECTION]) {
            if (trayWindow->window == None)
                InitTrayWindow(trayWindow);
            TrayFindDock(dpy, trayWindow);
            return true;
        }
        break;

    case Expose:
        if (event->xexpose.window == trayWindow->window) {
            DrawTrayWindow(trayWindow);
        }
        break;
    case ConfigureNotify:
        if (trayWindow->window == event->xconfigure.window) {
            int size = event->xconfigure.height;
            if (size != trayWindow->size) {
                trayWindow->size = size;
                XSizeHints size_hints;
                size_hints.flags = PWinGravity | PBaseSize;
                size_hints.base_width = trayWindow->size;
                size_hints.base_height = trayWindow->size;
                XSetWMNormalHints(dpy, trayWindow->window, &size_hints);
            }

            DrawTrayWindow(trayWindow);
            return true;
        }
        break;
    case ButtonPress: {
        if (event->xbutton.window == trayWindow->window) {
            switch (event->xbutton.button) {
            case Button1:
                if (FcitxInstanceGetCurrentState(instance) == IS_CLOSED) {
                    FcitxInstanceEnableIM(instance, FcitxInstanceGetCurrentIC(instance), false);
                } else {
                    FcitxInstanceCloseIM(instance, FcitxInstanceGetCurrentIC(instance));
                }
                break;
            case Button3: {
                XlibMenu *mainMenuWindow = classicui->mainMenuWindow;
                int dwidth, dheight;
                FcitxMenuUpdate(mainMenuWindow->menushell);
                GetScreenSize(classicui, &dwidth, &dheight);
                GetMenuSize(mainMenuWindow);
                if (event->xbutton.x_root - event->xbutton.x +
                        mainMenuWindow->width >= dwidth)
                    mainMenuWindow->iPosX = dwidth - mainMenuWindow->width - event->xbutton.x;
                else
                    mainMenuWindow->iPosX =
                        event->xbutton.x_root - event->xbutton.x;

                // 面板的高度是可以变动的,需要取得准确的面板高度,才能准确确定右键菜单位置。
                if (event->xbutton.y_root + mainMenuWindow->height -
                        event->xbutton.y >= dheight)
                    mainMenuWindow->iPosY =
                        dheight - mainMenuWindow->height -
                        event->xbutton.y - 15;
                else
                    mainMenuWindow->iPosY = event->xbutton.y_root - event->xbutton.y + 25;     // +sc.skin_tray_icon.active_img.height;

                DrawXlibMenu(mainMenuWindow);
                DisplayXlibMenu(mainMenuWindow);
            }
            break;
            }
            return true;
        }
    }
    break;
    case DestroyNotify:
        if (event->xdestroywindow.window == trayWindow->dockWindow) {
            trayWindow->dockWindow = None;
            trayWindow->bTrayMapped = False;
            ReleaseTrayWindow(trayWindow);
            return true;
        }
        break;

    case ReparentNotify:
        if (event->xreparent.parent == DefaultRootWindow(dpy) && event->xreparent.window == trayWindow->window) {
            trayWindow->bTrayMapped = False;
            ReleaseTrayWindow(trayWindow);
            return true;
        }
        break;
    }
    return false;
}
Example #2
0
boolean MenuWindowEventHandler(void *arg, XEvent* event)
{
    XlibMenu* menu = (XlibMenu*) arg;
    if (event->xany.window == menu->menuWindow)
    {
        switch (event->type)
        {
        case MapNotify:
            UpdateMenuShell(menu->menushell);
            break;
        case Expose:
            DrawXlibMenu(menu);
            break;
        case LeaveNotify:
        {
            int x = event->xcrossing.x_root;
            int y = event->xcrossing.y_root;

            if (!IsMouseInOtherMenu(menu, x, y))
            {
                CloseAllSubMenuWindow(menu);
            }
        }
        break;
        case MotionNotify:
        {
            int offseth = 0;
            GetMenuSize(menu);
            int i=SelectShellIndex(menu, event->xmotion.x, event->xmotion.y, &offseth);
            boolean flag = ReverseColor(menu,i);
            if (!flag)
            {
                DrawXlibMenu(menu);
            }
            MenuShell *shell = GetMenuShell(menu->menushell, i);
            if (shell && shell->type == MENUTYPE_SUBMENU && shell->subMenu)
            {
                XlibMenu* subxlibmenu = (XlibMenu*) shell->subMenu->uipriv;
                CloseOtherSubMenuWindow(menu, subxlibmenu);
                MoveSubMenu(subxlibmenu, menu, offseth);
                DrawXlibMenu(subxlibmenu);
                XMapRaised(menu->owner->dpy, subxlibmenu->menuWindow);
            }
            if (shell == NULL)
                CloseOtherSubMenuWindow(menu, NULL);
        }
        break;
        case ButtonPress:
        {
            switch (event->xbutton.button)
            {
            case Button1:
            {
                int offseth;
                int i=SelectShellIndex(menu, event->xmotion.x, event->xmotion.y, &offseth);
                if (menu->menushell->MenuAction)
                {
                    if (menu->menushell->MenuAction(menu->menushell, i))
                        CloseAllMenuWindow(menu->owner);
                }
            }
            break;
            case Button3:
                CloseAllMenuWindow(menu->owner);
                break;
            }
        }
        break;
        }
        return true;
    }
    return false;
}