Skip to content

Commit

Permalink
Initial mouse wheel support (#6)
Browse files Browse the repository at this point in the history
Probably a bit shaky but has initial support of wheel data from Wayland
to Lua widgets.

Showcasing with audio widget. Actual values sent to pactl seems to be a
bit badly chosen, something better is needed.
  • Loading branch information
2hdddg authored Jan 24, 2024
1 parent c666d7c commit ff32887
Show file tree
Hide file tree
Showing 11 changed files with 129 additions and 15 deletions.
14 changes: 12 additions & 2 deletions config/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ local function render_workspaces(displayName)
end

local function click_workspace(tag)
os.execute("swaymsg workspace '" .. tag .. "'")
os.execute('swaymsg workspace "' .. tag .. '"')
end

local function render_time()
Expand Down Expand Up @@ -151,6 +151,16 @@ local function click_audio()
os.execute("pactl set-sink-mute @DEFAULT_SINK@ toggle")
end

local function wheel_audio(tag, value)
local prefix = ""
if value < 0 then
prefix = "+"
else
prefix = "-"
end
os.execute("pactl set-sink-volume @DEFAULT_SINK@ " .. prefix .. "10000")
end

local function click_keyboard()
local layout = "se"
if zen.keyboard.layout == "Swedish" then
Expand Down Expand Up @@ -211,7 +221,7 @@ return {
anchor = "right",
widgets = {
{ sources = {'keyboard'}, padding = { right = 10 }, on_render = render_keyboard, on_click = click_keyboard },
{ sources = {'audio'}, padding = { top = 10, right = 10 }, on_render = render_audio, on_click = click_audio },
{ sources = {'audio'}, padding = { top = 10, right = 10 }, on_render = render_audio, on_click = click_audio, on_wheel = wheel_audio },
{ sources = {'power'}, padding = { top = 10, right = 10 }, on_render = render_power },
{ sources = {'networks'}, padding = { top = 10, right = 10 }, on_render = render_networks },
},
Expand Down
1 change: 1 addition & 0 deletions src/Configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ struct WidgetConfig {
WidgetConfig() : padding({}) {}
std::function<std::unique_ptr<Renderable>(const std::string& outputName)> render;
std::function<void(std::string_view tag)> click;
std::function<void(std::string_view tag, int value)> wheel;
std::set<std::string> sources;
Padding padding;
};
Expand Down
12 changes: 10 additions & 2 deletions src/Manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@ std::shared_ptr<Manager> Manager::Create(std::shared_ptr<Registry> registry) {
spdlog::error("No seat in registry");
return nullptr;
}
registry->seat->RegisterClickHandler(
[manager](auto surface, int x, int y) { manager->ClickSurface(surface, x, y); });
registry->seat->RegisterHandlers(
[manager](auto surface, int x, int y) { manager->ClickSurface(surface, x, y); },
[manager](auto surface, int x, int y, int value) {
manager->WheelSurface(surface, x, y, value);
});
return manager;
}

Expand All @@ -20,6 +23,11 @@ void Manager::ClickSurface(wl_surface* surface, int x, int y) {
m_registry->BorrowOutputs().ClickSurface(surface, x, y);
}

void Manager::WheelSurface(wl_surface* surface, int x, int y, int value) {
spdlog::debug("Wheel in surface {} at {},{},{}", (void*)surface, x, y, value);
m_registry->BorrowOutputs().WheelSurface(surface, x, y, value);
}

void Manager::OnBatchProcessed() {
// Always publish sources
m_sources->PublishAll();
Expand Down
1 change: 1 addition & 0 deletions src/Manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class Manager : public IoBatchHandler {
void Hide();

void ClickSurface(wl_surface* surface, int x, int y);
void WheelSurface(wl_surface* surface, int x, int y, int value);

private:
Manager(std::shared_ptr<Registry> registry) : m_registry(registry) {}
Expand Down
19 changes: 19 additions & 0 deletions src/Output.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,17 @@ class Output {
return false;
}

bool WheelSurface(wl_surface *surface, int x, int y, int value) {
for (auto &kv : m_surfaces) {
if (kv.second->WheelSurface(surface, x, y, value)) {
spdlog::debug("Wheel in surface");
return true;
}
}
spdlog::debug("No surface found for wheel");
return false;
}

private:
Output(wl_output *wloutput, std::shared_ptr<Configuration> config, OnNamedCallback onNamed)
: m_wloutput(wloutput), m_config(config), m_onNamed(onNamed) {}
Expand Down Expand Up @@ -159,3 +170,11 @@ void Outputs::ClickSurface(wl_surface *surface, int x, int y) {
}
}
}

void Outputs::WheelSurface(wl_surface *surface, int x, int y, int value) {
for (auto &kv : m_map) {
if (kv.second->WheelSurface(surface, x, y, value)) {
return;
}
}
}
1 change: 1 addition & 0 deletions src/Output.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class Outputs {
void Hide(const Registry& registry);

void ClickSurface(wl_surface* surface, int x, int y);
void WheelSurface(wl_surface* surface, int x, int y, int value);

private:
Outputs(std::shared_ptr<Configuration> config) : m_config(config) {}
Expand Down
10 changes: 10 additions & 0 deletions src/ScriptContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ static void ParseWidgetConfig(const sol::table& table, std::vector<WidgetConfig>
}
return FromObject(*result);
};
// Click handler
sol::optional<sol::protected_function> maybeClickFunction = table["on_click"];
if (maybeClickFunction) {
auto clickFunction = *maybeClickFunction;
Expand All @@ -140,6 +141,15 @@ static void ParseWidgetConfig(const sol::table& table, std::vector<WidgetConfig>
return true;
};
}
// Wheel handler
sol::optional<sol::protected_function> maybeWheelFunction = table["on_wheel"];
if (maybeWheelFunction) {
auto wheelFunction = *maybeWheelFunction;
widget.wheel = [wheelFunction](std::string_view tag, int value) {
wheelFunction(tag, value);
return true;
};
}
widget.padding = PaddingFromProperty(table, "padding");
widgets.push_back(std::move(widget));
}
Expand Down
39 changes: 33 additions & 6 deletions src/Seat.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "Seat.h"

#include <linux/input-event-codes.h>
#include <sys/mman.h>
#include <wayland-client-protocol.h>
#include <xkbcommon/xkbcommon.h>
Expand Down Expand Up @@ -28,23 +29,43 @@ static void on_pointer_motion(void* data, struct wl_pointer*, uint32_t /*time*/,
static void on_pointer_button(void* data, struct wl_pointer*, uint32_t /*serial*/,
uint32_t /*time*/, uint32_t button, uint32_t state) {
spdlog::trace("Pointer click button {} state {}", button, state);
if (state == 0 /*release*/) {
if (state == 0 /*release*/ && button == BTN_LEFT) {
((Pointer*)data)->Click();
return;
}
}

void on_pointer_frame(void* /*data*/, struct wl_pointer*) {}
static void on_axis(void* data, struct wl_pointer*, uint32_t /*time*/, uint32_t axis,
wl_fixed_t value) {
spdlog::trace("on_axis, axis: {}, value: {}", axis, value);
if (axis == WL_POINTER_AXIS_SOURCE_WHEEL) {
((Pointer*)data)->Wheel(value);
}
}

static void on_pointer_frame(void* /*data*/, struct wl_pointer*) {}

static void on_axis_source(void* /*data*/, struct wl_pointer*, uint32_t /*axis_source*/) {}
static void on_axis_stop(void* /*data*/, struct wl_pointer*, uint32_t /*time*/, uint32_t /*axis*/) {
}
static void on_axis_discrete(void* /*data*/, struct wl_pointer*, uint32_t /*axis*/,
int32_t /*discrete*/) {}
/*
[2024-01-24 19:34:07.087] [trace] on_axis_source: 0
[2024-01-24 19:34:07.087] [trace] on_axis_discrete axis 0, discrete: 1
[2024-01-24 19:34:07.087] [trace] on_axis, axis: 0, value: 3840
*/

static const wl_pointer_listener pointer_listener = {
.enter = on_pointer_enter,
.leave = on_pointer_leave,
.motion = on_pointer_motion,
.button = on_pointer_button,
.axis = nullptr,
.axis = on_axis,
.frame = on_pointer_frame,
.axis_source = nullptr,
.axis_stop = nullptr,
.axis_discrete = nullptr,
.axis_source = on_axis_source,
.axis_stop = on_axis_stop,
.axis_discrete = on_axis_discrete,
// Version > supported
//.axis_value120 = nullptr,
//.axis_relative_direction = nullptr,
Expand All @@ -63,6 +84,12 @@ void Pointer::Click() {
m_clickHandler(m_current, wl_fixed_to_int(m_x), wl_fixed_to_int(m_y));
}

void Pointer::Wheel(wl_fixed_t value) {
if (!m_current) return;
if (!m_wheelHandler) return;
m_wheelHandler(m_current, wl_fixed_to_int(m_x), wl_fixed_to_int(m_y), wl_fixed_to_int(value));
}

static void on_keymap(void* data, struct wl_keyboard*, uint32_t format, int32_t fd, uint32_t size) {
if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) {
spdlog::error("Keyboard: Invalid keymap format");
Expand Down
12 changes: 9 additions & 3 deletions src/Seat.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "src/Sources.h"

using ClickHandler = std::function<void(wl_surface*, int, int)>;
using WheelHandler = std::function<void(wl_surface*, int, int, int)>;

class Keyboard : public Source {
public:
Expand Down Expand Up @@ -37,21 +38,26 @@ class Pointer {
wl_pointer_destroy(m_wlpointer);
m_wlpointer = nullptr;
}
void RegisterClickHandler(ClickHandler handler) { m_clickHandler = handler; }
void RegisterHandlers(ClickHandler clickHandler, WheelHandler wheelHandler) {
m_clickHandler = clickHandler;
m_wheelHandler = wheelHandler;
}
void Enter(wl_surface* surface) { m_current = surface; }
void Leave() { m_current = nullptr; }
void Track(wl_fixed_t x, wl_fixed_t y) {
m_x = x;
m_y = y;
}
void Click();
void Wheel(int value);

private:
wl_pointer* m_wlpointer;
wl_surface* m_current;
wl_fixed_t m_x;
wl_fixed_t m_y;
ClickHandler m_clickHandler;
WheelHandler m_wheelHandler;
};

class Seat {
Expand All @@ -63,11 +69,11 @@ class Seat {
m_wlseat = nullptr;
}

void RegisterClickHandler(ClickHandler handler) {
void RegisterHandlers(ClickHandler clickHandler, WheelHandler wheelHandler) {
// TODO: Log error
if (!m_pointer) return;

m_pointer->RegisterClickHandler(handler);
m_pointer->RegisterHandlers(clickHandler, wheelHandler);
}

std::shared_ptr<Keyboard> keyboard;
Expand Down
34 changes: 32 additions & 2 deletions src/ShellSurface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,7 @@ void ShellSurface::OnClosed() {
}

bool ShellSurface::ClickSurface(wl_surface *surface, int x, int y) {
bool isThis = surface == m_surface;
if (!isThis) {
if (surface != m_surface) {
return false;
}
// Check what widget
Expand Down Expand Up @@ -79,6 +78,37 @@ bool ShellSurface::ClickSurface(wl_surface *surface, int x, int y) {
return true;
}

// TODO: Refactor to share some code between Click and Wheel
bool ShellSurface::WheelSurface(wl_surface *surface, int x, int y, int value) {
if (surface != m_surface) {
return false;
}
// Check what widget
int i = 0;
for (const auto &w : m_drawn.widgets) {
if (w.position.Contains(x, y)) {
auto &widget = m_panelConfig.widgets.at(i);
if (widget.wheel) {
// Widget has a wheel handler. There might be inner more
// specific targets, find the tag of the correct one.
std::string tag = "";
for (const auto &t : w.targets) {
if (t.position.Contains(x, y)) {
tag = t.tag;
break;
}
}
spdlog::debug("Wheel in widget, tag: {}", tag);
widget.wheel(tag, value);
}
break;
}
i++;
}
// Return true even if no widget was found to stop trying other surfaces
return true;
}

void ShellSurface::Draw(const Registry &registry, BufferPool &bufferPool,
const std::string &outputName) {
if (m_isClosed) {
Expand Down
1 change: 1 addition & 0 deletions src/ShellSurface.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class ShellSurface {
void OnClosed();

bool ClickSurface(wl_surface *surface, int x, int y);
bool WheelSurface(wl_surface *surface, int x, int y, int value);

private:
ShellSurface(wl_output *output, wl_surface *surface, PanelConfig panelConfiguration)
Expand Down

0 comments on commit ff32887

Please sign in to comment.