Skip to content

Commit

Permalink
Simplify the xcb tray window logic and avoid SNI transitional flicker…
Browse files Browse the repository at this point in the history
… between two UI

Right now both virtual keyboard and classicui want SNI. When transition
between two UI, sni is disabled and then re-enabled which is causing XCB
tray window being show/hide immediately.

This change try to simplify the xcb tray window logic:
1. hide, if suspend()
2a. If SNI addon is not available. show on resume
    If SNI addon is available, defer 1sec and check SNI status.

SNI enable/disable logic is updated to allow multiple enable/disable by
using a reference counter. disable() is deferred with event dispatcher,
to avoid enable/disable causing register/unregistration.
  • Loading branch information
wengxt committed Oct 30, 2024
1 parent 452672a commit 600a5d2
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 21 deletions.
23 changes: 16 additions & 7 deletions src/modules/notificationitem/notificationitem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

FCITX_DEFINE_LOG_CATEGORY(notificationitem, "notificationitem");
#define SNI_DEBUG() FCITX_LOGC(::notificationitem, Debug)
#define SNI_ERROR() FCITX_LOGC(::notificationitem, Error)

namespace fcitx {

Expand Down Expand Up @@ -363,7 +364,8 @@ void NotificationItem::maybeScheduleRegister() {
}

void NotificationItem::enable() {
if (enabled_) {
enabled_ += 1;
if (enabled_ > 1) {
return;
}

Expand All @@ -373,13 +375,20 @@ void NotificationItem::enable() {
}

void NotificationItem::disable() {
if (!enabled_) {
return;
}
instance_->eventDispatcher().scheduleWithContext(
lifeTimeTracker_.watch(), [this]() {
if (enabled_ == 0) {
SNI_ERROR()
<< "NotificationItem::disable called without enable.";
return;
}

SNI_DEBUG() << "Disable SNI";
enabled_ = false;
setRegistered(false);
SNI_DEBUG() << "Disable SNI";
enabled_ -= 1;
if (enabled_ == 0) {
setRegistered(false);
}
});
}

void NotificationItem::cleanUp() {
Expand Down
4 changes: 3 additions & 1 deletion src/modules/notificationitem/notificationitem.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <memory>
#include <fcitx/addonmanager.h>
#include "fcitx-utils/dbus/servicewatcher.h"
#include "fcitx-utils/trackableobject.h"
#include "fcitx/addoninstance.h"
#include "fcitx/instance.h"
#include "dbus_public.h"
Expand Down Expand Up @@ -60,10 +61,11 @@ class NotificationItem : public AddonInstance {
eventHandlers_;
std::unique_ptr<dbus::Slot> pendingRegisterCall_;
std::string sniWatcherName_;
bool enabled_ = false;
uint32_t enabled_ = 0;
bool registered_ = false;
std::unique_ptr<EventSourceTime> scheduleRegister_;
HandlerTable<NotificationItemCallback> handlers_;
TrackableObject<void> lifeTimeTracker_;
};

} // namespace fcitx
Expand Down
4 changes: 4 additions & 0 deletions src/modules/notificationitem/notificationitem_public.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#ifndef _FCITX_MODULES_NOTIFICATIONITEM_NOTIFICATIONITEM_PUBLIC_H_
#define _FCITX_MODULES_NOTIFICATIONITEM_NOTIFICATIONITEM_PUBLIC_H_

#include <fcitx-utils/handlertable.h>
#include <fcitx/addoninstance.h>

namespace fcitx {
Expand All @@ -15,12 +16,15 @@ using NotificationItemCallback = std::function<void(bool)>;

} // namespace fcitx

// When enable is called
FCITX_ADDON_DECLARE_FUNCTION(NotificationItem, enable, void());
// Callback will be called when registered changed.
FCITX_ADDON_DECLARE_FUNCTION(
NotificationItem, watch,
std::unique_ptr<HandlerTableEntry<NotificationItemCallback>>(
NotificationItemCallback));
FCITX_ADDON_DECLARE_FUNCTION(NotificationItem, disable, void());
// Can be used to query current state.
FCITX_ADDON_DECLARE_FUNCTION(NotificationItem, registered, bool());

#endif // _FCITX_MODULES_NOTIFICATIONITEM_NOTIFICATIONITEM_PUBLIC_H_
15 changes: 4 additions & 11 deletions src/ui/classic/xcbui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -742,29 +742,22 @@ int XCBUI::scaledDPI(int dpi) {
return targetDPI;
}

void XCBUI::resume() { updateTray(); }
void XCBUI::resume() {}

void XCBUI::suspend() {
inputWindow_->update(nullptr);
updateTray();
trayWindow_->suspend();
}

void XCBUI::updateTray() {
bool enableTray = enableTray_ && !parent_->suspended();
void XCBUI::setEnableTray(bool enable) {
bool enableTray = enable && !parent_->suspended();
if (enableTray) {
trayWindow_->resume();
} else {
trayWindow_->suspend();
}
}

void XCBUI::setEnableTray(bool enable) {
if (enable != enableTray_) {
enableTray_ = enable;
updateTray();
}
}

void XCBUI::scheduleUpdateScreen() {
initScreenEvent_->setNextInterval(100000);
initScreenEvent_->setOneShot();
Expand Down
2 changes: 0 additions & 2 deletions src/ui/classic/xcbui.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ class XCBUI : public UIInterface {
void refreshManager();
void readXSettings();
void initScreen();
void updateTray();
void scheduleUpdateScreen();

static void destroyCairoDevice(cairo_device_t *device);
Expand All @@ -90,7 +89,6 @@ class XCBUI : public UIInterface {
bool needFreeColorMap_ = false;
std::unique_ptr<XCBInputWindow> inputWindow_;
std::unique_ptr<XCBTrayWindow> trayWindow_;
bool enableTray_ = false;

std::string iconThemeName_;

Expand Down

0 comments on commit 600a5d2

Please sign in to comment.