void FcitxDBusMenuEvent(FcitxNotificationItem* notificationitem, DBusMessage* message) { /* signature isvu */ DBusMessageIter args; dbus_message_iter_init(message, &args); int32_t id; char* type; do { if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_INT32) break; dbus_message_iter_get_basic(&args, &id); dbus_message_iter_next(&args); if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_STRING) break; dbus_message_iter_get_basic(&args, &type); dbus_message_iter_next(&args); if (strcmp(type, "clicked") != 0) break; /* TODO parse variant, but no one actually use this */ if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_VARIANT) break; dbus_message_iter_next(&args); /* timestamp, useless for us */ if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_UINT32) break; dbus_message_iter_next(&args); if (!FcitxInstanceCheckTimeoutByFunc(notificationitem->owner, FcitxDBusMenuDoEvent)) { notificationitem->pendingActionId = id; FcitxInstanceAddTimeout(notificationitem->owner, 50, FcitxDBusMenuDoEvent, notificationitem); } } while(0); }
static void FcitxNotifyCheckTimeout(FcitxNotify *notify) { time_t cur = FcitxNotifyGetTime(); FcitxNotifyItem *item; FcitxNotifyItem *next; boolean left = false; time_t earliest = 0; for (item = notify->intern_table;item;item = next) { next = item->intern_hh.next; if ((int64_t)(cur - item->time) > TIMEOUT_REAL_TIME) { /** * Remove from internal id table first so that it will not be * unref'ed here if it has not been unref'ed by libdbus. **/ FcitxNotifyItemRemoveInternal(notify, item); FcitxNotifyItemUnref(item); } else { if (!left) { earliest = item->time; left = true; } else { if ((int64_t)(item->time - earliest) < 0) { earliest = item->time; } } } } if (notify->timeout_added || !left) return; FcitxInstanceAddTimeout(notify->owner, (TIMEOUT_ADD_TIME + earliest - cur) * 1000, FcitxNotifyTimeoutCb, notify); }
void* X11Create(FcitxInstance* instance) { FcitxX11 *x11priv = fcitx_utils_new(FcitxX11); x11priv->dpy = XOpenDisplay(NULL); if (x11priv->dpy == NULL) return NULL; x11priv->owner = instance; x11priv->iScreen = DefaultScreen(x11priv->dpy); x11priv->rootWindow = DefaultRootWindow(x11priv->dpy); x11priv->eventWindow = XCreateWindow(x11priv->dpy, x11priv->rootWindow, 0, 0, 1, 1, 0, 0, InputOnly, CopyFromParent, 0, NULL); X11InitAtoms(x11priv); utarray_init(&x11priv->handlers, &handler_icd); utarray_init(&x11priv->comphandlers, &comphandler_icd); FcitxX11AddFunctions(instance); #ifdef HAVE_XFIXES int ignore; if (XFixesQueryExtension(x11priv->dpy, &x11priv->xfixesEventBase, &ignore)) x11priv->hasXfixes = true; #endif X11InitSelection(x11priv); X11InitComposite(x11priv); X11InitScreen(x11priv); XWindowAttributes attr; XGetWindowAttributes(x11priv->dpy, x11priv->rootWindow, &attr); if ((attr.your_event_mask & StructureNotifyMask) != StructureNotifyMask) { XSelectInput(x11priv->dpy, x11priv->rootWindow, attr.your_event_mask | StructureNotifyMask); } InitXErrorHandler(x11priv); X11DelayedCompositeTest(x11priv); FcitxInstanceAddTimeout(x11priv->owner, 5000, X11DelayedCompositeTest, x11priv); return x11priv; }