mirror of
https://github.com/noctalia-dev/noctalia-shell.git
synced 2026-05-11 17:08:27 +08:00
fix(controls): popup_window now inherits keyboard focus
This commit is contained in:
@@ -30,6 +30,7 @@
|
||||
#include "system/distro_info.h"
|
||||
#include "time/time_format.h"
|
||||
#include "ui/controls/input.h"
|
||||
#include "ui/controls/popup_window.h"
|
||||
#include "ui/dialogs/color_picker_dialog.h"
|
||||
#include "ui/dialogs/file_dialog.h"
|
||||
#include "ui/dialogs/glyph_picker_dialog.h"
|
||||
@@ -808,6 +809,9 @@ void Application::initUi() {
|
||||
m_fileDialogPopup.onKeyboardEvent(event);
|
||||
return;
|
||||
}
|
||||
if (PopupWindow::dispatchKeyboardEvent(m_wayland.lastKeyboardSurface(), event)) {
|
||||
return;
|
||||
}
|
||||
if (m_settingsWindow.isOpen() && m_settingsWindow.wlSurface() != nullptr &&
|
||||
m_wayland.lastKeyboardSurface() == m_settingsWindow.wlSurface()) {
|
||||
m_settingsWindow.onKeyboardEvent(event);
|
||||
|
||||
@@ -18,6 +18,11 @@ namespace {
|
||||
|
||||
} // namespace
|
||||
|
||||
std::vector<PopupWindow*>& PopupWindow::openPopups() {
|
||||
static std::vector<PopupWindow*> popups;
|
||||
return popups;
|
||||
}
|
||||
|
||||
PopupWindow::PopupWindow(WaylandConnection& wayland, RenderContext& renderContext)
|
||||
: m_wayland(wayland), m_renderContext(renderContext) {}
|
||||
|
||||
@@ -64,9 +69,17 @@ void PopupWindow::openCommon(PopupSurfaceConfig config, zwlr_layer_surface_v1* p
|
||||
const bool needsSceneBuild = self->m_sceneRoot == nullptr ||
|
||||
static_cast<std::uint32_t>(std::round(self->m_sceneRoot->width())) != width ||
|
||||
static_cast<std::uint32_t>(std::round(self->m_sceneRoot->height())) != height;
|
||||
if (needsSceneBuild || needsLayout) {
|
||||
if (needsSceneBuild) {
|
||||
UiPhaseScope layoutPhase(UiPhase::Layout);
|
||||
self->buildScene(width, height);
|
||||
return;
|
||||
}
|
||||
|
||||
if (needsLayout && self->m_sceneRoot != nullptr) {
|
||||
UiPhaseScope layoutPhase(UiPhase::Layout);
|
||||
self->m_sceneRoot->setSize(static_cast<float>(width), static_cast<float>(height));
|
||||
self->m_sceneRoot->layout(self->m_renderContext);
|
||||
self->m_surface->setSceneRoot(self->m_sceneRoot.get());
|
||||
}
|
||||
});
|
||||
|
||||
@@ -81,6 +94,7 @@ void PopupWindow::openCommon(PopupSurfaceConfig config, zwlr_layer_surface_v1* p
|
||||
}
|
||||
|
||||
m_wlSurface = m_surface->wlSurface();
|
||||
openPopups().push_back(this);
|
||||
}
|
||||
|
||||
void PopupWindow::buildScene(std::uint32_t width, std::uint32_t height) {
|
||||
@@ -109,6 +123,8 @@ void PopupWindow::buildScene(std::uint32_t width, std::uint32_t height) {
|
||||
|
||||
void PopupWindow::close() {
|
||||
const bool wasOpen = m_surface != nullptr;
|
||||
auto& popups = openPopups();
|
||||
popups.erase(std::remove(popups.begin(), popups.end(), this), popups.end());
|
||||
m_sceneRoot.reset();
|
||||
m_surface.reset();
|
||||
m_inputDispatcher.setSceneRoot(nullptr);
|
||||
@@ -209,6 +225,26 @@ void PopupWindow::requestRedraw() {
|
||||
}
|
||||
}
|
||||
|
||||
bool PopupWindow::dispatchKeyboardEvent(wl_surface* keyboardSurface, const KeyboardEvent& event) {
|
||||
if (keyboardSurface == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto& popups = openPopups();
|
||||
for (auto it = popups.rbegin(); it != popups.rend(); ++it) {
|
||||
auto* popup = *it;
|
||||
if (popup == nullptr || !popup->isOpen()) {
|
||||
continue;
|
||||
}
|
||||
if (popup->wlSurface() == keyboardSurface) {
|
||||
popup->onKeyboardEvent(event);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
PopupSurfaceConfig PopupWindow::makeConfig(std::int32_t anchorX, std::int32_t anchorY, std::int32_t anchorWidth,
|
||||
std::int32_t anchorHeight, std::uint32_t width, std::uint32_t height,
|
||||
std::uint32_t serial, AnchorMode mode, std::int32_t offsetX,
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
class Node;
|
||||
class PopupSurface;
|
||||
@@ -47,6 +48,9 @@ public:
|
||||
void requestLayout();
|
||||
void requestRedraw();
|
||||
|
||||
// Dispatch keyboard events to the popup that currently owns the provided Wayland keyboard surface.
|
||||
[[nodiscard]] static bool dispatchKeyboardEvent(wl_surface* keyboardSurface, const KeyboardEvent& event);
|
||||
|
||||
[[nodiscard]] static PopupSurfaceConfig makeConfig(std::int32_t anchorX, std::int32_t anchorY,
|
||||
std::int32_t anchorWidth, std::int32_t anchorHeight,
|
||||
std::uint32_t width, std::uint32_t height, std::uint32_t serial,
|
||||
@@ -69,4 +73,6 @@ private:
|
||||
ContentBuilder m_contentBuilder;
|
||||
SceneReadyCallback m_sceneReadyCallback;
|
||||
std::function<void()> m_onDismissed;
|
||||
|
||||
static std::vector<PopupWindow*>& openPopups();
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user