mirror of
https://github.com/hyprwm/Hyprland
synced 2024-11-26 13:05:58 +01:00
xdg-activation: move to new impl
This commit is contained in:
parent
39595aaca3
commit
86133983a9
11 changed files with 158 additions and 25 deletions
|
@ -275,6 +275,7 @@ protocolNew("unstable/pointer-gestures/pointer-gestures-unstable-v1.xml" "pointe
|
||||||
protocolNew("unstable/keyboard-shortcuts-inhibit/keyboard-shortcuts-inhibit-unstable-v1.xml" "keyboard-shortcuts-inhibit-unstable-v1" false)
|
protocolNew("unstable/keyboard-shortcuts-inhibit/keyboard-shortcuts-inhibit-unstable-v1.xml" "keyboard-shortcuts-inhibit-unstable-v1" false)
|
||||||
protocolNew("unstable/text-input/text-input-unstable-v3.xml" "text-input-unstable-v3" false)
|
protocolNew("unstable/text-input/text-input-unstable-v3.xml" "text-input-unstable-v3" false)
|
||||||
protocolNew("unstable/pointer-constraints/pointer-constraints-unstable-v1.xml" "pointer-constraints-unstable-v1" false)
|
protocolNew("unstable/pointer-constraints/pointer-constraints-unstable-v1.xml" "pointer-constraints-unstable-v1" false)
|
||||||
|
protocolNew("staging/xdg-activation/xdg-activation-v1.xml" "xdg-activation-v1" false)
|
||||||
|
|
||||||
# tools
|
# tools
|
||||||
add_subdirectory(hyprctl)
|
add_subdirectory(hyprctl)
|
||||||
|
|
|
@ -52,6 +52,7 @@ new_protocols = [
|
||||||
[wl_protocol_dir, 'unstable/keyboard-shortcuts-inhibit/keyboard-shortcuts-inhibit-unstable-v1.xml'],
|
[wl_protocol_dir, 'unstable/keyboard-shortcuts-inhibit/keyboard-shortcuts-inhibit-unstable-v1.xml'],
|
||||||
[wl_protocol_dir, 'unstable/text-input/text-input-unstable-v3.xml'],
|
[wl_protocol_dir, 'unstable/text-input/text-input-unstable-v3.xml'],
|
||||||
[wl_protocol_dir, 'unstable/pointer-constraints/pointer-constraints-unstable-v1.xml'],
|
[wl_protocol_dir, 'unstable/pointer-constraints/pointer-constraints-unstable-v1.xml'],
|
||||||
|
[wl_protocol_dir, 'staging/xdg-activation/xdg-activation-v1.xml'],
|
||||||
]
|
]
|
||||||
|
|
||||||
wl_protos_src = []
|
wl_protos_src = []
|
||||||
|
|
|
@ -265,8 +265,6 @@ void CCompositor::initServer() {
|
||||||
|
|
||||||
m_sWLRIMEMgr = wlr_input_method_manager_v2_create(m_sWLDisplay);
|
m_sWLRIMEMgr = wlr_input_method_manager_v2_create(m_sWLDisplay);
|
||||||
|
|
||||||
m_sWLRActivation = wlr_xdg_activation_v1_create(m_sWLDisplay);
|
|
||||||
|
|
||||||
m_sWLRHeadlessBackend = wlr_headless_backend_create(m_sWLEventLoop);
|
m_sWLRHeadlessBackend = wlr_headless_backend_create(m_sWLEventLoop);
|
||||||
|
|
||||||
m_sWLRSessionLockMgr = wlr_session_lock_manager_v1_create(m_sWLDisplay);
|
m_sWLRSessionLockMgr = wlr_session_lock_manager_v1_create(m_sWLDisplay);
|
||||||
|
@ -318,7 +316,6 @@ void CCompositor::initAllSignals() {
|
||||||
addWLSignal(&m_sWLRVKeyboardMgr->events.new_virtual_keyboard, &Events::listen_newVirtualKeyboard, m_sWLRVKeyboardMgr, "VKeyboardMgr");
|
addWLSignal(&m_sWLRVKeyboardMgr->events.new_virtual_keyboard, &Events::listen_newVirtualKeyboard, m_sWLRVKeyboardMgr, "VKeyboardMgr");
|
||||||
addWLSignal(&m_sWLRRenderer->events.destroy, &Events::listen_RendererDestroy, m_sWLRRenderer, "WLRRenderer");
|
addWLSignal(&m_sWLRRenderer->events.destroy, &Events::listen_RendererDestroy, m_sWLRRenderer, "WLRRenderer");
|
||||||
addWLSignal(&m_sWLRIMEMgr->events.input_method, &Events::listen_newIME, m_sWLRIMEMgr, "IMEMgr");
|
addWLSignal(&m_sWLRIMEMgr->events.input_method, &Events::listen_newIME, m_sWLRIMEMgr, "IMEMgr");
|
||||||
addWLSignal(&m_sWLRActivation->events.request_activate, &Events::listen_activateXDG, m_sWLRActivation, "ActivationV1");
|
|
||||||
addWLSignal(&m_sWLRSessionLockMgr->events.new_lock, &Events::listen_newSessionLock, m_sWLRSessionLockMgr, "SessionLockMgr");
|
addWLSignal(&m_sWLRSessionLockMgr->events.new_lock, &Events::listen_newSessionLock, m_sWLRSessionLockMgr, "SessionLockMgr");
|
||||||
|
|
||||||
if (m_sWRLDRMLeaseMgr)
|
if (m_sWRLDRMLeaseMgr)
|
||||||
|
@ -363,7 +360,6 @@ void CCompositor::removeAllSignals() {
|
||||||
removeWLSignal(&Events::listen_newVirtualKeyboard);
|
removeWLSignal(&Events::listen_newVirtualKeyboard);
|
||||||
removeWLSignal(&Events::listen_RendererDestroy);
|
removeWLSignal(&Events::listen_RendererDestroy);
|
||||||
removeWLSignal(&Events::listen_newIME);
|
removeWLSignal(&Events::listen_newIME);
|
||||||
removeWLSignal(&Events::listen_activateXDG);
|
|
||||||
removeWLSignal(&Events::listen_newSessionLock);
|
removeWLSignal(&Events::listen_newSessionLock);
|
||||||
|
|
||||||
if (m_sWRLDRMLeaseMgr)
|
if (m_sWRLDRMLeaseMgr)
|
||||||
|
|
|
@ -51,7 +51,6 @@ class CCompositor {
|
||||||
wlr_data_device_manager* m_sWLRDataDevMgr;
|
wlr_data_device_manager* m_sWLRDataDevMgr;
|
||||||
wlr_drm* m_sWRLDRM;
|
wlr_drm* m_sWRLDRM;
|
||||||
wlr_drm_lease_v1_manager* m_sWRLDRMLeaseMgr;
|
wlr_drm_lease_v1_manager* m_sWRLDRMLeaseMgr;
|
||||||
wlr_xdg_activation_v1* m_sWLRXDGActivation;
|
|
||||||
wlr_output_layout* m_sWLROutputLayout;
|
wlr_output_layout* m_sWLROutputLayout;
|
||||||
wlr_idle_notifier_v1* m_sWLRIdleNotifier;
|
wlr_idle_notifier_v1* m_sWLRIdleNotifier;
|
||||||
wlr_layer_shell_v1* m_sWLRLayerShell;
|
wlr_layer_shell_v1* m_sWLRLayerShell;
|
||||||
|
@ -67,7 +66,6 @@ class CCompositor {
|
||||||
wlr_tablet_manager_v2* m_sWLRTabletManager;
|
wlr_tablet_manager_v2* m_sWLRTabletManager;
|
||||||
wlr_xdg_foreign_registry* m_sWLRForeignRegistry;
|
wlr_xdg_foreign_registry* m_sWLRForeignRegistry;
|
||||||
wlr_input_method_manager_v2* m_sWLRIMEMgr;
|
wlr_input_method_manager_v2* m_sWLRIMEMgr;
|
||||||
wlr_xdg_activation_v1* m_sWLRActivation;
|
|
||||||
wlr_linux_dmabuf_v1* m_sWLRLinuxDMABuf;
|
wlr_linux_dmabuf_v1* m_sWLRLinuxDMABuf;
|
||||||
wlr_backend* m_sWLRHeadlessBackend;
|
wlr_backend* m_sWLRHeadlessBackend;
|
||||||
wlr_session_lock_manager_v1* m_sWLRSessionLockMgr;
|
wlr_session_lock_manager_v1* m_sWLRSessionLockMgr;
|
||||||
|
|
|
@ -1272,7 +1272,7 @@ void CWindow::activate() {
|
||||||
|
|
||||||
m_bIsUrgent = true;
|
m_bIsUrgent = true;
|
||||||
|
|
||||||
if (!*PFOCUSONACTIVATE || (m_eSuppressedEvents & SUPPRESS_ACTIVATE_FOCUSONLY))
|
if (!*PFOCUSONACTIVATE || (m_eSuppressedEvents & SUPPRESS_ACTIVATE_FOCUSONLY) || (m_eSuppressedEvents & SUPPRESS_ACTIVATE))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (m_bIsFloating)
|
if (m_bIsFloating)
|
||||||
|
|
|
@ -24,7 +24,6 @@ namespace Events {
|
||||||
|
|
||||||
// Surface XDG (window)
|
// Surface XDG (window)
|
||||||
LISTENER(newXDGToplevel);
|
LISTENER(newXDGToplevel);
|
||||||
LISTENER(activateXDG);
|
|
||||||
|
|
||||||
// Window events
|
// Window events
|
||||||
DYNLISTENFUNC(commitWindow);
|
DYNLISTENFUNC(commitWindow);
|
||||||
|
|
|
@ -1015,22 +1015,6 @@ void Events::listener_fullscreenWindow(void* owner, void* data) {
|
||||||
Debug::log(LOG, "{} fullscreen to {}", PWINDOW, PWINDOW->m_bIsFullscreen);
|
Debug::log(LOG, "{} fullscreen to {}", PWINDOW, PWINDOW->m_bIsFullscreen);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Events::listener_activateXDG(wl_listener* listener, void* data) {
|
|
||||||
const auto E = (wlr_xdg_activation_v1_request_activate_event*)data;
|
|
||||||
|
|
||||||
Debug::log(LOG, "Activate request for surface at {:x}", (uintptr_t)E->surface);
|
|
||||||
|
|
||||||
if (!wlr_xdg_surface_try_from_wlr_surface(E->surface))
|
|
||||||
return;
|
|
||||||
|
|
||||||
const auto PWINDOW = g_pCompositor->getWindowFromSurface(E->surface);
|
|
||||||
|
|
||||||
if (!PWINDOW || PWINDOW == g_pCompositor->m_pLastWindow.lock() || (PWINDOW->m_eSuppressedEvents & SUPPRESS_ACTIVATE))
|
|
||||||
return;
|
|
||||||
|
|
||||||
PWINDOW->activate();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Events::listener_activateX11(void* owner, void* data) {
|
void Events::listener_activateX11(void* owner, void* data) {
|
||||||
PHLWINDOW PWINDOW = ((CWindow*)owner)->m_pSelf.lock();
|
PHLWINDOW PWINDOW = ((CWindow*)owner)->m_pSelf.lock();
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,6 @@ extern "C" {
|
||||||
#include <wlr/types/wlr_server_decoration.h>
|
#include <wlr/types/wlr_server_decoration.h>
|
||||||
#include <wlr/types/wlr_viewporter.h>
|
#include <wlr/types/wlr_viewporter.h>
|
||||||
#include <wlr/types/wlr_virtual_keyboard_v1.h>
|
#include <wlr/types/wlr_virtual_keyboard_v1.h>
|
||||||
#include <wlr/types/wlr_xdg_activation_v1.h>
|
|
||||||
#include <wlr/types/wlr_xdg_output_v1.h>
|
#include <wlr/types/wlr_xdg_output_v1.h>
|
||||||
#include <wlr/types/wlr_xdg_shell.h>
|
#include <wlr/types/wlr_xdg_shell.h>
|
||||||
#include <wlr/types/wlr_subcompositor.h>
|
#include <wlr/types/wlr_subcompositor.h>
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "../protocols/TextInputV3.hpp"
|
#include "../protocols/TextInputV3.hpp"
|
||||||
#include "../protocols/PointerConstraints.hpp"
|
#include "../protocols/PointerConstraints.hpp"
|
||||||
#include "../protocols/OutputPower.hpp"
|
#include "../protocols/OutputPower.hpp"
|
||||||
|
#include "../protocols/XDGActivation.hpp"
|
||||||
|
|
||||||
#include "tearing-control-v1.hpp"
|
#include "tearing-control-v1.hpp"
|
||||||
#include "fractional-scale-v1.hpp"
|
#include "fractional-scale-v1.hpp"
|
||||||
|
@ -33,6 +34,7 @@
|
||||||
#include "text-input-unstable-v3.hpp"
|
#include "text-input-unstable-v3.hpp"
|
||||||
#include "pointer-constraints-unstable-v1.hpp"
|
#include "pointer-constraints-unstable-v1.hpp"
|
||||||
#include "wlr-output-power-management-unstable-v1.hpp"
|
#include "wlr-output-power-management-unstable-v1.hpp"
|
||||||
|
#include "xdg-activation-v1.hpp"
|
||||||
|
|
||||||
CProtocolManager::CProtocolManager() {
|
CProtocolManager::CProtocolManager() {
|
||||||
|
|
||||||
|
@ -52,6 +54,7 @@ CProtocolManager::CProtocolManager() {
|
||||||
PROTO::textInputV3 = std::make_unique<CTextInputV3Protocol>(&zwp_text_input_manager_v3_interface, 1, "TextInputV3");
|
PROTO::textInputV3 = std::make_unique<CTextInputV3Protocol>(&zwp_text_input_manager_v3_interface, 1, "TextInputV3");
|
||||||
PROTO::constraints = std::make_unique<CPointerConstraintsProtocol>(&zwp_pointer_constraints_v1_interface, 1, "PointerConstraints");
|
PROTO::constraints = std::make_unique<CPointerConstraintsProtocol>(&zwp_pointer_constraints_v1_interface, 1, "PointerConstraints");
|
||||||
PROTO::outputPower = std::make_unique<COutputPowerProtocol>(&zwlr_output_power_manager_v1_interface, 1, "OutputPower");
|
PROTO::outputPower = std::make_unique<COutputPowerProtocol>(&zwlr_output_power_manager_v1_interface, 1, "OutputPower");
|
||||||
|
PROTO::activation = std::make_unique<CXDGActivationProtocol>(&xdg_activation_v1_interface, 1, "XDGActivation");
|
||||||
|
|
||||||
// Old protocol implementations.
|
// Old protocol implementations.
|
||||||
// TODO: rewrite them to use hyprwayland-scanner.
|
// TODO: rewrite them to use hyprwayland-scanner.
|
||||||
|
|
103
src/protocols/XDGActivation.cpp
Normal file
103
src/protocols/XDGActivation.cpp
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
#include "XDGActivation.hpp"
|
||||||
|
#include "../managers/TokenManager.hpp"
|
||||||
|
#include "../Compositor.hpp"
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#define LOGM PROTO::activation->protoLog
|
||||||
|
|
||||||
|
CXDGActivationToken::CXDGActivationToken(SP<CXdgActivationTokenV1> resource_) : resource(resource_) {
|
||||||
|
if (!resource_->resource())
|
||||||
|
return;
|
||||||
|
|
||||||
|
resource->setDestroy([this](CXdgActivationTokenV1* r) { PROTO::activation->destroyToken(this); });
|
||||||
|
resource->setOnDestroy([this](CXdgActivationTokenV1* r) { PROTO::activation->destroyToken(this); });
|
||||||
|
|
||||||
|
resource->setSetSerial([this](CXdgActivationTokenV1* r, uint32_t serial_, wl_resource* seat) { serial = serial_; });
|
||||||
|
|
||||||
|
resource->setSetAppId([this](CXdgActivationTokenV1* r, const char* appid) { appID = appid; });
|
||||||
|
|
||||||
|
resource->setCommit([this](CXdgActivationTokenV1* r) {
|
||||||
|
// TODO: should we send a protocol error of already_used here
|
||||||
|
// if it was used? the protocol spec doesn't say _when_ it should be sent...
|
||||||
|
if (committed) {
|
||||||
|
LOGM(WARN, "possible protocol error, two commits from one token. Ignoring.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
committed = true;
|
||||||
|
// send done with a new token
|
||||||
|
token = g_pTokenManager->registerNewToken({}, std::chrono::months{12});
|
||||||
|
|
||||||
|
LOGM(LOG, "assigned new xdg-activation token {}", token);
|
||||||
|
|
||||||
|
resource->sendDone(token.c_str());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
CXDGActivationToken::~CXDGActivationToken() {
|
||||||
|
if (committed)
|
||||||
|
g_pTokenManager->removeToken(g_pTokenManager->getToken(token));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CXDGActivationToken::good() {
|
||||||
|
return resource->resource();
|
||||||
|
}
|
||||||
|
|
||||||
|
CXDGActivationProtocol::CXDGActivationProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) {
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CXDGActivationProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) {
|
||||||
|
const auto RESOURCE = m_vManagers.emplace_back(std::make_unique<CXdgActivationV1>(client, ver, id)).get();
|
||||||
|
RESOURCE->setOnDestroy([this](CXdgActivationV1* p) { this->onManagerResourceDestroy(p->resource()); });
|
||||||
|
|
||||||
|
RESOURCE->setDestroy([this](CXdgActivationV1* pMgr) { this->onManagerResourceDestroy(pMgr->resource()); });
|
||||||
|
RESOURCE->setGetActivationToken([this](CXdgActivationV1* pMgr, uint32_t id) { this->onGetToken(pMgr, id); });
|
||||||
|
RESOURCE->setActivate([this](CXdgActivationV1* pMgr, const char* token, wl_resource* surface) {
|
||||||
|
const auto TOKEN = std::find_if(m_vTokens.begin(), m_vTokens.end(), [token](const auto& t) { return t->committed && t->token == token; });
|
||||||
|
|
||||||
|
if (TOKEN == m_vTokens.end()) {
|
||||||
|
LOGM(WARN, "activate event for non-existent token {}??", token);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto xdgToken = TOKEN->get();
|
||||||
|
|
||||||
|
if (xdgToken->used) {
|
||||||
|
LOGM(WARN, "activate event for already used token {}, ignoring", token);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
xdgToken->used = true;
|
||||||
|
|
||||||
|
wlr_surface* surf = wlr_surface_from_resource(surface);
|
||||||
|
const auto PWINDOW = g_pCompositor->getWindowFromSurface(surf);
|
||||||
|
|
||||||
|
if (!PWINDOW) {
|
||||||
|
LOGM(WARN, "activate event for non-window or gone surface with token {}, ignoring", token);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PWINDOW->activate();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void CXDGActivationProtocol::onManagerResourceDestroy(wl_resource* res) {
|
||||||
|
std::erase_if(m_vManagers, [&](const auto& other) { return other->resource() == res; });
|
||||||
|
}
|
||||||
|
|
||||||
|
void CXDGActivationProtocol::destroyToken(CXDGActivationToken* token) {
|
||||||
|
std::erase_if(m_vTokens, [&](const auto& other) { return other.get() == token; });
|
||||||
|
}
|
||||||
|
|
||||||
|
void CXDGActivationProtocol::onGetToken(CXdgActivationV1* pMgr, uint32_t id) {
|
||||||
|
const auto CLIENT = wl_resource_get_client(pMgr->resource());
|
||||||
|
const auto RESOURCE =
|
||||||
|
m_vTokens.emplace_back(std::make_unique<CXDGActivationToken>(std::make_shared<CXdgActivationTokenV1>(CLIENT, wl_resource_get_version(pMgr->resource()), id))).get();
|
||||||
|
|
||||||
|
if (!RESOURCE->good()) {
|
||||||
|
wl_resource_post_no_memory(pMgr->resource());
|
||||||
|
m_vTokens.pop_back();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
49
src/protocols/XDGActivation.hpp
Normal file
49
src/protocols/XDGActivation.hpp
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
#include <cstdint>
|
||||||
|
#include "WaylandProtocol.hpp"
|
||||||
|
#include "xdg-activation-v1.hpp"
|
||||||
|
|
||||||
|
class CXDGActivationToken {
|
||||||
|
public:
|
||||||
|
CXDGActivationToken(SP<CXdgActivationTokenV1> resource_);
|
||||||
|
~CXDGActivationToken();
|
||||||
|
|
||||||
|
bool good();
|
||||||
|
|
||||||
|
private:
|
||||||
|
SP<CXdgActivationTokenV1> resource;
|
||||||
|
|
||||||
|
uint32_t serial = 0;
|
||||||
|
std::string appID = "";
|
||||||
|
bool committed = false;
|
||||||
|
bool used = false;
|
||||||
|
|
||||||
|
std::string token = "";
|
||||||
|
|
||||||
|
friend class CXDGActivationProtocol;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CXDGActivationProtocol : public IWaylandProtocol {
|
||||||
|
public:
|
||||||
|
CXDGActivationProtocol(const wl_interface* iface, const int& ver, const std::string& name);
|
||||||
|
|
||||||
|
virtual void bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void onManagerResourceDestroy(wl_resource* res);
|
||||||
|
void destroyToken(CXDGActivationToken* pointer);
|
||||||
|
void onGetToken(CXdgActivationV1* pMgr, uint32_t id);
|
||||||
|
|
||||||
|
//
|
||||||
|
std::vector<UP<CXdgActivationV1>> m_vManagers;
|
||||||
|
std::vector<UP<CXDGActivationToken>> m_vTokens;
|
||||||
|
|
||||||
|
friend class CXDGActivationToken;
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace PROTO {
|
||||||
|
inline UP<CXDGActivationProtocol> activation;
|
||||||
|
};
|
Loading…
Reference in a new issue