INPUT_RETURN_VALUE IMSelectorGetCand(void* arg, FcitxCandidateWord* candWord) { IMSelector* imselector = arg; FcitxInstance* instance = imselector->owner; if (!candWord->priv) { FcitxInstanceSetLocalIMName(instance, FcitxInstanceGetCurrentIC(instance), NULL); return IRV_CLEAN; } int index = FcitxInstanceGetIMIndexByName(imselector->owner, (char*) candWord->priv); if (index == 0) FcitxInstanceCloseIM(instance, FcitxInstanceGetCurrentIC(instance)); else { if (imselector->global) FcitxInstanceSwitchIMByIndex(instance, index); else FcitxInstanceSetLocalIMName(instance, FcitxInstanceGetCurrentIC(instance), (char*) candWord->priv); if (FcitxInstanceGetCurrentState(instance) != IS_ACTIVE) FcitxInstanceEnableIM(instance, FcitxInstanceGetCurrentIC(instance), false); } return IRV_CLEAN; }
void SwitchVK(FcitxVKState *vkstate) { FcitxInstance* instance = vkstate->owner; if (vkstate->vkWindow == NULL) vkstate->vkWindow = CreateVKWindow(vkstate); VKWindow *vkWindow = vkstate->vkWindow; if (!vkstate->iVKCount) return; vkstate->bVK = !vkstate->bVK; if (vkstate->bVK) { int x, y; int dwidth, dheight; InvokeVaArgs(vkstate->owner, FCITX_X11, GETSCREENSIZE, &dwidth, &dheight); if (!FcitxUISupportMainWindow(instance)) { x = dwidth / 2 - VK_WINDOW_WIDTH / 2; y = 40; } else { int mx = 0, my = 0, mw = 0, mh = 0; FcitxUIGetMainWindowSize(instance, &mx, &my, &mw, &mh); x = mx; y = my + mh + 2; if ((y + VK_WINDOW_HEIGHT) >= dheight) y = my - VK_WINDOW_HEIGHT - 2; if (y < 0) y = 0; } if ((x + VK_WINDOW_WIDTH) >= dwidth) x = dwidth - VK_WINDOW_WIDTH - 1; if (x < 0) x = 0; XMoveWindow(vkWindow->dpy, vkWindow->window, x, y); DisplayVKWindow(vkWindow); FcitxUICloseInputWindow(instance); FcitxInputContext* ic = FcitxInstanceGetCurrentIC(instance); if (ic && FcitxInstanceGetCurrentState(instance) == IS_CLOSED) FcitxInstanceEnableIM(instance, ic, true); } else { XUnmapWindow(vkWindow->dpy, vkWindow->window); FcitxInstanceCleanInputWindow(instance); FcitxUIUpdateInputWindow(instance); } }
static void RemoteProcessEvent(void* p) { FcitxRemote* remote = (FcitxRemote*) p; unsigned int O; // lower 16bit 0->get 1->set, 2->reload, 3->toggle, 4->setIM int client_fd = UdAccept(remote->socket_fd); if (client_fd < 0) return; read(client_fd, &O, sizeof(int)); unsigned int cmd = O & 0xFFFF; unsigned int arg = (O >> 16) & 0xFFFF; switch (cmd) { /// {{{ case 0: SendIMState(remote, client_fd); break; case 1: /* arg is not state, due to backward compatible */ if (arg == 0) FcitxInstanceCloseIM(remote->owner, FcitxInstanceGetCurrentIC(remote->owner)); else { FcitxInstanceEnableIM(remote->owner, FcitxInstanceGetCurrentIC(remote->owner), false); } break; case 2: FcitxInstanceReloadConfig(remote->owner); break; case 3: FcitxInstanceChangeIMState(remote->owner, FcitxInstanceGetCurrentIC(remote->owner)); break; case 4: { char imname[MAX_IMNAME_LEN]; int n = read(client_fd, imname, MAX_IMNAME_LEN-1); imname[n] = '\0'; FcitxInstanceSwitchIMByName(remote->owner, imname); break; } default: break; /// }}} } close(client_fd); }
INPUT_RETURN_VALUE IMSelectorSelect(void* arg) { SelectorHandle* handle = arg; IMSelector* imselector = handle->imselector; FcitxInstance* instance = imselector->owner; FcitxIM* im = FcitxInstanceGetIMByIndex(instance, handle->idx); if (!im) return IRV_TO_PROCESS; if (handle->global) { FcitxInstanceSwitchIMByIndex(instance, handle->idx); } else { FcitxInstanceSetLocalIMName(instance, FcitxInstanceGetCurrentIC(instance), im->uniqueName); if (FcitxInstanceGetCurrentState(instance) != IS_ACTIVE) FcitxInstanceEnableIM(instance, FcitxInstanceGetCurrentIC(instance), false); } return IRV_CLEAN; }
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; }
void XIMProcessKey(FcitxXimFrontend* xim, IMForwardEventStruct * call_data) { KeySym originsym; FcitxKeySym sym; XKeyEvent *kev; int keyCount; uint32_t state; char strbuf[STRBUFLEN]; FcitxInputContext* ic = FcitxInstanceGetCurrentIC(xim->owner); FcitxGlobalConfig* config = FcitxInstanceGetGlobalConfig(xim->owner); FcitxInputState* input = FcitxInstanceGetInputState(xim->owner); if (ic == NULL) { ic = FcitxInstanceFindIC(xim->owner, xim->frontendid, &call_data->icid); if (FcitxInstanceSetCurrentIC(xim->owner, ic) && ic) FcitxUIOnInputFocus(xim->owner); } if (ic == NULL) return; if (ic->frontendid != xim->frontendid || GetXimIC(ic)->id != call_data->icid) { ic = FcitxInstanceFindIC(xim->owner, xim->frontendid, &call_data->icid); if (ic == NULL) return; if (FcitxInstanceSetCurrentIC(xim->owner, ic)) FcitxUIOnInputFocus(xim->owner); } kev = (XKeyEvent *) & call_data->event; memset(strbuf, 0, STRBUFLEN); keyCount = XLookupString(kev, strbuf, STRBUFLEN, &originsym, NULL); const uint32_t originstate = kev->state; state = kev->state - (kev->state & FcitxKeyState_NumLock) - (kev->state & FcitxKeyState_CapsLock) - (kev->state & FcitxKeyState_ScrollLock); state &= FcitxKeyState_UsedMask; FcitxHotkeyGetKey((FcitxKeySym) originsym, state, &sym, &state); FcitxLog(DEBUG, "KeyRelease=%d state=%d KEYCODE=%d KEYSYM=%d keyCount=%d", (call_data->event.type == KeyRelease), state, kev->keycode, (int) sym, keyCount); xim->currentSerialNumberCallData = call_data->serial_number; xim->currentSerialNumberKey = kev->serial; FcitxKeyEventType type = (call_data->event.type == KeyRelease) ? (FCITX_RELEASE_KEY) : (FCITX_PRESS_KEY); if (ic->state == IS_CLOSED) { if (type == FCITX_PRESS_KEY && FcitxHotkeyIsHotKey(sym, state, config->hkTrigger)) { FcitxInstanceEnableIM(xim->owner, ic, false); return; } else { XimForwardKeyInternal(xim, GetXimIC(ic), &call_data->event ); return; } } FcitxInputStateSetKeyCode(input, kev->keycode); FcitxInputStateSetKeySym(input, originsym); FcitxInputStateSetKeyState(input, originstate); INPUT_RETURN_VALUE retVal = FcitxInstanceProcessKey(xim->owner, type, kev->time, sym, state); FcitxInputStateSetKeyCode(input, 0); FcitxInputStateSetKeySym(input, 0); FcitxInputStateSetKeyState(input, 0); if ((retVal & IRV_FLAG_FORWARD_KEY) || retVal == IRV_TO_PROCESS) { XimForwardKeyInternal(xim, GetXimIC(ic), &call_data->event ); } else { if (!GetXimIC(ic)->bHasCursorLocation) SetTrackPos(xim, ic, NULL); } xim->currentSerialNumberCallData = xim->currentSerialNumberKey = 0L; }