diff --git a/src/frontend/waylandim/waylandim.cpp b/src/frontend/waylandim/waylandim.cpp index 6bfc47442..f8a095175 100644 --- a/src/frontend/waylandim/waylandim.cpp +++ b/src/frontend/waylandim/waylandim.cpp @@ -32,6 +32,7 @@ namespace fcitx { WaylandIMModule::WaylandIMModule(Instance *instance) : instance_(instance) { reloadConfig(); + persistentVirtualKeyboard_ = *config_.persistentVirtualKeyboard; createdCallback_ = wayland()->call( [this](const std::string &name, wl_display *display, diff --git a/src/frontend/waylandim/waylandim.h b/src/frontend/waylandim/waylandim.h index 78218dcbc..de2884dce 100644 --- a/src/frontend/waylandim/waylandim.h +++ b/src/frontend/waylandim/waylandim.h @@ -36,7 +36,18 @@ FCITX_CONFIGURATION( Option preferKeyEvent{ this, "PreferKeyEvent", _("Forward key event instead of commiting text if it is not handled"), - true};); + true}; + OptionWithAnnotation persistentVirtualKeyboard{ + this, + "PersistentVirtualKeyboard", + _("Keep virtual keyboard object for V2 Protocol (Need restart)"), + false, + {}, + {}, + {_("If enabled, when using zwp_input_method_v2, do not create and " + "destroy zwp_virtual_keyboard_v1 on activate and deactivate. This " + "may workaround some bug in certain Compositor, including " + "Sway<=1.9, RiverWM<=0.3.0.")}};); constexpr int32_t repeatHackDelay = 3000; class WaylandIMServer; @@ -67,6 +78,10 @@ class WaylandIMModule : public AddonInstance { AggregatedAppMonitor *appMonitor(const std::string &display); + bool persistentVirtualKeyboard() const { + return persistentVirtualKeyboard_; + } + private: Instance *instance_; WaylandIMConfig config_; @@ -79,6 +94,7 @@ class WaylandIMModule : public AddonInstance { std::unique_ptr> createdCallback_; std::unique_ptr> closedCallback_; + bool persistentVirtualKeyboard_ = false; }; } // namespace fcitx diff --git a/src/frontend/waylandim/waylandimserverv2.cpp b/src/frontend/waylandim/waylandimserverv2.cpp index d7a24f5d8..ea0be8cc8 100644 --- a/src/frontend/waylandim/waylandimserverv2.cpp +++ b/src/frontend/waylandim/waylandimserverv2.cpp @@ -30,6 +30,7 @@ #include "fcitx/instance.h" #include "virtualinputcontext.h" #include "wayland-text-input-unstable-v3-client-protocol.h" +#include "wayland_public.h" #include "waylandim.h" #include "waylandimserverbase.h" #include "wl_seat.h" @@ -145,6 +146,10 @@ WaylandIMInputContextV2::WaylandIMInputContextV2( : VirtualInputContextGlue(inputContextManager), server_(server), seat_(std::move(seat)), ic_(server->inputMethodManagerV2()->getInputMethod(seat_.get())) { + if (server_->parent()->persistentVirtualKeyboard()) { + vk_.reset(server_->virtualKeyboardManagerV1()->createVirtualKeyboard( + seat_.get())); + } server->add(this, seat_.get()); ic_->surroundingText().connect( [this](const char *text, uint32_t cursor, uint32_t anchor) { @@ -185,16 +190,20 @@ WaylandIMInputContextV2::WaylandIMInputContextV2( } focusOutWrapper(); } - vk_.reset(); - vkReady_ = false; + if (!server_->parent()->persistentVirtualKeyboard()) { + vk_.reset(); + vkReady_ = false; + } } if (pendingActivate_) { pendingActivate_ = false; - vk_.reset(); - vkReady_ = false; - vk_.reset( - server_->virtualKeyboardManagerV1()->createVirtualKeyboard( - seat_.get())); + if (!server_->parent()->persistentVirtualKeyboard()) { + vk_.reset(); + vkReady_ = false; + vk_.reset( + server_->virtualKeyboardManagerV1()->createVirtualKeyboard( + seat_.get())); + } // There can be only one grab. Always release old grab first. // It is possible when switching between two client, there will be // two activate. In that case we will have already one grab. The @@ -445,8 +454,10 @@ void WaylandIMInputContextV2::keymapCallback(uint32_t format, int32_t fd, 1 << xkb_keymap_mod_get_index(server_->keymap_.get(), "Mod5"); if (keymapChanged || !vkReady_) { - vk_->keymap(format, scopeFD.fd(), size); - vkReady_ = true; + if (vk_) { + vk_->keymap(format, scopeFD.fd(), size); + vkReady_ = true; + } } server_->parent_->wayland()->call();