summaryrefslogtreecommitdiffstats
path: root/swaybar/bar.c
diff options
context:
space:
mode:
Diffstat (limited to 'swaybar/bar.c')
-rw-r--r--swaybar/bar.c167
1 files changed, 161 insertions, 6 deletions
diff --git a/swaybar/bar.c b/swaybar/bar.c
index 0fc41517..f743236c 100644
--- a/swaybar/bar.c
+++ b/swaybar/bar.c
@@ -9,7 +9,13 @@
9#include <sys/wait.h> 9#include <sys/wait.h>
10#include <unistd.h> 10#include <unistd.h>
11#include <wayland-client.h> 11#include <wayland-client.h>
12#include <wayland-cursor.h>
12#include <wlr/util/log.h> 13#include <wlr/util/log.h>
14#ifdef __FreeBSD__
15#include <dev/evdev/input-event-codes.h>
16#else
17#include <linux/input-event-codes.h>
18#endif
13#include "swaybar/render.h" 19#include "swaybar/render.h"
14#include "swaybar/config.h" 20#include "swaybar/config.h"
15#include "swaybar/event_loop.h" 21#include "swaybar/event_loop.h"
@@ -18,6 +24,7 @@
18#include "swaybar/ipc.h" 24#include "swaybar/ipc.h"
19#include "ipc-client.h" 25#include "ipc-client.h"
20#include "list.h" 26#include "list.h"
27#include "log.h"
21#include "pango.h" 28#include "pango.h"
22#include "pool-buffer.h" 29#include "pool-buffer.h"
23#include "wlr-layer-shell-unstable-v1-client-protocol.h" 30#include "wlr-layer-shell-unstable-v1-client-protocol.h"
@@ -27,12 +34,6 @@ static void bar_init(struct swaybar *bar) {
27 wl_list_init(&bar->outputs); 34 wl_list_init(&bar->outputs);
28} 35}
29 36
30struct swaybar_output *new_output(const char *name) {
31 struct swaybar_output *output = malloc(sizeof(struct swaybar_output));
32 output->name = strdup(name);
33 return output;
34}
35
36static void layer_surface_configure(void *data, 37static void layer_surface_configure(void *data,
37 struct zwlr_layer_surface_v1 *surface, 38 struct zwlr_layer_surface_v1 *surface,
38 uint32_t serial, uint32_t width, uint32_t height) { 39 uint32_t serial, uint32_t width, uint32_t height) {
@@ -56,12 +57,156 @@ struct zwlr_layer_surface_v1_listener layer_surface_listener = {
56 .closed = layer_surface_closed, 57 .closed = layer_surface_closed,
57}; 58};
58 59
60static void wl_pointer_enter(void *data, struct wl_pointer *wl_pointer,
61 uint32_t serial, struct wl_surface *surface,
62 wl_fixed_t surface_x, wl_fixed_t surface_y) {
63 struct swaybar *bar = data;
64 struct swaybar_pointer *pointer = &bar->pointer;
65 struct swaybar_output *output;
66 wl_list_for_each(output, &bar->outputs, link) {
67 if (output->surface == surface) {
68 pointer->current = output;
69 break;
70 }
71 }
72 wl_surface_attach(pointer->cursor_surface,
73 wl_cursor_image_get_buffer(pointer->cursor_image), 0, 0);
74 wl_pointer_set_cursor(wl_pointer, serial, pointer->cursor_surface,
75 pointer->cursor_image->hotspot_x,
76 pointer->cursor_image->hotspot_y);
77 wl_surface_commit(pointer->cursor_surface);
78}
79
80static void wl_pointer_leave(void *data, struct wl_pointer *wl_pointer,
81 uint32_t serial, struct wl_surface *surface) {
82 struct swaybar *bar = data;
83 bar->pointer.current = NULL;
84}
85
86static void wl_pointer_motion(void *data, struct wl_pointer *wl_pointer,
87 uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y) {
88 struct swaybar *bar = data;
89 bar->pointer.x = wl_fixed_to_int(surface_x);
90 bar->pointer.y = wl_fixed_to_int(surface_y);
91}
92
93static void wl_pointer_button(void *data, struct wl_pointer *wl_pointer,
94 uint32_t serial, uint32_t time, uint32_t button, uint32_t state) {
95 struct swaybar *bar = data;
96 struct swaybar_pointer *pointer = &bar->pointer;
97 struct swaybar_output *output = pointer->current;
98 if (!sway_assert(output, "button with no active output")) {
99 return;
100 }
101 if (state != WL_POINTER_BUTTON_STATE_PRESSED) {
102 return;
103 }
104 struct swaybar_hotspot *hotspot;
105 wl_list_for_each(hotspot, &output->hotspots, link) {
106 if (pointer->x >= hotspot->x
107 && pointer->y >= hotspot->y
108 && pointer->x < hotspot->x + hotspot->width
109 && pointer->y < hotspot->y + hotspot->height) {
110 hotspot->callback(output, pointer->x, pointer->y,
111 button, hotspot->data);
112 }
113 }
114}
115
116static void wl_pointer_axis(void *data, struct wl_pointer *wl_pointer,
117 uint32_t time, uint32_t axis, wl_fixed_t value) {
118 struct swaybar *bar = data;
119 struct swaybar_output *output = bar->pointer.current;
120 if (!sway_assert(output, "axis with no active output")) {
121 return;
122 }
123 double amt = wl_fixed_to_double(value);
124 if (!bar->config->wrap_scroll) {
125 int i = 0;
126 struct swaybar_workspace *ws = NULL;
127 wl_list_for_each(ws, &output->workspaces, link) {
128 if (ws->focused) {
129 break;
130 }
131 ++i;
132 }
133 int len = wl_list_length(&output->workspaces);
134 if (!sway_assert(i != len, "axis with null workspace")) {
135 return;
136 }
137 if (i == 0 && amt > 0) {
138 return; // Do not wrap
139 }
140 if (i == len - 1 && amt < 0) {
141 return; // Do not wrap
142 }
143 }
144
145 const char *workspace_name =
146 amt < 0 ? "prev_on_output" : "next_on_output";
147 ipc_send_workspace_command(bar, workspace_name);
148}
149
150static void wl_pointer_frame(void *data, struct wl_pointer *wl_pointer) {
151 // Who cares
152}
153
154static void wl_pointer_axis_source(void *data, struct wl_pointer *wl_pointer,
155 uint32_t axis_source) {
156 // Who cares
157}
158
159static void wl_pointer_axis_stop(void *data, struct wl_pointer *wl_pointer,
160 uint32_t time, uint32_t axis) {
161 // Who cares
162}
163
164static void wl_pointer_axis_discrete(void *data, struct wl_pointer *wl_pointer,
165 uint32_t axis, int32_t discrete) {
166 // Who cares
167}
168
169struct wl_pointer_listener pointer_listener = {
170 .enter = wl_pointer_enter,
171 .leave = wl_pointer_leave,
172 .motion = wl_pointer_motion,
173 .button = wl_pointer_button,
174 .axis = wl_pointer_axis,
175 .frame = wl_pointer_frame,
176 .axis_source = wl_pointer_axis_source,
177 .axis_stop = wl_pointer_axis_stop,
178 .axis_discrete = wl_pointer_axis_discrete,
179};
180
181static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat,
182 enum wl_seat_capability caps) {
183 struct swaybar *bar = data;
184 if ((caps & WL_SEAT_CAPABILITY_POINTER)) {
185 bar->pointer.pointer = wl_seat_get_pointer(wl_seat);
186 wl_pointer_add_listener(bar->pointer.pointer, &pointer_listener, bar);
187 }
188}
189
190static void seat_handle_name(void *data, struct wl_seat *wl_seat,
191 const char *name) {
192 // Who cares
193}
194
195const struct wl_seat_listener seat_listener = {
196 .capabilities = seat_handle_capabilities,
197 .name = seat_handle_name,
198};
199
59static void handle_global(void *data, struct wl_registry *registry, 200static void handle_global(void *data, struct wl_registry *registry,
60 uint32_t name, const char *interface, uint32_t version) { 201 uint32_t name, const char *interface, uint32_t version) {
61 struct swaybar *bar = data; 202 struct swaybar *bar = data;
62 if (strcmp(interface, wl_compositor_interface.name) == 0) { 203 if (strcmp(interface, wl_compositor_interface.name) == 0) {
63 bar->compositor = wl_registry_bind(registry, name, 204 bar->compositor = wl_registry_bind(registry, name,
64 &wl_compositor_interface, 1); 205 &wl_compositor_interface, 1);
206 } else if (strcmp(interface, wl_seat_interface.name) == 0) {
207 bar->seat = wl_registry_bind(registry, name,
208 &wl_seat_interface, 1);
209 wl_seat_add_listener(bar->seat, &seat_listener, bar);
65 } else if (strcmp(interface, wl_shm_interface.name) == 0) { 210 } else if (strcmp(interface, wl_shm_interface.name) == 0) {
66 bar->shm = wl_registry_bind(registry, name, 211 bar->shm = wl_registry_bind(registry, name,
67 &wl_shm_interface, 1); 212 &wl_shm_interface, 1);
@@ -74,6 +219,7 @@ static void handle_global(void *data, struct wl_registry *registry,
74 &wl_output_interface, 1); 219 &wl_output_interface, 1);
75 output->index = index++; 220 output->index = index++;
76 wl_list_init(&output->workspaces); 221 wl_list_init(&output->workspaces);
222 wl_list_init(&output->hotspots);
77 wl_list_insert(&bar->outputs, &output->link); 223 wl_list_insert(&bar->outputs, &output->link);
78 } else if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) { 224 } else if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) {
79 bar->layer_shell = wl_registry_bind( 225 bar->layer_shell = wl_registry_bind(
@@ -116,6 +262,15 @@ void bar_setup(struct swaybar *bar,
116 wl_registry_add_listener(registry, &registry_listener, bar); 262 wl_registry_add_listener(registry, &registry_listener, bar);
117 wl_display_roundtrip(bar->display); 263 wl_display_roundtrip(bar->display);
118 assert(bar->compositor && bar->layer_shell && bar->shm); 264 assert(bar->compositor && bar->layer_shell && bar->shm);
265 struct swaybar_pointer *pointer = &bar->pointer;
266
267 assert(pointer->cursor_theme = wl_cursor_theme_load(NULL, 16, bar->shm));
268 struct wl_cursor *cursor;
269 assert(cursor = wl_cursor_theme_get_cursor(
270 pointer->cursor_theme, "left_ptr"));
271 pointer->cursor_image = cursor->images[0];
272 assert(pointer->cursor_surface =
273 wl_compositor_create_surface(bar->compositor));
119 274
120 // TODO: we might not necessarily be meant to do all of the outputs 275 // TODO: we might not necessarily be meant to do all of the outputs
121 struct swaybar_output *output; 276 struct swaybar_output *output;