TrayWindow* CreateTrayWindow(FcitxClassicUI *classicui) { TrayWindow *trayWindow = fcitx_utils_malloc0(sizeof(TrayWindow)); trayWindow->owner = classicui; FcitxModuleFunctionArg arg; arg.args[0] = TrayEventHandler; arg.args[1] = trayWindow; InvokeFunction(classicui->owner, FCITX_X11, ADDXEVENTHANDLER, arg); InitTrayWindow(trayWindow); return trayWindow; }
void ClassicUIResume(void* arg) { FcitxClassicUI* classicui = (FcitxClassicUI*) arg; classicui->isSuspend = false; InitTrayWindow(classicui->trayWindow); }
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; }