mirror of
https://github.com/hyprwm/Hyprland
synced 2024-11-02 12:26:00 +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;
|
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) {
|
CWindow* CCompositor::getWindowFromSurface(wlr_surface* pSurface) {
|
||||||
for (auto& w : m_vWindows) {
|
for (auto& w : m_vWindows) {
|
||||||
if (!w->m_bIsMapped || w->m_bFadingOut)
|
if (!w->m_bIsMapped || w->m_bFadingOut)
|
||||||
|
|
|
@ -135,7 +135,6 @@ class CCompositor {
|
||||||
bool monitorExists(CMonitor*);
|
bool monitorExists(CMonitor*);
|
||||||
CWindow* vectorToWindowUnified(const Vector2D&, uint8_t properties, CWindow* pIgnoreWindow = nullptr);
|
CWindow* vectorToWindowUnified(const Vector2D&, uint8_t properties, CWindow* pIgnoreWindow = nullptr);
|
||||||
wlr_surface* vectorToLayerSurface(const Vector2D&, std::vector<std::unique_ptr<SLayerSurface>>*, Vector2D*, SLayerSurface**);
|
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);
|
wlr_surface* vectorWindowToSurface(const Vector2D&, CWindow*, Vector2D& sl);
|
||||||
Vector2D vectorToSurfaceLocal(const Vector2D&, CWindow*, wlr_surface*);
|
Vector2D vectorToSurfaceLocal(const Vector2D&, CWindow*, wlr_surface*);
|
||||||
CMonitor* getMonitorFromOutput(wlr_output*);
|
CMonitor* getMonitorFromOutput(wlr_output*);
|
||||||
|
|
|
@ -126,12 +126,6 @@ namespace Events {
|
||||||
LISTENER(newTextInput);
|
LISTENER(newTextInput);
|
||||||
LISTENER(newVirtualKeyboard);
|
LISTENER(newVirtualKeyboard);
|
||||||
|
|
||||||
// IME Popups
|
|
||||||
DYNLISTENFUNC(mapInputPopup);
|
|
||||||
DYNLISTENFUNC(unmapInputPopup);
|
|
||||||
DYNLISTENFUNC(commitInputPopup);
|
|
||||||
DYNLISTENFUNC(destroyInputPopup);
|
|
||||||
|
|
||||||
// Touch
|
// Touch
|
||||||
LISTENER(touchBegin);
|
LISTENER(touchBegin);
|
||||||
LISTENER(touchEnd);
|
LISTENER(touchEnd);
|
||||||
|
|
|
@ -298,26 +298,6 @@ struct SIMEKbGrab {
|
||||||
DYNLISTENER(grabDestroy);
|
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 {
|
struct STouchDevice {
|
||||||
wlr_input_device* pWlrDevice = nullptr;
|
wlr_input_device* pWlrDevice = nullptr;
|
||||||
|
|
||||||
|
|
|
@ -215,10 +215,10 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||||
|
|
||||||
// also IME popups
|
// also IME popups
|
||||||
if (!foundSurface) {
|
if (!foundSurface) {
|
||||||
auto popup = g_pCompositor->vectorToIMEPopup(mouseCoords, m_sIMERelay.m_lIMEPopups);
|
auto popup = g_pInputManager->m_sIMERelay.popupFromCoords(mouseCoords);
|
||||||
if (popup) {
|
if (popup) {
|
||||||
foundSurface = popup->pSurface->surface;
|
foundSurface = popup->getWlrSurface();
|
||||||
surfacePos = Vector2D(popup->realX, popup->realY);
|
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(
|
hyprListener_IMENewPopup.initCallback(
|
||||||
&m_pWLRIME->events.new_popup_surface,
|
&m_pWLRIME->events.new_popup_surface,
|
||||||
[&](void* owner, void* data) {
|
[&](void* owner, void* data) {
|
||||||
const auto PNEWPOPUP = &m_lIMEPopups.emplace_back();
|
m_vIMEPopups.emplace_back(std::make_unique<CInputPopup>((wlr_input_popup_surface_v2*)data));
|
||||||
|
|
||||||
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");
|
|
||||||
|
|
||||||
Debug::log(LOG, "New input popup");
|
Debug::log(LOG, "New input popup");
|
||||||
},
|
},
|
||||||
|
@ -103,132 +96,12 @@ void CInputMethodRelay::onNewIME(wlr_input_method_v2* pIME) {
|
||||||
PTI->enter(PTI->focusedSurface());
|
PTI->enter(PTI->focusedSurface());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CInputMethodRelay::updateInputPopup(SIMEPopup* pPopup) {
|
void CInputMethodRelay::setIMEPopupFocus(CInputPopup* pPopup, wlr_surface* pSurface) {
|
||||||
if (!pPopup->pSurface->surface->mapped)
|
pPopup->onCommit();
|
||||||
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(SIMEPopup* pPopup, wlr_surface* pSurface) {
|
void CInputMethodRelay::removePopup(CInputPopup* pPopup) {
|
||||||
updateInputPopup(pPopup);
|
std::erase_if(m_vIMEPopups, [pPopup](const auto& other) { return other.get() == 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SIMEKbGrab* CInputMethodRelay::getIMEKeyboardGrab(SKeyboard* pKeyboard) {
|
SIMEKbGrab* CInputMethodRelay::getIMEKeyboardGrab(SKeyboard* pKeyboard) {
|
||||||
|
@ -268,7 +141,13 @@ void CInputMethodRelay::onNewTextInput(STextInputV1* pTIV1) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CInputMethodRelay::removeTextInput(CTextInput* pInput) {
|
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) {
|
void CInputMethodRelay::commitIMEState(CTextInput* pInput) {
|
||||||
|
@ -304,3 +183,12 @@ void CInputMethodRelay::onKeyboardFocus(wlr_surface* pSurface) {
|
||||||
ti->enter(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 "../../defines.hpp"
|
||||||
#include "../../helpers/WLClasses.hpp"
|
#include "../../helpers/WLClasses.hpp"
|
||||||
#include "TextInput.hpp"
|
#include "TextInput.hpp"
|
||||||
|
#include "InputMethodPopup.hpp"
|
||||||
|
|
||||||
class CInputManager;
|
class CInputManager;
|
||||||
|
class CHyprRenderer;
|
||||||
struct STextInputV1;
|
struct STextInputV1;
|
||||||
|
|
||||||
class CInputMethodRelay {
|
class CInputMethodRelay {
|
||||||
|
@ -27,18 +29,20 @@ class CInputMethodRelay {
|
||||||
|
|
||||||
SIMEKbGrab* getIMEKeyboardGrab(SKeyboard*);
|
SIMEKbGrab* getIMEKeyboardGrab(SKeyboard*);
|
||||||
|
|
||||||
void setIMEPopupFocus(SIMEPopup*, wlr_surface*);
|
void setIMEPopupFocus(CInputPopup*, wlr_surface*);
|
||||||
void updateInputPopup(SIMEPopup*);
|
void removePopup(CInputPopup*);
|
||||||
void damagePopup(SIMEPopup*);
|
|
||||||
void removePopup(SIMEPopup*);
|
CInputPopup* popupFromCoords(const Vector2D& point);
|
||||||
|
|
||||||
|
void updateAllPopups();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<SIMEKbGrab> m_pKeyboardGrab;
|
std::unique_ptr<SIMEKbGrab> m_pKeyboardGrab;
|
||||||
|
|
||||||
std::list<std::unique_ptr<CTextInput>> m_vTextInputs;
|
std::vector<std::unique_ptr<CTextInput>> m_vTextInputs;
|
||||||
std::list<SIMEPopup> m_lIMEPopups;
|
std::vector<std::unique_ptr<CInputPopup>> m_vIMEPopups;
|
||||||
|
|
||||||
wlr_surface* m_pLastKbFocus = nullptr;
|
wlr_surface* m_pLastKbFocus = nullptr;
|
||||||
|
|
||||||
DYNLISTENER(textInputNew);
|
DYNLISTENER(textInputNew);
|
||||||
DYNLISTENER(IMECommit);
|
DYNLISTENER(IMECommit);
|
||||||
|
@ -50,4 +54,5 @@ class CInputMethodRelay {
|
||||||
friend class CInputManager;
|
friend class CInputManager;
|
||||||
friend class CTextInputV1ProtocolManager;
|
friend class CTextInputV1ProtocolManager;
|
||||||
friend struct CTextInput;
|
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);
|
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.updateAllPopups();
|
||||||
g_pInputManager->m_sIMERelay.updateInputPopup(&p);
|
|
||||||
}
|
|
||||||
|
|
||||||
wlr_input_method_v2_send_done(ime);
|
wlr_input_method_v2_send_done(ime);
|
||||||
}
|
}
|
||||||
|
|
|
@ -679,16 +679,20 @@ void CHyprRenderer::renderLayer(SLayerSurface* pLayer, CMonitor* pMonitor, times
|
||||||
g_pHyprOpenGL->m_RenderData.clipBox = {};
|
g_pHyprOpenGL->m_RenderData.clipBox = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprRenderer::renderIMEPopup(SIMEPopup* pPopup, CMonitor* pMonitor, timespec* time) {
|
void CHyprRenderer::renderIMEPopup(CInputPopup* pPopup, CMonitor* pMonitor, timespec* time) {
|
||||||
SRenderData renderdata = {pMonitor, time, pPopup->realX, pPopup->realY};
|
const auto POS = pPopup->globalBox().pos();
|
||||||
|
|
||||||
|
SRenderData renderdata = {pMonitor, time, POS.x, POS.y};
|
||||||
|
|
||||||
|
const auto SURF = pPopup->getWlrSurface();
|
||||||
|
|
||||||
renderdata.blur = false;
|
renderdata.blur = false;
|
||||||
renderdata.surface = pPopup->pSurface->surface;
|
renderdata.surface = SURF;
|
||||||
renderdata.decorate = false;
|
renderdata.decorate = false;
|
||||||
renderdata.w = pPopup->pSurface->surface->current.width;
|
renderdata.w = SURF->current.width;
|
||||||
renderdata.h = pPopup->pSurface->surface->current.height;
|
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) {
|
void CHyprRenderer::renderSessionLockSurface(SSessionLockSurface* pSurface, CMonitor* pMonitor, timespec* time) {
|
||||||
|
@ -830,8 +834,8 @@ void CHyprRenderer::renderAllClientsForWorkspace(CMonitor* pMonitor, CWorkspace*
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render IME popups
|
// Render IME popups
|
||||||
for (auto& imep : g_pInputManager->m_sIMERelay.m_lIMEPopups) {
|
for (auto& imep : g_pInputManager->m_sIMERelay.m_vIMEPopups) {
|
||||||
renderIMEPopup(&imep, pMonitor, time);
|
renderIMEPopup(imep.get(), pMonitor, time);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& ls : pMonitor->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]) {
|
for (auto& ls : pMonitor->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]) {
|
||||||
|
|
|
@ -115,7 +115,7 @@ class CHyprRenderer {
|
||||||
void renderLayer(SLayerSurface*, CMonitor*, timespec*);
|
void renderLayer(SLayerSurface*, CMonitor*, timespec*);
|
||||||
void renderSessionLockSurface(SSessionLockSurface*, CMonitor*, timespec*);
|
void renderSessionLockSurface(SSessionLockSurface*, CMonitor*, timespec*);
|
||||||
void renderDragIcon(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 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);
|
void renderAllClientsForWorkspace(CMonitor* pMonitor, CWorkspace* pWorkspace, timespec* now, const Vector2D& translate = {0, 0}, const float& scale = 1.f);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue