Skip to content

Commit 42f847f

Browse files
authored
Simplify the xcb tray window logic and avoid SNI transitional flicker between two UI (#1166)
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() 2. 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.
1 parent 452672a commit 42f847f

File tree

5 files changed

+27
-21
lines changed

5 files changed

+27
-21
lines changed

src/modules/notificationitem/notificationitem.cpp

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
FCITX_DEFINE_LOG_CATEGORY(notificationitem, "notificationitem");
2929
#define SNI_DEBUG() FCITX_LOGC(::notificationitem, Debug)
30+
#define SNI_ERROR() FCITX_LOGC(::notificationitem, Error)
3031

3132
namespace fcitx {
3233

@@ -363,7 +364,8 @@ void NotificationItem::maybeScheduleRegister() {
363364
}
364365

365366
void NotificationItem::enable() {
366-
if (enabled_) {
367+
enabled_ += 1;
368+
if (enabled_ > 1) {
367369
return;
368370
}
369371

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

375377
void NotificationItem::disable() {
376-
if (!enabled_) {
377-
return;
378-
}
378+
instance_->eventDispatcher().scheduleWithContext(
379+
lifeTimeTracker_.watch(), [this]() {
380+
if (enabled_ == 0) {
381+
SNI_ERROR()
382+
<< "NotificationItem::disable called without enable.";
383+
return;
384+
}
379385

380-
SNI_DEBUG() << "Disable SNI";
381-
enabled_ = false;
382-
setRegistered(false);
386+
SNI_DEBUG() << "Disable SNI";
387+
enabled_ -= 1;
388+
if (enabled_ == 0) {
389+
setRegistered(false);
390+
}
391+
});
383392
}
384393

385394
void NotificationItem::cleanUp() {

src/modules/notificationitem/notificationitem.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <memory>
1111
#include <fcitx/addonmanager.h>
1212
#include "fcitx-utils/dbus/servicewatcher.h"
13+
#include "fcitx-utils/trackableobject.h"
1314
#include "fcitx/addoninstance.h"
1415
#include "fcitx/instance.h"
1516
#include "dbus_public.h"
@@ -60,10 +61,11 @@ class NotificationItem : public AddonInstance {
6061
eventHandlers_;
6162
std::unique_ptr<dbus::Slot> pendingRegisterCall_;
6263
std::string sniWatcherName_;
63-
bool enabled_ = false;
64+
uint32_t enabled_ = 0;
6465
bool registered_ = false;
6566
std::unique_ptr<EventSourceTime> scheduleRegister_;
6667
HandlerTable<NotificationItemCallback> handlers_;
68+
TrackableObject<void> lifeTimeTracker_;
6769
};
6870

6971
} // namespace fcitx

src/modules/notificationitem/notificationitem_public.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#ifndef _FCITX_MODULES_NOTIFICATIONITEM_NOTIFICATIONITEM_PUBLIC_H_
88
#define _FCITX_MODULES_NOTIFICATIONITEM_NOTIFICATIONITEM_PUBLIC_H_
99

10+
#include <fcitx-utils/handlertable.h>
1011
#include <fcitx/addoninstance.h>
1112

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

1617
} // namespace fcitx
1718

19+
// When enable is called
1820
FCITX_ADDON_DECLARE_FUNCTION(NotificationItem, enable, void());
21+
// Callback will be called when registered changed.
1922
FCITX_ADDON_DECLARE_FUNCTION(
2023
NotificationItem, watch,
2124
std::unique_ptr<HandlerTableEntry<NotificationItemCallback>>(
2225
NotificationItemCallback));
2326
FCITX_ADDON_DECLARE_FUNCTION(NotificationItem, disable, void());
27+
// Can be used to query current state.
2428
FCITX_ADDON_DECLARE_FUNCTION(NotificationItem, registered, bool());
2529

2630
#endif // _FCITX_MODULES_NOTIFICATIONITEM_NOTIFICATIONITEM_PUBLIC_H_

src/ui/classic/xcbui.cpp

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -742,29 +742,22 @@ int XCBUI::scaledDPI(int dpi) {
742742
return targetDPI;
743743
}
744744

745-
void XCBUI::resume() { updateTray(); }
745+
void XCBUI::resume() {}
746746

747747
void XCBUI::suspend() {
748748
inputWindow_->update(nullptr);
749-
updateTray();
749+
trayWindow_->suspend();
750750
}
751751

752-
void XCBUI::updateTray() {
753-
bool enableTray = enableTray_ && !parent_->suspended();
752+
void XCBUI::setEnableTray(bool enable) {
753+
bool enableTray = enable && !parent_->suspended();
754754
if (enableTray) {
755755
trayWindow_->resume();
756756
} else {
757757
trayWindow_->suspend();
758758
}
759759
}
760760

761-
void XCBUI::setEnableTray(bool enable) {
762-
if (enable != enableTray_) {
763-
enableTray_ = enable;
764-
updateTray();
765-
}
766-
}
767-
768761
void XCBUI::scheduleUpdateScreen() {
769762
initScreenEvent_->setNextInterval(100000);
770763
initScreenEvent_->setOneShot();

src/ui/classic/xcbui.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@ class XCBUI : public UIInterface {
7373
void refreshManager();
7474
void readXSettings();
7575
void initScreen();
76-
void updateTray();
7776
void scheduleUpdateScreen();
7877

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

9593
std::string iconThemeName_;
9694

0 commit comments

Comments
 (0)