mirror of
https://github.com/hyprwm/Hyprland
synced 2024-12-23 01:09:49 +01:00
IME: Refactor and fixup popups
This commit is contained in:
parent
acf15e5579
commit
5cc4bf699c
12 changed files with 260 additions and 198 deletions
|
@ -1163,21 +1163,6 @@ wlr_surface* CCompositor::vectorToLayerSurface(const Vector2D& pos, std::vector<
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
SIMEPopup* CCompositor::vectorToIMEPopup(const Vector2D& pos, std::list<SIMEPopup>& popups) {
|
||||
for (auto& popup : popups) {
|
||||
auto surface = popup.pSurface->surface;
|
||||
CBox box{
|
||||
popup.realX,
|
||||
popup.realY,
|
||||
surface->current.width,
|
||||
surface->current.height,
|
||||
};
|
||||
if (box.containsPoint(pos))
|
||||
return &popup;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CWindow* CCompositor::getWindowFromSurface(wlr_surface* pSurface) {
|
||||
for (auto& w : m_vWindows) {
|
||||
if (!w->m_bIsMapped || w->m_bFadingOut)
|
||||
|
|
|
@ -135,7 +135,6 @@ class CCompositor {
|
|||
bool monitorExists(CMonitor*);
|
||||
CWindow* vectorToWindowUnified(const Vector2D&, uint8_t properties, CWindow* pIgnoreWindow = nullptr);
|
||||
wlr_surface* vectorToLayerSurface(const Vector2D&, std::vector<std::unique_ptr<SLayerSurface>>*, Vector2D*, SLayerSurface**);
|
||||
SIMEPopup* vectorToIMEPopup(const Vector2D& pos, std::list<SIMEPopup>& popups);
|
||||
wlr_surface* vectorWindowToSurface(const Vector2D&, CWindow*, Vector2D& sl);
|
||||
Vector2D vectorToSurfaceLocal(const Vector2D&, CWindow*, wlr_surface*);
|
||||
CMonitor* getMonitorFromOutput(wlr_output*);
|
||||
|
|
|
@ -126,12 +126,6 @@ namespace Events {
|
|||
LISTENER(newTextInput);
|
||||
LISTENER(newVirtualKeyboard);
|
||||
|
||||
// IME Popups
|
||||
DYNLISTENFUNC(mapInputPopup);
|
||||
DYNLISTENFUNC(unmapInputPopup);
|
||||
DYNLISTENFUNC(commitInputPopup);
|
||||
DYNLISTENFUNC(destroyInputPopup);
|
||||
|
||||
// Touch
|
||||
LISTENER(touchBegin);
|
||||
LISTENER(touchEnd);
|
||||
|
|
|
@ -298,26 +298,6 @@ struct SIMEKbGrab {
|
|||
DYNLISTENER(grabDestroy);
|
||||
};
|
||||
|
||||
struct SIMEPopup {
|
||||
wlr_input_popup_surface_v2* pSurface = nullptr;
|
||||
|
||||
int x, y;
|
||||
int realX, realY;
|
||||
bool visible;
|
||||
CBox lastBox;
|
||||
|
||||
DYNLISTENER(mapPopup);
|
||||
DYNLISTENER(unmapPopup);
|
||||
DYNLISTENER(destroyPopup);
|
||||
DYNLISTENER(commitPopup);
|
||||
|
||||
DYNLISTENER(focusedSurfaceUnmap);
|
||||
|
||||
bool operator==(const SIMEPopup& other) const {
|
||||
return pSurface == other.pSurface;
|
||||
}
|
||||
};
|
||||
|
||||
struct STouchDevice {
|
||||
wlr_input_device* pWlrDevice = nullptr;
|
||||
|
||||
|
|
|
@ -215,10 +215,10 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
|||
|
||||
// also IME popups
|
||||
if (!foundSurface) {
|
||||
auto popup = g_pCompositor->vectorToIMEPopup(mouseCoords, m_sIMERelay.m_lIMEPopups);
|
||||
auto popup = g_pInputManager->m_sIMERelay.popupFromCoords(mouseCoords);
|
||||
if (popup) {
|
||||
foundSurface = popup->pSurface->surface;
|
||||
surfacePos = Vector2D(popup->realX, popup->realY);
|
||||
foundSurface = popup->getWlrSurface();
|
||||
surfacePos = popup->globalBox().pos();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
168
src/managers/input/InputMethodPopup.cpp
Normal file
168
src/managers/input/InputMethodPopup.cpp
Normal file
|
@ -0,0 +1,168 @@
|
|||
#include "InputMethodPopup.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");
|
||||
}
|
||||
|
||||
CWLSurface* CInputPopup::queryOwner() {
|
||||
const auto FOCUSED = g_pInputManager->m_sIMERelay.getFocusedTextInput();
|
||||
|
||||
if (!FOCUSED)
|
||||
return nullptr;
|
||||
|
||||
return CWLSurface::surfaceFromWlr(FOCUSED->focusedSurface());
|
||||
}
|
||||
|
||||
void CInputPopup::onDestroy() {
|
||||
hyprListener_commitPopup.removeCallback();
|
||||
hyprListener_destroyPopup.removeCallback();
|
||||
hyprListener_mapPopup.removeCallback();
|
||||
hyprListener_unmapPopup.removeCallback();
|
||||
|
||||
g_pInputManager->m_sIMERelay.removePopup(this);
|
||||
}
|
||||
|
||||
void CInputPopup::onMap() {
|
||||
Debug::log(LOG, "Mapped an IME Popup");
|
||||
|
||||
updateBox();
|
||||
damageEntire();
|
||||
}
|
||||
|
||||
void CInputPopup::onUnmap() {
|
||||
Debug::log(LOG, "Unmapped an IME Popup");
|
||||
|
||||
damageEntire();
|
||||
}
|
||||
|
||||
void CInputPopup::onCommit() {
|
||||
updateBox();
|
||||
}
|
||||
|
||||
void CInputPopup::damageEntire() {
|
||||
const auto OWNER = queryOwner();
|
||||
|
||||
if (!OWNER) {
|
||||
Debug::log(ERR, "BUG THIS: No owner in imepopup::damageentire");
|
||||
return;
|
||||
}
|
||||
|
||||
Vector2D pos = OWNER->getSurfaceBoxGlobal().value_or(CBox{0, 0, 0, 0}).pos();
|
||||
CBox global = lastBoxLocal.copy().translate(pos);
|
||||
|
||||
g_pHyprRenderer->damageBox(&global);
|
||||
}
|
||||
|
||||
void CInputPopup::damageSurface() {
|
||||
const auto OWNER = queryOwner();
|
||||
|
||||
if (!OWNER) {
|
||||
Debug::log(ERR, "BUG THIS: No owner in imepopup::damagesurface");
|
||||
return;
|
||||
}
|
||||
|
||||
Vector2D pos = OWNER->getSurfaceBoxGlobal().value_or(CBox{0, 0, 0, 0}).pos() + lastBoxLocal.pos();
|
||||
g_pHyprRenderer->damageSurface(surface.wlr(), pos.x, pos.y);
|
||||
}
|
||||
|
||||
void CInputPopup::updateBox() {
|
||||
if (!surface.wlr()->mapped)
|
||||
return;
|
||||
|
||||
const auto OWNER = queryOwner();
|
||||
const auto PFOCUSEDTI = g_pInputManager->m_sIMERelay.getFocusedTextInput();
|
||||
|
||||
if (!PFOCUSEDTI)
|
||||
return;
|
||||
|
||||
bool cursorRect = PFOCUSEDTI->hasCursorRectangle();
|
||||
CBox cursorBoxLocal = PFOCUSEDTI->cursorBox();
|
||||
|
||||
CBox parentBox;
|
||||
|
||||
if (!OWNER)
|
||||
parentBox = {0, 0, 500, 500};
|
||||
else
|
||||
parentBox = OWNER->getSurfaceBoxGlobal().value_or(CBox{0, 0, 500, 500});
|
||||
|
||||
if (!cursorRect) {
|
||||
Vector2D coords = OWNER ? OWNER->getSurfaceBoxGlobal().value_or(CBox{0, 0, 500, 500}).pos() : Vector2D{0, 0};
|
||||
parentBox = {coords, {500, 500}};
|
||||
cursorBoxLocal = {0, 0, (int)parentBox.w, (int)parentBox.h};
|
||||
}
|
||||
|
||||
if (cursorBoxLocal != lastBoxLocal)
|
||||
damageEntire();
|
||||
|
||||
CMonitor* pMonitor = g_pCompositor->getMonitorFromVector(parentBox.middle());
|
||||
|
||||
if (cursorBoxLocal.y + parentBox.y + surface.wlr()->current.height + cursorBoxLocal.height > pMonitor->vecPosition.y + pMonitor->vecSize.y)
|
||||
cursorBoxLocal.y -= surface.wlr()->current.height + cursorBoxLocal.height;
|
||||
|
||||
if (cursorBoxLocal.x + parentBox.x + surface.wlr()->current.width > pMonitor->vecPosition.x + pMonitor->vecSize.x)
|
||||
cursorBoxLocal.x -= (cursorBoxLocal.x + parentBox.x + surface.wlr()->current.width) - (pMonitor->vecPosition.x + pMonitor->vecSize.x);
|
||||
|
||||
lastBoxLocal = cursorBoxLocal;
|
||||
|
||||
wlr_input_popup_surface_v2_send_text_input_rectangle(pWlr, cursorBoxLocal.pWlr());
|
||||
|
||||
damageSurface();
|
||||
|
||||
if (const auto PM = g_pCompositor->getMonitorFromCursor(); PM && PM->ID != lastMonitor) {
|
||||
const auto PML = g_pCompositor->getMonitorFromID(lastMonitor);
|
||||
|
||||
if (PML)
|
||||
wlr_surface_send_leave(surface.wlr(), PML->output);
|
||||
|
||||
wlr_surface_send_enter(surface.wlr(), PM->output);
|
||||
|
||||
lastMonitor = PM->ID;
|
||||
}
|
||||
}
|
||||
|
||||
CBox CInputPopup::globalBox() {
|
||||
const auto OWNER = queryOwner();
|
||||
|
||||
if (!OWNER) {
|
||||
Debug::log(ERR, "BUG THIS: No owner in imepopup::globalbox");
|
||||
return {};
|
||||
}
|
||||
|
||||
return lastBoxLocal.copy().translate(OWNER->getSurfaceBoxGlobal().value_or(CBox{0, 0, 0, 0}).pos());
|
||||
}
|
||||
|
||||
bool CInputPopup::isVecInPopup(const Vector2D& point) {
|
||||
return globalBox().containsPoint(point);
|
||||
}
|
||||
|
||||
wlr_surface* CInputPopup::getWlrSurface() {
|
||||
return surface.wlr();
|
||||
}
|
41
src/managers/input/InputMethodPopup.hpp
Normal file
41
src/managers/input/InputMethodPopup.hpp
Normal file
|
@ -0,0 +1,41 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../helpers/WLListener.hpp"
|
||||
#include "../../desktop/WLSurface.hpp"
|
||||
#include "../../macros.hpp"
|
||||
#include "../../helpers/Box.hpp"
|
||||
|
||||
struct wlr_input_popup_surface_v2;
|
||||
|
||||
class CInputPopup {
|
||||
public:
|
||||
CInputPopup(wlr_input_popup_surface_v2* surf);
|
||||
|
||||
void onDestroy();
|
||||
void onMap();
|
||||
void onUnmap();
|
||||
void onCommit();
|
||||
|
||||
void damageEntire();
|
||||
void damageSurface();
|
||||
|
||||
bool isVecInPopup(const Vector2D& point);
|
||||
|
||||
CBox globalBox();
|
||||
wlr_surface* getWlrSurface();
|
||||
|
||||
private:
|
||||
void initCallbacks();
|
||||
CWLSurface* queryOwner();
|
||||
void updateBox();
|
||||
|
||||
wlr_input_popup_surface_v2* pWlr = nullptr;
|
||||
CWLSurface surface;
|
||||
CBox lastBoxLocal;
|
||||
uint64_t lastMonitor = -1;
|
||||
|
||||
DYNLISTENER(mapPopup);
|
||||
DYNLISTENER(unmapPopup);
|
||||
DYNLISTENER(destroyPopup);
|
||||
DYNLISTENER(commitPopup);
|
||||
};
|
|
@ -86,14 +86,7 @@ void CInputMethodRelay::onNewIME(wlr_input_method_v2* pIME) {
|
|||
hyprListener_IMENewPopup.initCallback(
|
||||
&m_pWLRIME->events.new_popup_surface,
|
||||
[&](void* owner, void* data) {
|
||||
const auto PNEWPOPUP = &m_lIMEPopups.emplace_back();
|
||||
|
||||
PNEWPOPUP->pSurface = (wlr_input_popup_surface_v2*)data;
|
||||
|
||||
PNEWPOPUP->hyprListener_commitPopup.initCallback(&PNEWPOPUP->pSurface->surface->events.commit, &Events::listener_commitInputPopup, PNEWPOPUP, "IME Popup");
|
||||
PNEWPOPUP->hyprListener_mapPopup.initCallback(&PNEWPOPUP->pSurface->surface->events.map, &Events::listener_mapInputPopup, PNEWPOPUP, "IME Popup");
|
||||
PNEWPOPUP->hyprListener_unmapPopup.initCallback(&PNEWPOPUP->pSurface->surface->events.unmap, &Events::listener_unmapInputPopup, PNEWPOPUP, "IME Popup");
|
||||
PNEWPOPUP->hyprListener_destroyPopup.initCallback(&PNEWPOPUP->pSurface->events.destroy, &Events::listener_destroyInputPopup, PNEWPOPUP, "IME Popup");
|
||||
m_vIMEPopups.emplace_back(std::make_unique<CInputPopup>((wlr_input_popup_surface_v2*)data));
|
||||
|
||||
Debug::log(LOG, "New input popup");
|
||||
},
|
||||
|
@ -103,132 +96,12 @@ void CInputMethodRelay::onNewIME(wlr_input_method_v2* pIME) {
|
|||
PTI->enter(PTI->focusedSurface());
|
||||
}
|
||||
|
||||
void CInputMethodRelay::updateInputPopup(SIMEPopup* pPopup) {
|
||||
if (!pPopup->pSurface->surface->mapped)
|
||||
return;
|
||||
|
||||
// damage last known pos & size
|
||||
g_pHyprRenderer->damageBox(&pPopup->lastBox);
|
||||
|
||||
const auto PFOCUSEDTI = getFocusedTextInput();
|
||||
|
||||
if (!PFOCUSEDTI || !PFOCUSEDTI->focusedSurface())
|
||||
return;
|
||||
|
||||
bool cursorRect = PFOCUSEDTI->hasCursorRectangle();
|
||||
const auto PFOCUSEDSURFACE = PFOCUSEDTI->focusedSurface();
|
||||
CBox cursorBox = PFOCUSEDTI->cursorBox();
|
||||
|
||||
CBox parentBox;
|
||||
|
||||
const auto PSURFACE = CWLSurface::surfaceFromWlr(PFOCUSEDSURFACE);
|
||||
|
||||
if (!PSURFACE)
|
||||
parentBox = {0, 0, 200, 200};
|
||||
else
|
||||
parentBox = PSURFACE->getSurfaceBoxGlobal().value_or(CBox{0, 0, 200, 200});
|
||||
|
||||
if (!cursorRect)
|
||||
cursorBox = {0, 0, (int)parentBox.w, (int)parentBox.h};
|
||||
|
||||
CMonitor* pMonitor = g_pCompositor->getMonitorFromVector(cursorBox.middle());
|
||||
|
||||
if (cursorBox.y + parentBox.y + pPopup->pSurface->surface->current.height + cursorBox.height > pMonitor->vecPosition.y + pMonitor->vecSize.y)
|
||||
cursorBox.y -= pPopup->pSurface->surface->current.height + cursorBox.height;
|
||||
|
||||
if (cursorBox.x + parentBox.x + pPopup->pSurface->surface->current.width > pMonitor->vecPosition.x + pMonitor->vecSize.x)
|
||||
cursorBox.x -= (cursorBox.x + parentBox.x + pPopup->pSurface->surface->current.width) - (pMonitor->vecPosition.x + pMonitor->vecSize.x);
|
||||
|
||||
pPopup->x = cursorBox.x;
|
||||
pPopup->y = cursorBox.y + cursorBox.height;
|
||||
|
||||
pPopup->realX = cursorBox.x + parentBox.x;
|
||||
pPopup->realY = cursorBox.y + parentBox.y + cursorBox.height;
|
||||
|
||||
pPopup->lastBox = cursorBox;
|
||||
|
||||
wlr_input_popup_surface_v2_send_text_input_rectangle(pPopup->pSurface, cursorBox.pWlr());
|
||||
|
||||
damagePopup(pPopup);
|
||||
void CInputMethodRelay::setIMEPopupFocus(CInputPopup* pPopup, wlr_surface* pSurface) {
|
||||
pPopup->onCommit();
|
||||
}
|
||||
|
||||
void CInputMethodRelay::setIMEPopupFocus(SIMEPopup* pPopup, wlr_surface* pSurface) {
|
||||
updateInputPopup(pPopup);
|
||||
}
|
||||
|
||||
void Events::listener_mapInputPopup(void* owner, void* data) {
|
||||
const auto PPOPUP = (SIMEPopup*)owner;
|
||||
|
||||
Debug::log(LOG, "Mapped an IME Popup");
|
||||
|
||||
g_pInputManager->m_sIMERelay.updateInputPopup(PPOPUP);
|
||||
|
||||
if (const auto PMONITOR = g_pCompositor->getMonitorFromVector(PPOPUP->lastBox.middle()); PMONITOR)
|
||||
wlr_surface_send_enter(PPOPUP->pSurface->surface, PMONITOR->output);
|
||||
}
|
||||
|
||||
void Events::listener_unmapInputPopup(void* owner, void* data) {
|
||||
const auto PPOPUP = (SIMEPopup*)owner;
|
||||
|
||||
Debug::log(LOG, "Unmapped an IME Popup");
|
||||
|
||||
g_pHyprRenderer->damageBox(&PPOPUP->lastBox);
|
||||
|
||||
g_pInputManager->m_sIMERelay.updateInputPopup(PPOPUP);
|
||||
}
|
||||
|
||||
void Events::listener_destroyInputPopup(void* owner, void* data) {
|
||||
const auto PPOPUP = (SIMEPopup*)owner;
|
||||
|
||||
Debug::log(LOG, "Removed an IME Popup");
|
||||
|
||||
PPOPUP->hyprListener_commitPopup.removeCallback();
|
||||
PPOPUP->hyprListener_destroyPopup.removeCallback();
|
||||
PPOPUP->hyprListener_focusedSurfaceUnmap.removeCallback();
|
||||
PPOPUP->hyprListener_mapPopup.removeCallback();
|
||||
PPOPUP->hyprListener_unmapPopup.removeCallback();
|
||||
|
||||
g_pInputManager->m_sIMERelay.removePopup(PPOPUP);
|
||||
}
|
||||
|
||||
void Events::listener_commitInputPopup(void* owner, void* data) {
|
||||
const auto PPOPUP = (SIMEPopup*)owner;
|
||||
|
||||
g_pInputManager->m_sIMERelay.updateInputPopup(PPOPUP);
|
||||
}
|
||||
|
||||
void CInputMethodRelay::removePopup(SIMEPopup* pPopup) {
|
||||
m_lIMEPopups.remove(*pPopup);
|
||||
}
|
||||
|
||||
void CInputMethodRelay::damagePopup(SIMEPopup* pPopup) {
|
||||
if (!pPopup->pSurface->surface->mapped)
|
||||
return;
|
||||
|
||||
const auto PFOCUSEDTI = getFocusedTextInput();
|
||||
|
||||
if (!PFOCUSEDTI || !PFOCUSEDTI->focusedSurface())
|
||||
return;
|
||||
|
||||
Vector2D parentPos;
|
||||
|
||||
const auto PFOCUSEDSURFACE = PFOCUSEDTI->focusedSurface();
|
||||
|
||||
if (wlr_layer_surface_v1_try_from_wlr_surface(PFOCUSEDSURFACE)) {
|
||||
const auto PLS = g_pCompositor->getLayerSurfaceFromWlr(wlr_layer_surface_v1_try_from_wlr_surface(PFOCUSEDSURFACE));
|
||||
|
||||
if (PLS) {
|
||||
parentPos = Vector2D(PLS->geometry.x, PLS->geometry.y) + g_pCompositor->getMonitorFromID(PLS->monitorID)->vecPosition;
|
||||
}
|
||||
} else {
|
||||
const auto PWINDOW = g_pCompositor->getWindowFromSurface(PFOCUSEDSURFACE);
|
||||
|
||||
if (PWINDOW) {
|
||||
parentPos = PWINDOW->m_vRealPosition.goal();
|
||||
}
|
||||
}
|
||||
|
||||
g_pHyprRenderer->damageSurface(pPopup->pSurface->surface, parentPos.x + pPopup->x, parentPos.y + pPopup->y);
|
||||
void CInputMethodRelay::removePopup(CInputPopup* pPopup) {
|
||||
std::erase_if(m_vIMEPopups, [pPopup](const auto& other) { return other.get() == pPopup; });
|
||||
}
|
||||
|
||||
SIMEKbGrab* CInputMethodRelay::getIMEKeyboardGrab(SKeyboard* pKeyboard) {
|
||||
|
@ -268,7 +141,13 @@ void CInputMethodRelay::onNewTextInput(STextInputV1* pTIV1) {
|
|||
}
|
||||
|
||||
void CInputMethodRelay::removeTextInput(CTextInput* pInput) {
|
||||
m_vTextInputs.remove_if([&](const auto& other) { return other.get() == pInput; });
|
||||
std::erase_if(m_vTextInputs, [pInput](const auto& other) { return other.get() == pInput; });
|
||||
}
|
||||
|
||||
void CInputMethodRelay::updateAllPopups() {
|
||||
for (auto& p : m_vIMEPopups) {
|
||||
p->onCommit();
|
||||
}
|
||||
}
|
||||
|
||||
void CInputMethodRelay::commitIMEState(CTextInput* pInput) {
|
||||
|
@ -304,3 +183,12 @@ void CInputMethodRelay::onKeyboardFocus(wlr_surface* pSurface) {
|
|||
ti->enter(pSurface);
|
||||
}
|
||||
}
|
||||
|
||||
CInputPopup* CInputMethodRelay::popupFromCoords(const Vector2D& point) {
|
||||
for (auto& p : m_vIMEPopups) {
|
||||
if (p->isVecInPopup(point))
|
||||
return p.get();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -4,8 +4,10 @@
|
|||
#include "../../defines.hpp"
|
||||
#include "../../helpers/WLClasses.hpp"
|
||||
#include "TextInput.hpp"
|
||||
#include "InputMethodPopup.hpp"
|
||||
|
||||
class CInputManager;
|
||||
class CHyprRenderer;
|
||||
struct STextInputV1;
|
||||
|
||||
class CInputMethodRelay {
|
||||
|
@ -27,18 +29,20 @@ class CInputMethodRelay {
|
|||
|
||||
SIMEKbGrab* getIMEKeyboardGrab(SKeyboard*);
|
||||
|
||||
void setIMEPopupFocus(SIMEPopup*, wlr_surface*);
|
||||
void updateInputPopup(SIMEPopup*);
|
||||
void damagePopup(SIMEPopup*);
|
||||
void removePopup(SIMEPopup*);
|
||||
void setIMEPopupFocus(CInputPopup*, wlr_surface*);
|
||||
void removePopup(CInputPopup*);
|
||||
|
||||
CInputPopup* popupFromCoords(const Vector2D& point);
|
||||
|
||||
void updateAllPopups();
|
||||
|
||||
private:
|
||||
std::unique_ptr<SIMEKbGrab> m_pKeyboardGrab;
|
||||
std::unique_ptr<SIMEKbGrab> m_pKeyboardGrab;
|
||||
|
||||
std::list<std::unique_ptr<CTextInput>> m_vTextInputs;
|
||||
std::list<SIMEPopup> m_lIMEPopups;
|
||||
std::vector<std::unique_ptr<CTextInput>> m_vTextInputs;
|
||||
std::vector<std::unique_ptr<CInputPopup>> m_vIMEPopups;
|
||||
|
||||
wlr_surface* m_pLastKbFocus = nullptr;
|
||||
wlr_surface* m_pLastKbFocus = nullptr;
|
||||
|
||||
DYNLISTENER(textInputNew);
|
||||
DYNLISTENER(IMECommit);
|
||||
|
@ -50,4 +54,5 @@ class CInputMethodRelay {
|
|||
friend class CInputManager;
|
||||
friend class CTextInputV1ProtocolManager;
|
||||
friend struct CTextInput;
|
||||
friend class CHyprRenderer;
|
||||
};
|
||||
|
|
|
@ -222,9 +222,7 @@ void CTextInput::commitStateToIME(wlr_input_method_v2* ime) {
|
|||
wlr_input_method_v2_send_content_type(ime, pV1Input->pendingContentType.hint, pV1Input->pendingContentType.purpose);
|
||||
}
|
||||
|
||||
for (auto& p : g_pInputManager->m_sIMERelay.m_lIMEPopups) {
|
||||
g_pInputManager->m_sIMERelay.updateInputPopup(&p);
|
||||
}
|
||||
g_pInputManager->m_sIMERelay.updateAllPopups();
|
||||
|
||||
wlr_input_method_v2_send_done(ime);
|
||||
}
|
||||
|
|
|
@ -679,16 +679,20 @@ void CHyprRenderer::renderLayer(SLayerSurface* pLayer, CMonitor* pMonitor, times
|
|||
g_pHyprOpenGL->m_RenderData.clipBox = {};
|
||||
}
|
||||
|
||||
void CHyprRenderer::renderIMEPopup(SIMEPopup* pPopup, CMonitor* pMonitor, timespec* time) {
|
||||
SRenderData renderdata = {pMonitor, time, pPopup->realX, pPopup->realY};
|
||||
void CHyprRenderer::renderIMEPopup(CInputPopup* pPopup, CMonitor* pMonitor, timespec* time) {
|
||||
const auto POS = pPopup->globalBox().pos();
|
||||
|
||||
SRenderData renderdata = {pMonitor, time, POS.x, POS.y};
|
||||
|
||||
const auto SURF = pPopup->getWlrSurface();
|
||||
|
||||
renderdata.blur = false;
|
||||
renderdata.surface = pPopup->pSurface->surface;
|
||||
renderdata.surface = SURF;
|
||||
renderdata.decorate = false;
|
||||
renderdata.w = pPopup->pSurface->surface->current.width;
|
||||
renderdata.h = pPopup->pSurface->surface->current.height;
|
||||
renderdata.w = SURF->current.width;
|
||||
renderdata.h = SURF->current.height;
|
||||
|
||||
wlr_surface_for_each_surface(pPopup->pSurface->surface, renderSurface, &renderdata);
|
||||
wlr_surface_for_each_surface(SURF, renderSurface, &renderdata);
|
||||
}
|
||||
|
||||
void CHyprRenderer::renderSessionLockSurface(SSessionLockSurface* pSurface, CMonitor* pMonitor, timespec* time) {
|
||||
|
@ -830,8 +834,8 @@ void CHyprRenderer::renderAllClientsForWorkspace(CMonitor* pMonitor, CWorkspace*
|
|||
}
|
||||
|
||||
// Render IME popups
|
||||
for (auto& imep : g_pInputManager->m_sIMERelay.m_lIMEPopups) {
|
||||
renderIMEPopup(&imep, pMonitor, time);
|
||||
for (auto& imep : g_pInputManager->m_sIMERelay.m_vIMEPopups) {
|
||||
renderIMEPopup(imep.get(), pMonitor, time);
|
||||
}
|
||||
|
||||
for (auto& ls : pMonitor->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]) {
|
||||
|
|
|
@ -115,7 +115,7 @@ class CHyprRenderer {
|
|||
void renderLayer(SLayerSurface*, CMonitor*, timespec*);
|
||||
void renderSessionLockSurface(SSessionLockSurface*, CMonitor*, timespec*);
|
||||
void renderDragIcon(CMonitor*, timespec*);
|
||||
void renderIMEPopup(SIMEPopup*, CMonitor*, timespec*);
|
||||
void renderIMEPopup(CInputPopup*, CMonitor*, timespec*);
|
||||
void renderWorkspace(CMonitor* pMonitor, CWorkspace* pWorkspace, timespec* now, const CBox& geometry);
|
||||
void renderAllClientsForWorkspace(CMonitor* pMonitor, CWorkspace* pWorkspace, timespec* now, const Vector2D& translate = {0, 0}, const float& scale = 1.f);
|
||||
|
||||
|
|
Loading…
Reference in a new issue