Skip to content

Commit

Permalink
xdg-activation: move to new impl
Browse files Browse the repository at this point in the history
  • Loading branch information
vaxerski committed Apr 29, 2024
1 parent 39595aa commit 8613398
Show file tree
Hide file tree
Showing 11 changed files with 158 additions and 25 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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/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("staging/xdg-activation/xdg-activation-v1.xml" "xdg-activation-v1" false)

# tools
add_subdirectory(hyprctl)
Expand Down
1 change: 1 addition & 0 deletions protocols/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ new_protocols = [
[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/pointer-constraints/pointer-constraints-unstable-v1.xml'],
[wl_protocol_dir, 'staging/xdg-activation/xdg-activation-v1.xml'],
]

wl_protos_src = []
Expand Down
4 changes: 0 additions & 4 deletions src/Compositor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -265,8 +265,6 @@ void CCompositor::initServer() {

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_sWLRSessionLockMgr = wlr_session_lock_manager_v1_create(m_sWLDisplay);
Expand Down Expand Up @@ -318,7 +316,6 @@ void CCompositor::initAllSignals() {
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_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");

if (m_sWRLDRMLeaseMgr)
Expand Down Expand Up @@ -363,7 +360,6 @@ void CCompositor::removeAllSignals() {
removeWLSignal(&Events::listen_newVirtualKeyboard);
removeWLSignal(&Events::listen_RendererDestroy);
removeWLSignal(&Events::listen_newIME);
removeWLSignal(&Events::listen_activateXDG);
removeWLSignal(&Events::listen_newSessionLock);

if (m_sWRLDRMLeaseMgr)
Expand Down
2 changes: 0 additions & 2 deletions src/Compositor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ class CCompositor {
wlr_data_device_manager* m_sWLRDataDevMgr;
wlr_drm* m_sWRLDRM;
wlr_drm_lease_v1_manager* m_sWRLDRMLeaseMgr;
wlr_xdg_activation_v1* m_sWLRXDGActivation;
wlr_output_layout* m_sWLROutputLayout;
wlr_idle_notifier_v1* m_sWLRIdleNotifier;
wlr_layer_shell_v1* m_sWLRLayerShell;
Expand All @@ -67,7 +66,6 @@ class CCompositor {
wlr_tablet_manager_v2* m_sWLRTabletManager;
wlr_xdg_foreign_registry* m_sWLRForeignRegistry;
wlr_input_method_manager_v2* m_sWLRIMEMgr;
wlr_xdg_activation_v1* m_sWLRActivation;
wlr_linux_dmabuf_v1* m_sWLRLinuxDMABuf;
wlr_backend* m_sWLRHeadlessBackend;
wlr_session_lock_manager_v1* m_sWLRSessionLockMgr;
Expand Down
2 changes: 1 addition & 1 deletion src/desktop/Window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1272,7 +1272,7 @@ void CWindow::activate() {

m_bIsUrgent = true;

if (!*PFOCUSONACTIVATE || (m_eSuppressedEvents & SUPPRESS_ACTIVATE_FOCUSONLY))
if (!*PFOCUSONACTIVATE || (m_eSuppressedEvents & SUPPRESS_ACTIVATE_FOCUSONLY) || (m_eSuppressedEvents & SUPPRESS_ACTIVATE))
return;

if (m_bIsFloating)
Expand Down
1 change: 0 additions & 1 deletion src/events/Events.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ namespace Events {

// Surface XDG (window)
LISTENER(newXDGToplevel);
LISTENER(activateXDG);

// Window events
DYNLISTENFUNC(commitWindow);
Expand Down
16 changes: 0 additions & 16 deletions src/events/Windows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1015,22 +1015,6 @@ void Events::listener_fullscreenWindow(void* owner, void* data) {
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) {
PHLWINDOW PWINDOW = ((CWindow*)owner)->m_pSelf.lock();

Expand Down
1 change: 0 additions & 1 deletion src/includes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ extern "C" {
#include <wlr/types/wlr_server_decoration.h>
#include <wlr/types/wlr_viewporter.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_shell.h>
#include <wlr/types/wlr_subcompositor.h>
Expand Down
3 changes: 3 additions & 0 deletions src/managers/ProtocolManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "../protocols/TextInputV3.hpp"
#include "../protocols/PointerConstraints.hpp"
#include "../protocols/OutputPower.hpp"
#include "../protocols/XDGActivation.hpp"

#include "tearing-control-v1.hpp"
#include "fractional-scale-v1.hpp"
Expand All @@ -33,6 +34,7 @@
#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"

CProtocolManager::CProtocolManager() {

Expand All @@ -52,6 +54,7 @@ CProtocolManager::CProtocolManager() {
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::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.
// TODO: rewrite them to use hyprwayland-scanner.
Expand Down
103 changes: 103 additions & 0 deletions src/protocols/XDGActivation.cpp
Original file line number Diff line number Diff line change
@@ -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 changes: 49 additions & 0 deletions src/protocols/XDGActivation.hpp
Original file line number Diff line number Diff line change
@@ -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;
};

0 comments on commit 8613398

Please sign in to comment.