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; }
FCITX_EXPORT_API boolean FcitxInstanceSetCurrentIC(FcitxInstance* instance, FcitxInputContext* ic) { FcitxContextState prevstate = FcitxInstanceGetCurrentState(instance); boolean changed = (instance->CurrentIC != ic); instance->CurrentIC = ic; FcitxContextState nextstate = FcitxInstanceGetCurrentState(instance); if (!((prevstate == IS_CLOSED && nextstate == IS_CLOSED) || (prevstate != IS_CLOSED && nextstate != IS_CLOSED))) { if (prevstate == IS_CLOSED) instance->timeStart = time(NULL); else instance->totaltime += difftime(time(NULL), instance->timeStart); } return changed; }
void LightUIOnTriggerOn(void* arg) { FcitxLightUI* lightui = (FcitxLightUI*) arg; FcitxInstance *instance = lightui->owner; if (FcitxInstanceGetCurrentState(instance) == IS_ACTIVE) { DrawMainWindow(lightui->mainWindow); ShowMainWindow(lightui->mainWindow); } DrawTrayWindow(lightui->trayWindow); }
FCITX_EXPORT_API void FcitxUIOnInputFocus(FcitxInstance* instance) { if (UI_FUNC_IS_VALID(OnInputFocus)) instance->ui->ui->OnInputFocus(instance->ui->addonInstance); FcitxInstanceProcessInputFocusHook(instance); FcitxInstanceResetInput(instance); if (instance->config->firstAsInactive) { if (FcitxInstanceGetCurrentState(instance) == IS_ACTIVE) FcitxInstanceSwitchIM(instance, instance->lastIMIndex); else if (FcitxInstanceGetCurrentState(instance) == IS_ENG) { if (instance->iIMIndex != 0) instance->lastIMIndex = instance->iIMIndex; FcitxInstanceSwitchIMInternal(instance, 0, false); } } FcitxUICloseInputWindow(instance); }
void VKUpdate(void* arg) { FcitxVKState *vkstate = (FcitxVKState*) arg; VKWindow* vkWindow = vkstate->vkWindow; if (vkWindow) { if (FcitxInstanceGetCurrentState(vkstate->owner) != IS_CLOSED && vkstate->bVK) { DrawVKWindow(vkWindow); DisplayVKWindow(vkWindow); } else XUnmapWindow(vkWindow->dpy, vkWindow->window); } }
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); } }
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; }
static void SendIMState(FcitxRemote* remote, int fd) { FcitxContextState r = FcitxInstanceGetCurrentState(remote->owner); write(fd, &r, sizeof(r)); }
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 DrawTrayWindow(TrayWindow* trayWindow) { FcitxClassicUI *classicui = trayWindow->owner; FcitxSkin *sc = &classicui->skin; SkinImage *image; int f_state; if (!classicui->bUseTrayIcon) return; if (FcitxInstanceGetCurrentState(classicui->owner) == IS_ACTIVE) f_state = ACTIVE_ICON; else f_state = INACTIVE_ICON; cairo_t *c; cairo_surface_t *png_surface ; if (!trayWindow->bTrayMapped) return; /* 画png */ if (f_state) { image = LoadImage(sc, sc->skinTrayIcon.active, true); } else { image = LoadImage(sc, sc->skinTrayIcon.inactive, true); } if (image == NULL) return; png_surface = image->image; c = cairo_create(trayWindow->cs); cairo_set_source_rgba(c, 0, 0, 0, 0); cairo_set_operator(c, CAIRO_OPERATOR_SOURCE); cairo_paint(c); do { if (png_surface) { int w = cairo_image_surface_get_width(png_surface); int h = cairo_image_surface_get_height(png_surface); if (w == 0 || h == 0) break; double scaleW = 1.0, scaleH = 1.0; if (w > trayWindow->size || h > trayWindow->size) { scaleW = ((double) trayWindow->size) / w; scaleH = ((double) trayWindow->size) / h; if (scaleW > scaleH) scaleH = scaleW; else scaleW = scaleH; } int aw = scaleW * w; int ah = scaleH * h; cairo_scale(c, scaleW, scaleH); cairo_set_source_surface(c, png_surface, (trayWindow->size - aw) / 2 , (trayWindow->size - ah) / 2); cairo_set_operator(c, CAIRO_OPERATOR_OVER); cairo_paint_with_alpha(c, 1); } } while(0); cairo_destroy(c); XVisualInfo* vi = trayWindow->visual.visual ? &trayWindow->visual : NULL; if (!(vi && vi->visual)) { XClearArea(trayWindow->owner->dpy, trayWindow->window, 0, 0, trayWindow->size, trayWindow->size, False); } c = cairo_create(trayWindow->cs_x); if (vi && vi->visual) { cairo_set_source_rgba(c, 0, 0, 0, 0); cairo_set_operator(c, CAIRO_OPERATOR_SOURCE); cairo_paint(c); } cairo_set_operator(c, CAIRO_OPERATOR_OVER); cairo_set_source_surface(c, trayWindow->cs, 0, 0); cairo_rectangle(c, 0, 0, trayWindow->size, trayWindow->size); cairo_clip(c); cairo_paint(c); cairo_destroy(c); }