void XlibMenuShow(XlibMenu* menu) { if (!menu->visible) { FcitxMenuUpdate(menu->menushell); } FcitxXlibWindowPaint(&menu->parent); if (!menu->visible) { XMapRaised(menu->parent.owner->dpy, menu->parent.wId); } menu->visible = true; }
void MoveSubMenu(XlibMenu *sub, XlibMenu *parent, int offseth) { int dwidth, dheight; FcitxSkin *sc = &parent->owner->skin; GetScreenSize(parent->owner, &dwidth, &dheight); FcitxMenuUpdate(sub->menushell); GetMenuSize(sub); sub->iPosX = parent->iPosX + parent->width - sc->skinMenu.marginRight - 4; sub->iPosY = parent->iPosY + offseth - sc->skinMenu.marginTop; if (sub->iPosX + sub->width > dwidth) sub->iPosX = parent->iPosX - sub->width + sc->skinMenu.marginLeft + 4; if (sub->iPosY + sub->height > dheight) sub->iPosY = dheight - sub->height; XMoveWindow(parent->owner->dpy, sub->menuWindow, sub->iPosX, sub->iPosY); }
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; }
boolean MenuWindowEventHandler(void *arg, XEvent* event) { XlibMenu* menu = (XlibMenu*) arg; FcitxClassicUI* classicui = menu->owner; if (event->xany.window == menu->menuWindow) { switch (event->type) { case MapNotify: FcitxMenuUpdate(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); FcitxMenuItem *item = GetMenuItem(menu->menushell, i); if (!flag) { DrawXlibMenu(menu); if (item && item->type == MENUTYPE_SUBMENU && item->subMenu) { XlibMenu* subxlibmenu = (XlibMenu*) item->subMenu->uipriv[classicui->isfallback]; CloseOtherSubMenuWindow(menu, subxlibmenu); MoveSubMenu(subxlibmenu, menu, offseth); DrawXlibMenu(subxlibmenu); XMapRaised(menu->owner->dpy, subxlibmenu->menuWindow); } } if (item == 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; }