Skip to content

Commit

Permalink
primary-selection: move to hyprland impl
Browse files Browse the repository at this point in the history
  • Loading branch information
vaxerski committed May 13, 2024
1 parent 9ccaa8a commit ddabd5f
Show file tree
Hide file tree
Showing 10 changed files with 519 additions and 13 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,7 @@ protocolNew("staging/ext-session-lock/ext-session-lock-v1.xml" "ext-session-lock
protocolNew("stable/tablet/tablet-v2.xml" "tablet-v2" false)
protocolNew("stable/presentation-time/presentation-time.xml" "presentation-time" false)
protocolNew("stable/xdg-shell/xdg-shell.xml" "xdg-shell" false)
protocolNew("unstable/primary-selection/primary-selection-unstable-v1.xml" "primary-selection-unstable-v1" false)

protocolWayland()

Expand Down
1 change: 1 addition & 0 deletions protocols/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ new_protocols = [
[wl_protocol_dir, 'stable/tablet/tablet-v2.xml'],
[wl_protocol_dir, 'stable/presentation-time/presentation-time.xml'],
[wl_protocol_dir, 'stable/xdg-shell/xdg-shell.xml'],
[wl_protocol_dir, 'unstable/primary-selection/primary-selection-unstable-v1.xml'],
]

wl_protos_src = []
Expand Down
1 change: 1 addition & 0 deletions src/config/ConfigManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,7 @@ CConfigManager::CConfigManager() {
m_pConfig->addConfigValue("misc:background_color", Hyprlang::INT{0xff111111});
m_pConfig->addConfigValue("misc:new_window_takes_over_fullscreen", Hyprlang::INT{0});
m_pConfig->addConfigValue("misc:initial_workspace_tracking", Hyprlang::INT{1});
m_pConfig->addConfigValue("misc:middle_click_paste", Hyprlang::INT{1});

m_pConfig->addConfigValue("group:insert_after_current", Hyprlang::INT{1});
m_pConfig->addConfigValue("group:focus_removed_window", Hyprlang::INT{1});
Expand Down
2 changes: 2 additions & 0 deletions src/managers/ProtocolManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "../protocols/PresentationTime.hpp"
#include "../protocols/XDGShell.hpp"
#include "../protocols/DataDeviceWlr.hpp"
#include "../protocols/PrimarySelection.hpp"

#include "../protocols/core/Seat.hpp"
#include "../protocols/core/DataDevice.hpp"
Expand Down Expand Up @@ -71,6 +72,7 @@ CProtocolManager::CProtocolManager() {
PROTO::presentation = std::make_unique<CPresentationProtocol>(&wp_presentation_interface, 1, "Presentation");
PROTO::xdgShell = std::make_unique<CXDGShellProtocol>(&xdg_wm_base_interface, 6, "XDGShell");
PROTO::dataWlr = std::make_unique<CDataDeviceWLRProtocol>(&zwlr_data_control_manager_v1_interface, 2, "DataDeviceWlr");
PROTO::primarySelection = std::make_unique<CPrimarySelectionProtocol>(&zwp_primary_selection_device_manager_v1_interface, 1, "PrimarySelection");

// Old protocol implementations.
// TODO: rewrite them to use hyprwayland-scanner.
Expand Down
26 changes: 25 additions & 1 deletion src/managers/SeatManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "../protocols/core/Seat.hpp"
#include "../protocols/core/DataDevice.hpp"
#include "../protocols/DataDeviceWlr.hpp"
#include "../protocols/PrimarySelection.hpp"
#include "../Compositor.hpp"
#include "../devices/IKeyboard.hpp"
#include <algorithm>
Expand Down Expand Up @@ -425,7 +426,30 @@ void CSeatManager::setCurrentSelection(SP<IDataSource> source) {
if (source) {
selection.destroySelection = source->events.destroy.registerListener([this](std::any d) { setCurrentSelection(nullptr); });
PROTO::data->setSelection(source);
PROTO::dataWlr->setSelection(source);
PROTO::dataWlr->setSelection(source, false);
}
}

void CSeatManager::setCurrentPrimarySelection(SP<IDataSource> source) {
if (source == selection.currentPrimarySelection) {
Debug::log(WARN, "[seat] duplicated setCurrentPrimarySelection?");
return;
}

selection.destroyPrimarySelection.reset();

if (selection.currentPrimarySelection)
selection.currentPrimarySelection->cancelled();

if (!source)
PROTO::primarySelection->setSelection(nullptr);

selection.currentPrimarySelection = source;

if (source) {
selection.destroyPrimarySelection = source->events.destroy.registerListener([this](std::any d) { setCurrentSelection(nullptr); });
PROTO::primarySelection->setSelection(source);
PROTO::dataWlr->setSelection(source, true);
}
}

Expand Down
3 changes: 3 additions & 0 deletions src/managers/SeatManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,12 @@ class CSeatManager {
struct {
WP<IDataSource> currentSelection;
CHyprSignalListener destroySelection;
WP<IDataSource> currentPrimarySelection;
CHyprSignalListener destroyPrimarySelection;
} selection;

void setCurrentSelection(SP<IDataSource> source);
void setCurrentPrimarySelection(SP<IDataSource> source);

// do not write to directly, use set...
WP<IPointer> mouse;
Expand Down
30 changes: 21 additions & 9 deletions src/protocols/DataDeviceWlr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,11 @@ CWLRDataDevice::CWLRDataDevice(SP<CZwlrDataControlDeviceV1> resource_) : resourc
source->markUsed();

LOGM(LOG, "wlr manager requests primary selection to {:x}", (uintptr_t)source.get());
g_pSeatManager->setCurrentSelection(source);
g_pSeatManager->setCurrentPrimarySelection(source);
});

resource->sendSelectionRaw(nullptr);
resource->sendPrimarySelectionRaw(nullptr);
}

bool CWLRDataDevice::good() {
Expand All @@ -167,6 +168,10 @@ void CWLRDataDevice::sendSelection(SP<CWLRDataOffer> selection) {
resource->sendSelection(selection->resource.get());
}

void CWLRDataDevice::sendPrimarySelection(SP<CWLRDataOffer> selection) {
resource->sendPrimarySelection(selection->resource.get());
}

CWLRDataControlManagerResource::CWLRDataControlManagerResource(SP<CZwlrDataControlManagerV1> resource_) : resource(resource_) {
if (!good())
return;
Expand Down Expand Up @@ -254,7 +259,7 @@ void CDataDeviceWLRProtocol::destroyResource(CWLRDataOffer* resource) {
std::erase_if(m_vOffers, [&](const auto& other) { return other.get() == resource; });
}

void CDataDeviceWLRProtocol::sendSelectionToDevice(SP<CWLRDataDevice> dev, SP<IDataSource> sel) {
void CDataDeviceWLRProtocol::sendSelectionToDevice(SP<CWLRDataDevice> dev, SP<IDataSource> sel, bool primary) {
if (!sel)
return;

Expand All @@ -266,34 +271,41 @@ void CDataDeviceWLRProtocol::sendSelectionToDevice(SP<CWLRDataDevice> dev, SP<ID
return;
}

LOGM(LOG, "New offer {:x} for data source {:x}", (uintptr_t)OFFER.get(), (uintptr_t)sel.get());
OFFER->primary = primary;

LOGM(LOG, "New {}offer {:x} for data source {:x}", primary ? "primary " : " ", (uintptr_t)OFFER.get(), (uintptr_t)sel.get());

dev->sendDataOffer(OFFER);
OFFER->sendData();
dev->sendSelection(OFFER);
if (primary)
dev->sendPrimarySelection(OFFER);
else
dev->sendSelection(OFFER);
}

void CDataDeviceWLRProtocol::setSelection(SP<IDataSource> source) {
void CDataDeviceWLRProtocol::setSelection(SP<IDataSource> source, bool primary) {
for (auto& o : m_vOffers) {
if (o->source && o->source->hasDnd())
continue;
if (o->primary != primary)
continue;
o->dead = true;
}

if (!source) {
LOGM(LOG, "resetting selection");
LOGM(LOG, "resetting {}selection", primary ? "primary " : " ");

for (auto& d : m_vDevices) {
sendSelectionToDevice(d, nullptr);
sendSelectionToDevice(d, nullptr, primary);
}

return;
}

LOGM(LOG, "New selection for data source {:x}", (uintptr_t)source.get());
LOGM(LOG, "New {}selection for data source {:x}", primary ? "primary" : "", (uintptr_t)source.get());

for (auto& d : m_vDevices) {
sendSelectionToDevice(d, source);
sendSelectionToDevice(d, source, primary);
}
}

Expand Down
8 changes: 5 additions & 3 deletions src/protocols/DataDeviceWlr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ class CWLRDataOffer {
bool good();
void sendData();

bool dead = false;
bool dead = false;
bool primary = false;

WP<IDataSource> source;

Expand Down Expand Up @@ -60,6 +61,7 @@ class CWLRDataDevice {

void sendDataOffer(SP<CWLRDataOffer> offer);
void sendSelection(SP<CWLRDataOffer> selection);
void sendPrimarySelection(SP<CWLRDataOffer> selection);

WP<CWLRDataDevice> self;

Expand Down Expand Up @@ -102,8 +104,8 @@ class CDataDeviceWLRProtocol : public IWaylandProtocol {
std::vector<SP<CWLRDataOffer>> m_vOffers;

//
void setSelection(SP<IDataSource> source);
void sendSelectionToDevice(SP<CWLRDataDevice> dev, SP<IDataSource> sel);
void setSelection(SP<IDataSource> source, bool primary);
void sendSelectionToDevice(SP<CWLRDataDevice> dev, SP<IDataSource> sel, bool primary);

//
SP<CWLRDataDevice> dataDeviceForClient(wl_client*);
Expand Down
Loading

0 comments on commit ddabd5f

Please sign in to comment.