Skip to content

Commit

Permalink
Implement foundation for pointer constraints
Browse files Browse the repository at this point in the history
  • Loading branch information
serebit committed Oct 27, 2023
1 parent 943e867 commit 569d020
Show file tree
Hide file tree
Showing 7 changed files with 136 additions and 0 deletions.
55 changes: 55 additions & 0 deletions src/input/constraint.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#include "constraint.hpp"

#include "seat.hpp"
#include "types.hpp"

#include <wayland-util.h>

#include "wlr-wrap-start.hpp"
#include <wlr/types/wlr_compositor.h>
#include "wlr-wrap-end.hpp"

static void constraint_set_region_notify(wl_listener* listener, void* data) {
(void) listener;
(void) data;
}

static void constraint_surface_commit_notify(wl_listener* listener, void* data) {
(void) listener;
(void) data;
}

static void constraint_destroy_notify(wl_listener* listener, void* data) {
PointerConstraint& constraint = magpie_container_of(listener, constraint, destroy);
(void) data;

auto& current_constraint = constraint.seat.current_constraint;
if (current_constraint.has_value() && current_constraint.value().wlr == constraint.wlr) {
current_constraint.reset();
}
}

PointerConstraint::PointerConstraint(Seat& seat, wlr_pointer_constraint_v1* constraint) noexcept
: listeners(*this), seat(seat), wlr(constraint) {
listeners.set_region.notify = constraint_set_region_notify;
wl_signal_add(&constraint->events.set_region, &listeners.set_region);
listeners.surface_commit.notify = constraint_surface_commit_notify;
wl_signal_add(&constraint->surface->events.commit, &listeners.surface_commit);
listeners.destroy.notify = constraint_destroy_notify;
wl_signal_add(&constraint->events.destroy, &listeners.destroy);
}

PointerConstraint::~PointerConstraint() noexcept {
deactivate();
wl_list_remove(&listeners.set_region.link);
wl_list_remove(&listeners.surface_commit.link);
wl_list_remove(&listeners.destroy.link);
}

void PointerConstraint::activate() const {
wlr_pointer_constraint_v1_send_activated(wlr);
}

void PointerConstraint::deactivate() const {
wlr_pointer_constraint_v1_send_deactivated(wlr);
}
37 changes: 37 additions & 0 deletions src/input/constraint.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#ifndef MAGPIE_CONSTRAINT_HPP
#define MAGPIE_CONSTRAINT_HPP

#include "types.hpp"

#include <functional>
#include <wayland-server-core.h>

#include "wlr-wrap-start.hpp"
#include <wlr/types/wlr_pointer_constraints_v1.h>
#include "wlr-wrap-end.hpp"

class PointerConstraint {
public:
struct Listeners {
std::reference_wrapper<PointerConstraint> parent;
wl_listener set_region;
wl_listener surface_commit;
wl_listener destroy;
Listeners(PointerConstraint& parent) noexcept : parent(parent) {}
};

private:
Listeners listeners;

public:
Seat& seat;
wlr_pointer_constraint_v1* wlr;

PointerConstraint(Seat& seat, wlr_pointer_constraint_v1* wlr) noexcept;
~PointerConstraint() noexcept;

void activate() const;
void deactivate() const;
};

#endif
31 changes: 31 additions & 0 deletions src/input/seat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,17 @@ static void new_virtual_keyboard_notify(wl_listener* listener, void* data) {
seat.new_input_device(&keyboard->keyboard.base);
}

static void new_pointer_constraint_notify(wl_listener* listener, void* data) {
Seat& seat = magpie_container_of(listener, seat, new_pointer_constraint);
auto* wlr_constraint = static_cast<wlr_pointer_constraint_v1*>(data);

auto* focused_surface = seat.seat->keyboard_state.focused_surface;
if (focused_surface == wlr_constraint->surface) {
// only allow creating constraints for the focused view
seat.set_constraint(wlr_constraint);
}
}

static void request_cursor_notify(wl_listener* listener, void* data) {
const Seat& seat = magpie_container_of(listener, seat, request_cursor);
auto* event = static_cast<wlr_seat_pointer_request_set_cursor_event*>(data);
Expand Down Expand Up @@ -85,6 +96,10 @@ Seat::Seat(Server& server) noexcept : listeners(*this), server(server), cursor(*
virtual_keyboard_mgr = wlr_virtual_keyboard_manager_v1_create(server.display);
listeners.new_virtual_keyboard.notify = new_virtual_keyboard_notify;
wl_signal_add(&virtual_keyboard_mgr->events.new_virtual_keyboard, &listeners.new_virtual_keyboard);

pointer_constraints = wlr_pointer_constraints_v1_create(server.display);
listeners.new_pointer_constraint.notify = new_pointer_constraint_notify;
wl_signal_add(&pointer_constraints->events.new_constraint, &listeners.new_pointer_constraint);
}

void Seat::new_input_device(wlr_input_device* device) {
Expand All @@ -107,3 +122,19 @@ void Seat::new_input_device(wlr_input_device* device) {
}
wlr_seat_set_capabilities(seat, caps);
}

void Seat::set_constraint(wlr_pointer_constraint_v1* wlr_constraint) {
if (current_constraint.has_value()) {
if (current_constraint.value().wlr == wlr_constraint) {
// we already have this constraint marked as the current constraint
return;
}

current_constraint.reset();
}

if (wlr_constraint != nullptr) {
current_constraint.emplace(PointerConstraint(*this, wlr_constraint));
current_constraint.value().activate();
}
}
7 changes: 7 additions & 0 deletions src/input/seat.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@
#define MAGPIE_SEAT_HPP

#include "cursor.hpp"
#include "constraint.hpp"
#include "types.hpp"

#include <optional>
#include <vector>

#include "wlr-wrap-start.hpp"
#include <wlr/types/wlr_pointer_constraints_v1.h>
#include <wlr/types/wlr_seat.h>
#include <wlr/types/wlr_virtual_keyboard_v1.h>
#include <wlr/types/wlr_virtual_pointer_v1.h>
Expand All @@ -19,6 +22,7 @@ class Seat {
wl_listener new_input;
wl_listener new_virtual_pointer;
wl_listener new_virtual_keyboard;
wl_listener new_pointer_constraint;
wl_listener request_cursor;
wl_listener request_set_selection;
Listeners(Seat& parent) noexcept : parent(parent) {}
Expand All @@ -34,11 +38,14 @@ class Seat {
std::vector<Keyboard*> keyboards;
wlr_virtual_pointer_manager_v1* virtual_pointer_mgr;
wlr_virtual_keyboard_manager_v1* virtual_keyboard_mgr;
wlr_pointer_constraints_v1* pointer_constraints;
std::optional<PointerConstraint> current_constraint = {};

Seat(Server& server) noexcept;
~Seat() noexcept;

void new_input_device(wlr_input_device* device);
void set_constraint(wlr_pointer_constraint_v1* wlr_constraint);
};

#endif
1 change: 1 addition & 0 deletions src/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ magpie_sources = [
'output.cpp',
'server.cpp',
'xwayland.cpp',
'input/constraint.cpp',
'input/cursor.cpp',
'input/keyboard.cpp',
'input/seat.cpp',
Expand Down
4 changes: 4 additions & 0 deletions src/server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ void Server::focus_view(View& view, wlr_surface* surface) {
if (keyboard != nullptr) {
wlr_seat_keyboard_notify_enter(seat, view.surface, keyboard->keycodes, keyboard->num_keycodes, &keyboard->modifiers);
}

wlr_pointer_constraint_v1* constraint =
wlr_pointer_constraints_v1_constraint_for_surface(server.seat->pointer_constraints, surface, seat);
server.seat->set_constraint(constraint);
}

Surface* Server::surface_at(const double lx, const double ly, wlr_surface** surface, double* sx, double* sy) {
Expand Down
1 change: 1 addition & 0 deletions src/types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class Output;
class Seat;
class Keyboard;
class Cursor;
class PointerConstraint;

struct Surface;
struct View;
Expand Down

0 comments on commit 569d020

Please sign in to comment.