click handling (without modifiers)

This commit is contained in:
Raphael Robatsch 2021-10-26 11:40:46 +02:00
parent dd9c7d72cc
commit 8c959d60a1
6 changed files with 115 additions and 31 deletions

View File

@ -75,22 +75,22 @@
<event name="selected">
<description summary="updates the selected state of the monitor">
</description>
<arg name="selected" type="int"/>
<arg name="selected" type="uint"/>
</event>
<event name="tag">
<description summary="updates the state of one tag">
</description>
<arg name="tag" type="int"/>
<arg name="tag" type="uint"/>
<arg name="state" type="uint" enum="tag_state"/>
<arg name="num_clients" type="int"/>
<arg name="num_clients" type="uint"/>
<arg name="focused_client" type="int" summary="-1 if there is no focused client"/>
</event>
<event name="layout">
<description summary="updates the selected layout">
</description>
<arg name="layout" type="int"/>
<arg name="layout" type="uint"/>
</event>
<event name="title">
@ -103,5 +103,18 @@
<description summary="sent after all other events have been sent. allows for atomic updates.">
</description>
</event>
<request name="set_tags">
<description summary="sets the active tags on this monitor. changes are applied immediately.">
</description>
<arg name="tagmask" type="uint"/>
<arg name="toggle_tagset" type="uint"/>
</request>
<request name="set_layout">
<description summary="sets the active layout on this monitor. changes are applied immediately.">
</description>
<arg name="layout" type="uint"/>
</request>
</interface>
</protocol>

View File

@ -32,10 +32,11 @@ static QFontMetrics fontMetrics = QFontMetrics {font};
const wl_surface* Bar::surface() const { return _surface.get(); }
Bar::Bar()
Bar::Bar(Monitor *mon)
{
for (auto tag : tagNames) {
_tags.push_back({ tag, ZNET_TAPESOFTWARE_DWL_WM_MONITOR_V1_TAG_STATE_NONE, 0, 0, 0 });
_mon = mon;
for (auto i=0u; i<tagNames.size(); i++) {
_tags.push_back({ ZNET_TAPESOFTWARE_DWL_WM_MONITOR_V1_TAG_STATE_NONE, 0, 0, 0 });
}
}
@ -57,11 +58,29 @@ void Bar::create(wl_output *output)
wl_surface_commit(_surface.get());
}
void Bar::click(int x, int)
void Bar::click(int x, int, int btn, unsigned int modifiers)
{
for (auto tag=_tags.rbegin(); tag != _tags.rend(); tag++) {
if (x > tag->x) {
// todo toggle
Arg arg = {0};
Arg *argp = nullptr;
Control control = Control::None;
if (x > _statusX) {
control = Control::StatusText;
} else if (x > _titleX) {
control = Control::WinTitle;
} else if (x > _layoutX) {
control = Control::LayoutSymbol;
} else for (auto tag = _tags.size()-1; tag >= 0; tag--) {
if (x > _tags[tag].x) {
control = Control::TagBar;
arg.ui = 1<<tag;
argp = &arg;
break;
}
}
for (auto i = 0u; i < sizeof(buttons)/sizeof(buttons[0]); i++) {
const auto& button = buttons[i];
if (button.control == control && button.btn == btn && button.modifiers == modifiers) {
button.func(*_mon, *(argp ? argp : &button.arg));
return;
}
}
@ -112,8 +131,11 @@ void Bar::render()
renderTags();
setColorScheme(_selected ? colorActive : colorInactive);
_layoutX = _x;
renderText(layoutNames[_layout]);
_titleX = _x;
renderText(_title);
_statusX = _x;
renderStatus();
_painter = nullptr;
@ -132,11 +154,12 @@ void Bar::setColorScheme(const ColorScheme &scheme)
void Bar::renderTags()
{
for (auto &tag : _tags) {
for (auto i=0u; i<_tags.size(); i++) {
auto& tag = _tags[i];
tag.x = _x;
setColorScheme(tag.state & ZNET_TAPESOFTWARE_DWL_WM_MONITOR_V1_TAG_STATE_URGENT ? colorUrgent
: tag.state & ZNET_TAPESOFTWARE_DWL_WM_MONITOR_V1_TAG_STATE_ACTIVE ? colorActive : colorInactive);
renderText(tag.name);
renderText(tagNames[i]);
auto indicators = qMin(tag.numClients, _bufs->height/2);
for (auto ind = 0; ind < indicators; ind++) {
if (ind == tag.focusedClient) {

View File

@ -13,22 +13,24 @@
#include "shm_buffer.hpp"
struct Tag {
QString name;
znet_tapesoftware_dwl_wm_monitor_v1_tag_state state;
int numClients;
int focusedClient;
int x;
};
struct Monitor;
class Bar {
static const zwlr_layer_surface_v1_listener _layerSurfaceListener;
static const wl_callback_listener _frameListener;
wl_unique_ptr<wl_surface> _surface;
wl_unique_ptr<zwlr_layer_surface_v1> _layerSurface;
Monitor *_mon;
QPainter *_painter {nullptr};
std::optional<ShmBuffer> _bufs;
int _textY, _x;
int _statusX, _titleX, _layoutX;
bool _invalid {false};
std::vector<Tag> _tags;
@ -45,7 +47,7 @@ class Bar {
int textWidth(const QString &text);
void setColorScheme(const ColorScheme &scheme);
public:
Bar();
Bar(Monitor *mon);
const wl_surface* surface() const;
void create(wl_output *output);
void setSelected(bool selected);
@ -54,5 +56,5 @@ public:
void setTitle(const char *title);
void setStatus(const QString &status);
void invalidate();
void click(int x, int y);
void click(int x, int y, int btn, unsigned int modifiers);
};

View File

@ -2,14 +2,26 @@
// See LICENSE file for copyright and license details.
#pragma once
#include <wayland-client.h>
#include <memory>
#include <vector>
#include <wayland-client.h>
#include <linux/input-event-codes.h>
#include <QColor>
#include <QString>
#include "wlr-layer-shell-unstable-v1-client-protocol.h"
#include "net-tapesoftware-dwl-wm-unstable-v1-client-protocol.h"
struct ColorScheme {
QColor fg, bg;
};
union Arg {
int i;
unsigned int ui;
float f;
const void *v;
};
struct Monitor;
extern wl_display *display;
extern wl_compositor *compositor;
extern wl_shm *shm;
@ -17,8 +29,17 @@ extern zwlr_layer_shell_v1 *wlrLayerShell;
extern std::vector<QString> tagNames;
extern std::vector<QString> layoutNames;
struct ColorScheme {
QColor fg, bg;
void toggleview(Monitor &m, const Arg &arg);
void view(Monitor &m, const Arg &arg);
void setlayout(Monitor &m, const Arg &arg);
enum class Control { None, TagBar, LayoutSymbol, WinTitle, StatusText };
struct Button {
Control control;
unsigned int modifiers; // todo xkbcommon
int btn; // <linux/input-event-codes.h>
void (*func)(Monitor &mon, const Arg &arg);
const Arg arg;
};
// wayland smart pointers

View File

@ -16,3 +16,11 @@ constexpr bool fontBold = false;
constexpr ColorScheme colorInactive = {QColor(0xbb, 0xbb, 0xbb), QColor(0x22, 0x22, 0x22)};
constexpr ColorScheme colorActive = {QColor(0xee, 0xee, 0xee), QColor(0x00, 0x55, 0x77)};
constexpr ColorScheme colorUrgent = {colorActive.bg, colorActive.fg};
constexpr Button buttons[] = {
{ Control::TagBar, 0, BTN_LEFT, toggleview, {0} },
{ Control::TagBar, 0, BTN_MIDDLE, view, {0} },
//{ Control::TagBar, 0, BTN_RIGHT, tag, {0} },
{ Control::LayoutSymbol, 0, BTN_LEFT, setlayout, {.ui = 0} },
{ Control::LayoutSymbol, 0, BTN_RIGHT, setlayout, {.ui = 2} },
};

View File

@ -12,6 +12,7 @@
#include <unistd.h>
#include <linux/input-event-codes.h>
#include <optional>
#include <vector>
#include <QGuiApplication>
#include <QSocketNotifier>
#include <wayland-client.h>
@ -44,6 +45,7 @@ zwlr_layer_shell_v1 *wlrLayerShell;
znet_tapesoftware_dwl_wm_v1 *dwlWm;
std::vector<QString> tagNames;
std::vector<QString> layoutNames;
static xdg_wm_base *xdgWmBase;
static bool ready;
static std::vector<Monitor> monitors;
static QString lastStatus;
@ -53,7 +55,19 @@ static int statusFifoWriter {-1};
static QSocketNotifier *displayWriteNotifier;
static bool quitting {false};
static xdg_wm_base *xdgWmBase;
void toggleview(Monitor &m, const Arg &arg)
{
znet_tapesoftware_dwl_wm_monitor_v1_set_tags(m.dwlMonitor.get(), arg.ui, 0);
}
void view(Monitor &m, const Arg &arg)
{
znet_tapesoftware_dwl_wm_monitor_v1_set_tags(m.dwlMonitor.get(), arg.ui, 1);
}
void setlayout(Monitor &m, const Arg &arg)
{
znet_tapesoftware_dwl_wm_monitor_v1_set_layout(m.dwlMonitor.get(), arg.ui);
}
static const struct xdg_wm_base_listener xdgWmBaseListener = {
[](void*, xdg_wm_base *sender, uint32_t serial) {
xdg_wm_base_pong(sender, serial);
@ -66,7 +80,7 @@ struct SeatState {
wl_cursor_image *cursorImage;
Bar *focusedBar;
int x, y;
bool leftButtonClick;
std::vector<int> btns;
};
static SeatState seatState;
static Bar* barFromSurface(const wl_surface *surface)
@ -92,17 +106,20 @@ static const struct wl_pointer_listener pointerListener = {
seatState.y = wl_fixed_to_int(y);
},
.button = [](void*, wl_pointer*, uint32_t, uint32_t, uint32_t button, uint32_t pressed) {
if (button == BTN_LEFT) {
seatState.leftButtonClick = pressed == WL_POINTER_BUTTON_STATE_PRESSED;
auto it = std::find(begin(seatState.btns), end(seatState.btns), button);
if (pressed == WL_POINTER_BUTTON_STATE_PRESSED && it == end(seatState.btns)) {
seatState.btns.push_back(button);
} else if (pressed == WL_POINTER_BUTTON_STATE_RELEASED && it != end(seatState.btns)) {
seatState.btns.erase(it);
}
},
.axis = [](void*, wl_pointer*, uint32_t, uint32_t, wl_fixed_t) { },
.frame = [](void*, wl_pointer*) {
if (!seatState.focusedBar) return;
if (seatState.leftButtonClick) {
seatState.leftButtonClick = false;
seatState.focusedBar->click(seatState.x, seatState.y);
for (auto btn : seatState.btns) {
seatState.focusedBar->click(seatState.x, seatState.y, btn, 0);
}
seatState.btns.clear();
},
.axis_source = [](void*, wl_pointer*, uint32_t) { },
.axis_stop = [](void*, wl_pointer*, uint32_t, uint32_t) { },
@ -138,15 +155,15 @@ static const struct znet_tapesoftware_dwl_wm_v1_listener dwlWmListener = {
};
static const struct znet_tapesoftware_dwl_wm_monitor_v1_listener dwlWmMonitorListener {
.selected = [](void *mv, znet_tapesoftware_dwl_wm_monitor_v1*, int32_t selected) {
.selected = [](void *mv, znet_tapesoftware_dwl_wm_monitor_v1*, uint32_t selected) {
auto mon = static_cast<Monitor*>(mv);
mon->bar->setSelected(selected);
},
.tag = [](void *mv, znet_tapesoftware_dwl_wm_monitor_v1*, int32_t tag, uint32_t state, int32_t numClients, int32_t focusedClient) {
.tag = [](void *mv, znet_tapesoftware_dwl_wm_monitor_v1*, uint32_t tag, uint32_t state, uint32_t numClients, int32_t focusedClient) {
auto mon = static_cast<Monitor*>(mv);
mon->bar->setTag(tag, static_cast<znet_tapesoftware_dwl_wm_monitor_v1_tag_state>(state), numClients, focusedClient);
},
.layout = [](void *mv, znet_tapesoftware_dwl_wm_monitor_v1*, int32_t layout) {
.layout = [](void *mv, znet_tapesoftware_dwl_wm_monitor_v1*, uint32_t layout) {
auto mon = static_cast<Monitor*>(mv);
mon->bar->setLayout(layout);
},
@ -160,13 +177,14 @@ static const struct znet_tapesoftware_dwl_wm_monitor_v1_listener dwlWmMonitorLis
mon->bar->invalidate();
} else {
mon->bar->create(mon->wlOutput.get());
mon->created = true;
}
}
};
static void setupMonitor(Monitor &monitor) {
monitor.dwlMonitor.reset(znet_tapesoftware_dwl_wm_v1_get_monitor(dwlWm, monitor.wlOutput.get()));
monitor.bar.emplace();
monitor.bar.emplace(&monitor);
monitor.bar->setStatus(lastStatus);
znet_tapesoftware_dwl_wm_monitor_v1_add_listener(monitor.dwlMonitor.get(), &dwlWmMonitorListener, &monitor);
}
@ -255,7 +273,6 @@ struct HandleGlobalHelper {
static void registryHandleGlobal(void*, wl_registry *registry, uint32_t name, const char *interface, uint32_t version)
{
auto reg = HandleGlobalHelper { registry, name, interface };
printf("got global: %s v%d\n", interface, version);
if (reg.handle(compositor, wl_compositor_interface, 4)) return;
if (reg.handle(shm, wl_shm_interface, 1)) return;
if (reg.handle(wlrLayerShell, zwlr_layer_shell_v1_interface, 4)) return;