ime-v2: move to new impl
This commit is contained in:
parent
4ed6b69b68
commit
8bcccf9f0f
22 changed files with 1208 additions and 265 deletions
|
|
@ -324,9 +324,6 @@ bool CKeybindManager::onKeyEvent(wlr_keyboard_key_event* e, SKeyboard* pKeyboard
|
|||
return true;
|
||||
}
|
||||
|
||||
if (pKeyboard->isVirtual && g_pInputManager->shouldIgnoreVirtualKeyboard(pKeyboard))
|
||||
return true;
|
||||
|
||||
if (!m_pXKBTranslationState) {
|
||||
Debug::log(ERR, "BUG THIS: m_pXKBTranslationState NULL!");
|
||||
updateXKBTranslationState();
|
||||
|
|
|
|||
|
|
@ -19,26 +19,7 @@
|
|||
#include "../protocols/XDGActivation.hpp"
|
||||
#include "../protocols/IdleNotify.hpp"
|
||||
#include "../protocols/SessionLock.hpp"
|
||||
|
||||
#include "tearing-control-v1.hpp"
|
||||
#include "fractional-scale-v1.hpp"
|
||||
#include "xdg-output-unstable-v1.hpp"
|
||||
#include "cursor-shape-v1.hpp"
|
||||
#include "idle-inhibit-unstable-v1.hpp"
|
||||
#include "relative-pointer-unstable-v1.hpp"
|
||||
#include "xdg-decoration-unstable-v1.hpp"
|
||||
#include "alpha-modifier-v1.hpp"
|
||||
#include "wlr-gamma-control-unstable-v1.hpp"
|
||||
#include "ext-foreign-toplevel-list-v1.hpp"
|
||||
#include "pointer-gestures-unstable-v1.hpp"
|
||||
#include "wlr-foreign-toplevel-management-unstable-v1.hpp"
|
||||
#include "keyboard-shortcuts-inhibit-unstable-v1.hpp"
|
||||
#include "text-input-unstable-v3.hpp"
|
||||
#include "pointer-constraints-unstable-v1.hpp"
|
||||
#include "wlr-output-power-management-unstable-v1.hpp"
|
||||
#include "xdg-activation-v1.hpp"
|
||||
#include "ext-idle-notify-v1.hpp"
|
||||
#include "ext-session-lock-v1.hpp"
|
||||
#include "../protocols/InputMethodV2.hpp"
|
||||
|
||||
CProtocolManager::CProtocolManager() {
|
||||
|
||||
|
|
@ -61,6 +42,7 @@ CProtocolManager::CProtocolManager() {
|
|||
PROTO::activation = std::make_unique<CXDGActivationProtocol>(&xdg_activation_v1_interface, 1, "XDGActivation");
|
||||
PROTO::idle = std::make_unique<CIdleNotifyProtocol>(&ext_idle_notifier_v1_interface, 1, "IdleNotify");
|
||||
PROTO::sessionLock = std::make_unique<CSessionLockProtocol>(&ext_session_lock_manager_v1_interface, 1, "SessionLock");
|
||||
PROTO::ime = std::make_unique<CInputMethodV2Protocol>(&zwp_input_method_manager_v2_interface, 1, "IMEv2");
|
||||
|
||||
// Old protocol implementations.
|
||||
// TODO: rewrite them to use hyprwayland-scanner.
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include "../../protocols/PointerConstraints.hpp"
|
||||
#include "../../protocols/IdleNotify.hpp"
|
||||
#include "../../protocols/SessionLock.hpp"
|
||||
#include "../../protocols/InputMethodV2.hpp"
|
||||
|
||||
CInputManager::CInputManager() {
|
||||
m_sListeners.setCursorShape = PROTO::cursorShape->events.setShape.registerListener([this](std::any data) {
|
||||
|
|
@ -1207,6 +1208,8 @@ void CInputManager::onKeyboardKey(wlr_keyboard_key_event* e, SKeyboard* pKeyboar
|
|||
if (!pKeyboard->enabled)
|
||||
return;
|
||||
|
||||
const bool DISALLOWACTION = pKeyboard->isVirtual && shouldIgnoreVirtualKeyboard(pKeyboard);
|
||||
|
||||
const auto EMAP = std::unordered_map<std::string, std::any>{{"keyboard", pKeyboard}, {"event", e}};
|
||||
EMIT_HOOK_EVENT_CANCELLABLE("keyPress", EMAP);
|
||||
|
||||
|
|
@ -1216,17 +1219,16 @@ void CInputManager::onKeyboardKey(wlr_keyboard_key_event* e, SKeyboard* pKeyboar
|
|||
g_pKeybindManager->dpms("on");
|
||||
}
|
||||
|
||||
bool passEvent = g_pKeybindManager->onKeyEvent(e, pKeyboard);
|
||||
bool passEvent = DISALLOWACTION || g_pKeybindManager->onKeyEvent(e, pKeyboard);
|
||||
|
||||
PROTO::idle->onActivity();
|
||||
|
||||
if (passEvent) {
|
||||
const auto IME = m_sIMERelay.m_pIME.lock();
|
||||
|
||||
const auto PIMEGRAB = m_sIMERelay.getIMEKeyboardGrab(pKeyboard);
|
||||
|
||||
if (PIMEGRAB && PIMEGRAB->pWlrKbGrab && PIMEGRAB->pWlrKbGrab->input_method) {
|
||||
wlr_input_method_keyboard_grab_v2_set_keyboard(PIMEGRAB->pWlrKbGrab, wlr_keyboard_from_input_device(pKeyboard->keyboard));
|
||||
wlr_input_method_keyboard_grab_v2_send_key(PIMEGRAB->pWlrKbGrab, e->time_msec, e->keycode, e->state);
|
||||
if (IME && IME->hasGrab() && !DISALLOWACTION) {
|
||||
IME->setKeyboard(wlr_keyboard_from_input_device(pKeyboard->keyboard));
|
||||
IME->sendKey(e->time_msec, e->keycode, e->state);
|
||||
} else {
|
||||
wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, wlr_keyboard_from_input_device(pKeyboard->keyboard));
|
||||
wlr_seat_keyboard_notify_key(g_pCompositor->m_sSeat.seat, e->time_msec, e->keycode, e->state);
|
||||
|
|
@ -1240,16 +1242,18 @@ void CInputManager::onKeyboardMod(void* data, SKeyboard* pKeyboard) {
|
|||
if (!pKeyboard->enabled)
|
||||
return;
|
||||
|
||||
const auto PIMEGRAB = m_sIMERelay.getIMEKeyboardGrab(pKeyboard);
|
||||
const bool DISALLOWACTION = pKeyboard->isVirtual && shouldIgnoreVirtualKeyboard(pKeyboard);
|
||||
|
||||
const auto ALLMODS = accumulateModsFromAllKBs();
|
||||
|
||||
auto MODS = wlr_keyboard_from_input_device(pKeyboard->keyboard)->modifiers;
|
||||
MODS.depressed = ALLMODS;
|
||||
|
||||
if (PIMEGRAB && PIMEGRAB->pWlrKbGrab && PIMEGRAB->pWlrKbGrab->input_method) {
|
||||
wlr_input_method_keyboard_grab_v2_set_keyboard(PIMEGRAB->pWlrKbGrab, wlr_keyboard_from_input_device(pKeyboard->keyboard));
|
||||
wlr_input_method_keyboard_grab_v2_send_modifiers(PIMEGRAB->pWlrKbGrab, &MODS);
|
||||
const auto IME = m_sIMERelay.m_pIME.lock();
|
||||
|
||||
if (IME && IME->hasGrab() && !DISALLOWACTION) {
|
||||
IME->setKeyboard(wlr_keyboard_from_input_device(pKeyboard->keyboard));
|
||||
IME->sendMods(MODS.depressed, MODS.latched, MODS.locked, MODS.group);
|
||||
} else {
|
||||
wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, wlr_keyboard_from_input_device(pKeyboard->keyboard));
|
||||
wlr_seat_keyboard_notify_modifiers(g_pCompositor->m_sSeat.seat, &MODS);
|
||||
|
|
@ -1273,8 +1277,7 @@ void CInputManager::onKeyboardMod(void* data, SKeyboard* pKeyboard) {
|
|||
|
||||
bool CInputManager::shouldIgnoreVirtualKeyboard(SKeyboard* pKeyboard) {
|
||||
return !pKeyboard ||
|
||||
(m_sIMERelay.m_pKeyboardGrab &&
|
||||
wl_resource_get_client(m_sIMERelay.m_pKeyboardGrab->pWlrKbGrab->resource) == wl_resource_get_client(wlr_input_device_get_virtual_keyboard(pKeyboard->keyboard)->resource));
|
||||
(!m_sIMERelay.m_pIME.expired() && m_sIMERelay.m_pIME.lock()->grabClient() == wl_resource_get_client(wlr_input_device_get_virtual_keyboard(pKeyboard->keyboard)->resource));
|
||||
}
|
||||
|
||||
void CInputManager::refocus() {
|
||||
|
|
|
|||
|
|
@ -2,37 +2,14 @@
|
|||
#include "InputManager.hpp"
|
||||
#include "../../Compositor.hpp"
|
||||
#include "../../protocols/FractionalScale.hpp"
|
||||
#include "../../protocols/InputMethodV2.hpp"
|
||||
|
||||
CInputPopup::CInputPopup(wlr_input_popup_surface_v2* surf) : pWlr(surf) {
|
||||
surface.assign(surf->surface);
|
||||
initCallbacks();
|
||||
}
|
||||
|
||||
static void onCommit(void* owner, void* data) {
|
||||
const auto PPOPUP = (CInputPopup*)owner;
|
||||
PPOPUP->onCommit();
|
||||
}
|
||||
|
||||
static void onMap(void* owner, void* data) {
|
||||
const auto PPOPUP = (CInputPopup*)owner;
|
||||
PPOPUP->onMap();
|
||||
}
|
||||
|
||||
static void onUnmap(void* owner, void* data) {
|
||||
const auto PPOPUP = (CInputPopup*)owner;
|
||||
PPOPUP->onUnmap();
|
||||
}
|
||||
|
||||
static void onDestroy(void* owner, void* data) {
|
||||
const auto PPOPUP = (CInputPopup*)owner;
|
||||
PPOPUP->onDestroy();
|
||||
}
|
||||
|
||||
void CInputPopup::initCallbacks() {
|
||||
hyprListener_commitPopup.initCallback(&pWlr->surface->events.commit, &::onCommit, this, "IME Popup");
|
||||
hyprListener_mapPopup.initCallback(&pWlr->surface->events.map, &::onMap, this, "IME Popup");
|
||||
hyprListener_unmapPopup.initCallback(&pWlr->surface->events.unmap, &::onUnmap, this, "IME Popup");
|
||||
hyprListener_destroyPopup.initCallback(&pWlr->events.destroy, &::onDestroy, this, "IME Popup");
|
||||
CInputPopup::CInputPopup(SP<CInputMethodPopupV2> popup_) : popup(popup_) {
|
||||
listeners.commit = popup_->events.commit.registerListener([this](std::any d) { onCommit(); });
|
||||
listeners.map = popup_->events.map.registerListener([this](std::any d) { onMap(); });
|
||||
listeners.unmap = popup_->events.unmap.registerListener([this](std::any d) { onUnmap(); });
|
||||
listeners.destroy = popup_->events.destroy.registerListener([this](std::any d) { onDestroy(); });
|
||||
surface.assign(popup_->surface());
|
||||
}
|
||||
|
||||
CWLSurface* CInputPopup::queryOwner() {
|
||||
|
|
@ -45,11 +22,6 @@ CWLSurface* CInputPopup::queryOwner() {
|
|||
}
|
||||
|
||||
void CInputPopup::onDestroy() {
|
||||
hyprListener_commitPopup.removeCallback();
|
||||
hyprListener_destroyPopup.removeCallback();
|
||||
hyprListener_mapPopup.removeCallback();
|
||||
hyprListener_unmapPopup.removeCallback();
|
||||
|
||||
g_pInputManager->m_sIMERelay.removePopup(this);
|
||||
}
|
||||
|
||||
|
|
@ -101,7 +73,7 @@ void CInputPopup::damageSurface() {
|
|||
}
|
||||
|
||||
void CInputPopup::updateBox() {
|
||||
if (!surface.wlr()->mapped)
|
||||
if (!popup.lock()->mapped)
|
||||
return;
|
||||
|
||||
const auto OWNER = queryOwner();
|
||||
|
|
@ -142,7 +114,7 @@ void CInputPopup::updateBox() {
|
|||
popupOffset.x -= popupOverflow;
|
||||
|
||||
CBox cursorBoxLocal({-popupOffset.x, -popupOffset.y}, cursorBoxParent.size());
|
||||
wlr_input_popup_surface_v2_send_text_input_rectangle(pWlr, cursorBoxLocal.pWlr());
|
||||
popup.lock()->sendInputRectangle(cursorBoxLocal);
|
||||
|
||||
CBox popupBoxParent(cursorBoxParent.pos() + popupOffset, currentPopupSize);
|
||||
if (popupBoxParent != lastBoxLocal) {
|
||||
|
|
|
|||
|
|
@ -4,17 +4,13 @@
|
|||
#include "../../desktop/WLSurface.hpp"
|
||||
#include "../../macros.hpp"
|
||||
#include "../../helpers/Box.hpp"
|
||||
#include "../../helpers/signal/Listener.hpp"
|
||||
|
||||
struct wlr_input_popup_surface_v2;
|
||||
class CInputMethodPopupV2;
|
||||
|
||||
class CInputPopup {
|
||||
public:
|
||||
CInputPopup(wlr_input_popup_surface_v2* surf);
|
||||
|
||||
void onDestroy();
|
||||
void onMap();
|
||||
void onUnmap();
|
||||
void onCommit();
|
||||
CInputPopup(SP<CInputMethodPopupV2> popup);
|
||||
|
||||
void damageEntire();
|
||||
void damageSurface();
|
||||
|
|
@ -24,18 +20,25 @@ class CInputPopup {
|
|||
CBox globalBox();
|
||||
wlr_surface* getWlrSurface();
|
||||
|
||||
void onCommit();
|
||||
|
||||
private:
|
||||
void initCallbacks();
|
||||
CWLSurface* queryOwner();
|
||||
void updateBox();
|
||||
CWLSurface* queryOwner();
|
||||
void updateBox();
|
||||
|
||||
wlr_input_popup_surface_v2* pWlr = nullptr;
|
||||
CWLSurface surface;
|
||||
CBox lastBoxLocal;
|
||||
uint64_t lastMonitor = -1;
|
||||
void onDestroy();
|
||||
void onMap();
|
||||
void onUnmap();
|
||||
|
||||
DYNLISTENER(mapPopup);
|
||||
DYNLISTENER(unmapPopup);
|
||||
DYNLISTENER(destroyPopup);
|
||||
DYNLISTENER(commitPopup);
|
||||
WP<CInputMethodPopupV2> popup;
|
||||
CWLSurface surface;
|
||||
CBox lastBoxLocal;
|
||||
uint64_t lastMonitor = -1;
|
||||
|
||||
struct {
|
||||
CHyprSignalListener map;
|
||||
CHyprSignalListener unmap;
|
||||
CHyprSignalListener destroy;
|
||||
CHyprSignalListener commit;
|
||||
} listeners;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -2,98 +2,53 @@
|
|||
#include "InputManager.hpp"
|
||||
#include "../../Compositor.hpp"
|
||||
#include "../../protocols/TextInputV3.hpp"
|
||||
#include "../../protocols/InputMethodV2.hpp"
|
||||
|
||||
CInputMethodRelay::CInputMethodRelay() {
|
||||
static auto P = g_pHookSystem->hookDynamic("keyboardFocus", [&](void* self, SCallbackInfo& info, std::any param) { onKeyboardFocus(std::any_cast<wlr_surface*>(param)); });
|
||||
|
||||
listeners.newTIV3 = PROTO::textInputV3->events.newTextInput.registerListener([this](std::any ti) { onNewTextInput(ti); });
|
||||
listeners.newIME = PROTO::ime->events.newIME.registerListener([this](std::any ime) { onNewIME(std::any_cast<SP<CInputMethodV2>>(ime)); });
|
||||
}
|
||||
|
||||
void CInputMethodRelay::onNewIME(wlr_input_method_v2* pIME) {
|
||||
if (m_pWLRIME) {
|
||||
void CInputMethodRelay::onNewIME(SP<CInputMethodV2> pIME) {
|
||||
if (!m_pIME.expired()) {
|
||||
Debug::log(ERR, "Cannot register 2 IMEs at once!");
|
||||
|
||||
wlr_input_method_v2_send_unavailable(pIME);
|
||||
pIME->unavailable();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
m_pWLRIME = pIME;
|
||||
m_pIME = pIME;
|
||||
|
||||
hyprListener_IMECommit.initCallback(
|
||||
&m_pWLRIME->events.commit,
|
||||
[&](void* owner, void* data) {
|
||||
const auto PTI = getFocusedTextInput();
|
||||
const auto PIMR = (CInputMethodRelay*)owner;
|
||||
listeners.commitIME = pIME->events.onCommit.registerListener([this](std::any d) {
|
||||
const auto PTI = getFocusedTextInput();
|
||||
|
||||
if (!PTI) {
|
||||
Debug::log(LOG, "No focused TextInput on IME Commit");
|
||||
return;
|
||||
}
|
||||
if (!PTI) {
|
||||
Debug::log(LOG, "No focused TextInput on IME Commit");
|
||||
return;
|
||||
}
|
||||
|
||||
PTI->updateIMEState(PIMR->m_pWLRIME);
|
||||
},
|
||||
this, "IMERelay");
|
||||
PTI->updateIMEState(m_pIME.lock());
|
||||
});
|
||||
|
||||
hyprListener_IMEDestroy.initCallback(
|
||||
&m_pWLRIME->events.destroy,
|
||||
[&](void* owner, void* data) {
|
||||
m_pWLRIME = nullptr;
|
||||
listeners.destroyIME = pIME->events.destroy.registerListener([this](std::any d) {
|
||||
const auto PTI = getFocusedTextInput();
|
||||
|
||||
hyprListener_IMEDestroy.removeCallback();
|
||||
hyprListener_IMECommit.removeCallback();
|
||||
hyprListener_IMEGrab.removeCallback();
|
||||
hyprListener_IMENewPopup.removeCallback();
|
||||
Debug::log(LOG, "IME Destroy");
|
||||
|
||||
m_pKeyboardGrab.reset(nullptr);
|
||||
if (PTI)
|
||||
PTI->leave();
|
||||
|
||||
const auto PTI = getFocusedTextInput();
|
||||
m_pIME.reset();
|
||||
});
|
||||
|
||||
Debug::log(LOG, "IME Destroy");
|
||||
listeners.newPopup = pIME->events.newPopup.registerListener([this](std::any d) {
|
||||
m_vIMEPopups.emplace_back(std::make_unique<CInputPopup>(std::any_cast<SP<CInputMethodPopupV2>>(d)));
|
||||
|
||||
if (PTI)
|
||||
PTI->leave();
|
||||
},
|
||||
this, "IMERelay");
|
||||
|
||||
hyprListener_IMEGrab.initCallback(
|
||||
&m_pWLRIME->events.grab_keyboard,
|
||||
[&](void* owner, void* data) {
|
||||
Debug::log(LOG, "IME TextInput Keyboard Grab new");
|
||||
|
||||
m_pKeyboardGrab.reset(nullptr);
|
||||
|
||||
m_pKeyboardGrab = std::make_unique<SIMEKbGrab>();
|
||||
|
||||
m_pKeyboardGrab->pKeyboard = wlr_seat_get_keyboard(g_pCompositor->m_sSeat.seat);
|
||||
|
||||
const auto PKBGRAB = (wlr_input_method_keyboard_grab_v2*)data;
|
||||
|
||||
m_pKeyboardGrab->pWlrKbGrab = PKBGRAB;
|
||||
|
||||
wlr_input_method_keyboard_grab_v2_set_keyboard(m_pKeyboardGrab->pWlrKbGrab, m_pKeyboardGrab->pKeyboard);
|
||||
|
||||
m_pKeyboardGrab->hyprListener_grabDestroy.initCallback(
|
||||
&PKBGRAB->events.destroy,
|
||||
[&](void* owner, void* data) {
|
||||
m_pKeyboardGrab->hyprListener_grabDestroy.removeCallback();
|
||||
|
||||
Debug::log(LOG, "IME TextInput Keyboard Grab destroy");
|
||||
|
||||
m_pKeyboardGrab.reset(nullptr);
|
||||
},
|
||||
m_pKeyboardGrab.get(), "IME Keyboard Grab");
|
||||
},
|
||||
this, "IMERelay");
|
||||
|
||||
hyprListener_IMENewPopup.initCallback(
|
||||
&m_pWLRIME->events.new_popup_surface,
|
||||
[&](void* owner, void* data) {
|
||||
m_vIMEPopups.emplace_back(std::make_unique<CInputPopup>((wlr_input_popup_surface_v2*)data));
|
||||
|
||||
Debug::log(LOG, "New input popup");
|
||||
},
|
||||
this, "IMERelay");
|
||||
Debug::log(LOG, "New input popup");
|
||||
});
|
||||
|
||||
if (!g_pCompositor->m_pLastFocus)
|
||||
return;
|
||||
|
|
@ -117,22 +72,6 @@ void CInputMethodRelay::removePopup(CInputPopup* pPopup) {
|
|||
std::erase_if(m_vIMEPopups, [pPopup](const auto& other) { return other.get() == pPopup; });
|
||||
}
|
||||
|
||||
SIMEKbGrab* CInputMethodRelay::getIMEKeyboardGrab(SKeyboard* pKeyboard) {
|
||||
|
||||
if (!m_pWLRIME)
|
||||
return nullptr;
|
||||
|
||||
if (!m_pKeyboardGrab.get())
|
||||
return nullptr;
|
||||
|
||||
const auto VIRTKB = wlr_input_device_get_virtual_keyboard(pKeyboard->keyboard);
|
||||
|
||||
if (VIRTKB && (wl_resource_get_client(VIRTKB->resource) == wl_resource_get_client(m_pKeyboardGrab->pWlrKbGrab->resource)))
|
||||
return nullptr;
|
||||
|
||||
return m_pKeyboardGrab.get();
|
||||
}
|
||||
|
||||
CTextInput* CInputMethodRelay::getFocusedTextInput() {
|
||||
if (!g_pCompositor->m_pLastFocus)
|
||||
return nullptr;
|
||||
|
|
@ -164,33 +103,30 @@ void CInputMethodRelay::updateAllPopups() {
|
|||
}
|
||||
|
||||
void CInputMethodRelay::activateIME(CTextInput* pInput) {
|
||||
if (!m_pWLRIME)
|
||||
if (m_pIME.expired())
|
||||
return;
|
||||
|
||||
wlr_input_method_v2_send_activate(g_pInputManager->m_sIMERelay.m_pWLRIME);
|
||||
m_pIME.lock()->activate();
|
||||
commitIMEState(pInput);
|
||||
}
|
||||
|
||||
void CInputMethodRelay::deactivateIME(CTextInput* pInput) {
|
||||
if (!m_pWLRIME)
|
||||
if (m_pIME.expired())
|
||||
return;
|
||||
|
||||
if (!m_pWLRIME->active)
|
||||
return;
|
||||
|
||||
wlr_input_method_v2_send_deactivate(g_pInputManager->m_sIMERelay.m_pWLRIME);
|
||||
m_pIME.lock()->deactivate();
|
||||
commitIMEState(pInput);
|
||||
}
|
||||
|
||||
void CInputMethodRelay::commitIMEState(CTextInput* pInput) {
|
||||
if (!m_pWLRIME)
|
||||
if (m_pIME.expired())
|
||||
return;
|
||||
|
||||
pInput->commitStateToIME(m_pWLRIME);
|
||||
pInput->commitStateToIME(m_pIME.lock());
|
||||
}
|
||||
|
||||
void CInputMethodRelay::onKeyboardFocus(wlr_surface* pSurface) {
|
||||
if (!m_pWLRIME)
|
||||
if (m_pIME.expired())
|
||||
return;
|
||||
|
||||
if (pSurface == m_pLastKbFocus)
|
||||
|
|
|
|||
|
|
@ -11,39 +11,36 @@
|
|||
class CInputManager;
|
||||
class CHyprRenderer;
|
||||
struct STextInputV1;
|
||||
class CInputMethodV2;
|
||||
|
||||
class CInputMethodRelay {
|
||||
public:
|
||||
CInputMethodRelay();
|
||||
|
||||
void onNewIME(wlr_input_method_v2*);
|
||||
void onNewTextInput(std::any tiv3);
|
||||
void onNewTextInput(STextInputV1* pTIV1);
|
||||
void onNewIME(SP<CInputMethodV2>);
|
||||
void onNewTextInput(std::any tiv3);
|
||||
void onNewTextInput(STextInputV1* pTIV1);
|
||||
|
||||
wlr_input_method_v2* m_pWLRIME = nullptr;
|
||||
void activateIME(CTextInput* pInput);
|
||||
void deactivateIME(CTextInput* pInput);
|
||||
void commitIMEState(CTextInput* pInput);
|
||||
void removeTextInput(CTextInput* pInput);
|
||||
|
||||
void activateIME(CTextInput* pInput);
|
||||
void deactivateIME(CTextInput* pInput);
|
||||
void commitIMEState(CTextInput* pInput);
|
||||
void removeTextInput(CTextInput* pInput);
|
||||
void onKeyboardFocus(wlr_surface*);
|
||||
|
||||
void onKeyboardFocus(wlr_surface*);
|
||||
CTextInput* getFocusedTextInput();
|
||||
|
||||
CTextInput* getFocusedTextInput();
|
||||
void setIMEPopupFocus(CInputPopup*, wlr_surface*);
|
||||
void removePopup(CInputPopup*);
|
||||
|
||||
SIMEKbGrab* getIMEKeyboardGrab(SKeyboard*);
|
||||
CInputPopup* popupFromCoords(const Vector2D& point);
|
||||
CInputPopup* popupFromSurface(const wlr_surface* surface);
|
||||
|
||||
void setIMEPopupFocus(CInputPopup*, wlr_surface*);
|
||||
void removePopup(CInputPopup*);
|
||||
void updateAllPopups();
|
||||
|
||||
CInputPopup* popupFromCoords(const Vector2D& point);
|
||||
CInputPopup* popupFromSurface(const wlr_surface* surface);
|
||||
|
||||
void updateAllPopups();
|
||||
WP<CInputMethodV2> m_pIME;
|
||||
|
||||
private:
|
||||
std::unique_ptr<SIMEKbGrab> m_pKeyboardGrab;
|
||||
|
||||
std::vector<std::unique_ptr<CTextInput>> m_vTextInputs;
|
||||
std::vector<std::unique_ptr<CInputPopup>> m_vIMEPopups;
|
||||
|
||||
|
|
@ -51,14 +48,12 @@ class CInputMethodRelay {
|
|||
|
||||
struct {
|
||||
CHyprSignalListener newTIV3;
|
||||
CHyprSignalListener newIME;
|
||||
CHyprSignalListener commitIME;
|
||||
CHyprSignalListener destroyIME;
|
||||
CHyprSignalListener newPopup;
|
||||
} listeners;
|
||||
|
||||
DYNLISTENER(textInputNew);
|
||||
DYNLISTENER(IMECommit);
|
||||
DYNLISTENER(IMEDestroy);
|
||||
DYNLISTENER(IMEGrab);
|
||||
DYNLISTENER(IMENewPopup);
|
||||
|
||||
friend class CHyprRenderer;
|
||||
friend class CInputManager;
|
||||
friend class CTextInputV1ProtocolManager;
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include "../../protocols/TextInputV1.hpp"
|
||||
#include "../../Compositor.hpp"
|
||||
#include "../../protocols/TextInputV3.hpp"
|
||||
#include "../../protocols/InputMethodV2.hpp"
|
||||
|
||||
CTextInput::CTextInput(STextInputV1* ti) : pV1Input(ti) {
|
||||
ti->pTextInput = this;
|
||||
|
|
@ -67,7 +68,7 @@ void CTextInput::initCallbacks() {
|
|||
void CTextInput::onEnabled(wlr_surface* surfV1) {
|
||||
Debug::log(LOG, "TI ENABLE");
|
||||
|
||||
if (!g_pInputManager->m_sIMERelay.m_pWLRIME) {
|
||||
if (g_pInputManager->m_sIMERelay.m_pIME.expired()) {
|
||||
// Debug::log(WARN, "Enabling TextInput on no IME!");
|
||||
return;
|
||||
}
|
||||
|
|
@ -85,7 +86,7 @@ void CTextInput::onEnabled(wlr_surface* surfV1) {
|
|||
}
|
||||
|
||||
void CTextInput::onDisabled() {
|
||||
if (!g_pInputManager->m_sIMERelay.m_pWLRIME) {
|
||||
if (g_pInputManager->m_sIMERelay.m_pIME.expired()) {
|
||||
// Debug::log(WARN, "Disabling TextInput on no IME!");
|
||||
return;
|
||||
}
|
||||
|
|
@ -103,7 +104,7 @@ void CTextInput::onDisabled() {
|
|||
}
|
||||
|
||||
void CTextInput::onCommit() {
|
||||
if (!g_pInputManager->m_sIMERelay.m_pWLRIME) {
|
||||
if (g_pInputManager->m_sIMERelay.m_pIME.expired()) {
|
||||
// Debug::log(WARN, "Committing TextInput on no IME!");
|
||||
return;
|
||||
}
|
||||
|
|
@ -218,67 +219,66 @@ wl_client* CTextInput::client() {
|
|||
return isV3() ? pV3Input.lock()->client() : pV1Input->client;
|
||||
}
|
||||
|
||||
void CTextInput::commitStateToIME(wlr_input_method_v2* ime) {
|
||||
void CTextInput::commitStateToIME(SP<CInputMethodV2> ime) {
|
||||
if (isV3()) {
|
||||
const auto INPUT = pV3Input.lock();
|
||||
|
||||
if (INPUT->current.surrounding.updated)
|
||||
wlr_input_method_v2_send_surrounding_text(ime, INPUT->current.surrounding.text.c_str(), INPUT->current.surrounding.cursor, INPUT->current.surrounding.anchor);
|
||||
ime->surroundingText(INPUT->current.surrounding.text, INPUT->current.surrounding.cursor, INPUT->current.surrounding.anchor);
|
||||
|
||||
wlr_input_method_v2_send_text_change_cause(ime, INPUT->current.cause);
|
||||
ime->textChangeCause(INPUT->current.cause);
|
||||
|
||||
if (INPUT->current.contentType.updated)
|
||||
wlr_input_method_v2_send_content_type(ime, INPUT->current.contentType.hint, INPUT->current.contentType.purpose);
|
||||
ime->textContentType(INPUT->current.contentType.hint, INPUT->current.contentType.purpose);
|
||||
} else {
|
||||
if (pV1Input->pendingSurrounding.isPending)
|
||||
wlr_input_method_v2_send_surrounding_text(ime, pV1Input->pendingSurrounding.text.c_str(), pV1Input->pendingSurrounding.cursor, pV1Input->pendingSurrounding.anchor);
|
||||
ime->surroundingText(pV1Input->pendingSurrounding.text, pV1Input->pendingSurrounding.cursor, pV1Input->pendingSurrounding.anchor);
|
||||
|
||||
wlr_input_method_v2_send_text_change_cause(ime, 0);
|
||||
ime->textChangeCause(ZWP_TEXT_INPUT_V3_CHANGE_CAUSE_INPUT_METHOD);
|
||||
|
||||
if (pV1Input->pendingContentType.isPending)
|
||||
wlr_input_method_v2_send_content_type(ime, pV1Input->pendingContentType.hint, pV1Input->pendingContentType.purpose);
|
||||
ime->textContentType((zwpTextInputV3ContentHint)pV1Input->pendingContentType.hint, (zwpTextInputV3ContentPurpose)pV1Input->pendingContentType.purpose);
|
||||
}
|
||||
|
||||
g_pInputManager->m_sIMERelay.updateAllPopups();
|
||||
|
||||
wlr_input_method_v2_send_done(ime);
|
||||
ime->done();
|
||||
}
|
||||
|
||||
void CTextInput::updateIMEState(wlr_input_method_v2* ime) {
|
||||
void CTextInput::updateIMEState(SP<CInputMethodV2> ime) {
|
||||
if (isV3()) {
|
||||
const auto INPUT = pV3Input.lock();
|
||||
|
||||
if (ime->current.preedit.text)
|
||||
INPUT->preeditString(ime->current.preedit.text, ime->current.preedit.cursor_begin, ime->current.preedit.cursor_end);
|
||||
if (ime->current.preeditString.committed)
|
||||
INPUT->preeditString(ime->current.preeditString.string, ime->current.preeditString.begin, ime->current.preeditString.end);
|
||||
|
||||
if (ime->current.commit_text)
|
||||
INPUT->commitString(ime->current.commit_text);
|
||||
if (ime->current.committedString.committed)
|
||||
INPUT->commitString(ime->current.committedString.string);
|
||||
|
||||
if (ime->current.delete_.before_length || ime->current.delete_.after_length)
|
||||
INPUT->deleteSurroundingText(ime->current.delete_.before_length, ime->current.delete_.after_length);
|
||||
if (ime->current.deleteSurrounding.committed)
|
||||
INPUT->deleteSurroundingText(ime->current.deleteSurrounding.before, ime->current.deleteSurrounding.after);
|
||||
|
||||
INPUT->sendDone();
|
||||
} else {
|
||||
if (ime->current.preedit.text) {
|
||||
zwp_text_input_v1_send_preedit_cursor(pV1Input->resourceImpl, ime->current.preedit.cursor_begin);
|
||||
zwp_text_input_v1_send_preedit_styling(pV1Input->resourceImpl, 0, std::string(ime->current.preedit.text).length(), ZWP_TEXT_INPUT_V1_PREEDIT_STYLE_HIGHLIGHT);
|
||||
zwp_text_input_v1_send_preedit_string(pV1Input->resourceImpl, pV1Input->serial, ime->current.preedit.text, "");
|
||||
if (ime->current.preeditString.committed) {
|
||||
zwp_text_input_v1_send_preedit_cursor(pV1Input->resourceImpl, ime->current.preeditString.begin);
|
||||
zwp_text_input_v1_send_preedit_styling(pV1Input->resourceImpl, 0, std::string(ime->current.preeditString.string).length(), ZWP_TEXT_INPUT_V1_PREEDIT_STYLE_HIGHLIGHT);
|
||||
zwp_text_input_v1_send_preedit_string(pV1Input->resourceImpl, pV1Input->serial, ime->current.preeditString.string.c_str(), "");
|
||||
} else {
|
||||
zwp_text_input_v1_send_preedit_cursor(pV1Input->resourceImpl, ime->current.preedit.cursor_begin);
|
||||
zwp_text_input_v1_send_preedit_cursor(pV1Input->resourceImpl, ime->current.preeditString.begin);
|
||||
zwp_text_input_v1_send_preedit_styling(pV1Input->resourceImpl, 0, 0, ZWP_TEXT_INPUT_V1_PREEDIT_STYLE_HIGHLIGHT);
|
||||
zwp_text_input_v1_send_preedit_string(pV1Input->resourceImpl, pV1Input->serial, "", "");
|
||||
}
|
||||
|
||||
if (ime->current.commit_text) {
|
||||
zwp_text_input_v1_send_commit_string(pV1Input->resourceImpl, pV1Input->serial, ime->current.commit_text);
|
||||
}
|
||||
if (ime->current.committedString.committed)
|
||||
zwp_text_input_v1_send_commit_string(pV1Input->resourceImpl, pV1Input->serial, ime->current.committedString.string.c_str());
|
||||
|
||||
if (ime->current.delete_.before_length || ime->current.delete_.after_length) {
|
||||
zwp_text_input_v1_send_delete_surrounding_text(pV1Input->resourceImpl, std::string(ime->current.preedit.text).length() - ime->current.delete_.before_length,
|
||||
ime->current.delete_.after_length + ime->current.delete_.before_length);
|
||||
if (ime->current.deleteSurrounding.committed) {
|
||||
zwp_text_input_v1_send_delete_surrounding_text(pV1Input->resourceImpl, std::string(ime->current.preeditString.string).length() - ime->current.deleteSurrounding.before,
|
||||
ime->current.deleteSurrounding.after + ime->current.deleteSurrounding.before);
|
||||
|
||||
if (ime->current.preedit.text)
|
||||
zwp_text_input_v1_send_commit_string(pV1Input->resourceImpl, pV1Input->serial, ime->current.preedit.text);
|
||||
if (ime->current.preeditString.committed)
|
||||
zwp_text_input_v1_send_commit_string(pV1Input->resourceImpl, pV1Input->serial, ime->current.preeditString.string.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ struct wl_client;
|
|||
|
||||
struct STextInputV1;
|
||||
class CTextInputV3;
|
||||
class CInputMethodV2;
|
||||
|
||||
class CTextInput {
|
||||
public:
|
||||
|
|
@ -23,8 +24,8 @@ class CTextInput {
|
|||
void leave();
|
||||
void tiV1Destroyed();
|
||||
wl_client* client();
|
||||
void commitStateToIME(wlr_input_method_v2* ime);
|
||||
void updateIMEState(wlr_input_method_v2* ime);
|
||||
void commitStateToIME(SP<CInputMethodV2> ime);
|
||||
void updateIMEState(SP<CInputMethodV2> ime);
|
||||
|
||||
void onEnabled(wlr_surface* surfV1 = nullptr);
|
||||
void onDisabled();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue