mirror of
https://github.com/swaywm/sway.git
synced 2024-12-27 15:36:29 +01:00
Implement workspace switch on click
This commit is contained in:
parent
ae14dfc7ae
commit
2a5108a278
3 changed files with 67 additions and 19 deletions
|
@ -2,7 +2,6 @@
|
|||
#define _SWAYBAR_BAR_H
|
||||
#include <wayland-client.h>
|
||||
#include "pool-buffer.h"
|
||||
#include "list.h"
|
||||
|
||||
struct swaybar_config;
|
||||
struct swaybar_output;
|
||||
|
@ -14,6 +13,16 @@ struct swaybar_pointer {
|
|||
struct wl_cursor_image *cursor_image;
|
||||
struct wl_surface *cursor_surface;
|
||||
struct swaybar_output *current;
|
||||
int x, y;
|
||||
};
|
||||
|
||||
struct swaybar_hotspot {
|
||||
struct wl_list link;
|
||||
int x, y, width, height;
|
||||
void (*callback)(struct swaybar_output *output,
|
||||
int x, int y, uint32_t button, void *data);
|
||||
void (*destroy)(void *data);
|
||||
void *data;
|
||||
};
|
||||
|
||||
struct swaybar {
|
||||
|
@ -42,6 +51,7 @@ struct swaybar_output {
|
|||
struct zwlr_layer_surface_v1 *layer_surface;
|
||||
|
||||
struct wl_list workspaces;
|
||||
struct wl_list hotspots;
|
||||
|
||||
char *name;
|
||||
size_t index;
|
||||
|
@ -61,7 +71,6 @@ struct swaybar_workspace {
|
|||
bool urgent;
|
||||
};
|
||||
|
||||
// TODO: Rename stuff to match wlroots conventions (init/create/etc)
|
||||
void bar_setup(struct swaybar *bar,
|
||||
const char *socket_path,
|
||||
const char *bar_id);
|
||||
|
|
|
@ -34,12 +34,6 @@ static void bar_init(struct swaybar *bar) {
|
|||
wl_list_init(&bar->outputs);
|
||||
}
|
||||
|
||||
struct swaybar_output *new_output(const char *name) {
|
||||
struct swaybar_output *output = malloc(sizeof(struct swaybar_output));
|
||||
output->name = strdup(name);
|
||||
return output;
|
||||
}
|
||||
|
||||
static void layer_surface_configure(void *data,
|
||||
struct zwlr_layer_surface_v1 *surface,
|
||||
uint32_t serial, uint32_t width, uint32_t height) {
|
||||
|
@ -91,20 +85,39 @@ static void wl_pointer_leave(void *data, struct wl_pointer *wl_pointer,
|
|||
|
||||
static void wl_pointer_motion(void *data, struct wl_pointer *wl_pointer,
|
||||
uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y) {
|
||||
// TODO
|
||||
struct swaybar *bar = data;
|
||||
bar->pointer.x = wl_fixed_to_int(surface_x);
|
||||
bar->pointer.y = wl_fixed_to_int(surface_y);
|
||||
}
|
||||
|
||||
static void wl_pointer_button(void *data, struct wl_pointer *wl_pointer,
|
||||
uint32_t serial, uint32_t time, uint32_t button, uint32_t state) {
|
||||
wlr_log(L_DEBUG, "button");
|
||||
// TODO
|
||||
struct swaybar *bar = data;
|
||||
struct swaybar_pointer *pointer = &bar->pointer;
|
||||
struct swaybar_output *output = pointer->current;
|
||||
if (!sway_assert(output, "button with no active output")) {
|
||||
return;
|
||||
}
|
||||
if (state != WL_POINTER_BUTTON_STATE_PRESSED) {
|
||||
return;
|
||||
}
|
||||
struct swaybar_hotspot *hotspot;
|
||||
wl_list_for_each(hotspot, &output->hotspots, link) {
|
||||
if (pointer->x >= hotspot->x
|
||||
&& pointer->y >= hotspot->y
|
||||
&& pointer->x < hotspot->x + hotspot->width
|
||||
&& pointer->y < hotspot->y + hotspot->height) {
|
||||
hotspot->callback(output, pointer->x, pointer->y,
|
||||
button, hotspot->data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void wl_pointer_axis(void *data, struct wl_pointer *wl_pointer,
|
||||
uint32_t time, uint32_t axis, wl_fixed_t value) {
|
||||
struct swaybar *bar = data;
|
||||
struct swaybar_output *output = bar->pointer.current;
|
||||
if (!output) {
|
||||
if (!sway_assert(output, "axis with no active output")) {
|
||||
return;
|
||||
}
|
||||
double amt = wl_fixed_to_double(value);
|
||||
|
@ -206,6 +219,7 @@ static void handle_global(void *data, struct wl_registry *registry,
|
|||
&wl_output_interface, 1);
|
||||
output->index = index++;
|
||||
wl_list_init(&output->workspaces);
|
||||
wl_list_init(&output->hotspots);
|
||||
wl_list_insert(&bar->outputs, &output->link);
|
||||
} else if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) {
|
||||
bar->layer_shell = wl_registry_bind(
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
@ -8,6 +9,7 @@
|
|||
#include "pool-buffer.h"
|
||||
#include "swaybar/bar.h"
|
||||
#include "swaybar/config.h"
|
||||
#include "swaybar/ipc.h"
|
||||
#include "swaybar/render.h"
|
||||
#include "swaybar/status_line.h"
|
||||
#include "wlr-layer-shell-unstable-v1-client-protocol.h"
|
||||
|
@ -108,9 +110,14 @@ static const char *strip_workspace_number(const char *ws_name) {
|
|||
return ws_name;
|
||||
}
|
||||
|
||||
static void workspace_hotspot_callback(struct swaybar_output *output,
|
||||
int x, int y, uint32_t button, void *data) {
|
||||
ipc_send_workspace_command(output->bar, (const char *)data);
|
||||
}
|
||||
|
||||
static uint32_t render_workspace_button(cairo_t *cairo,
|
||||
struct swaybar_config *config, struct swaybar_workspace *ws,
|
||||
double *x, uint32_t height) {
|
||||
struct swaybar_output *output, struct swaybar_config *config,
|
||||
struct swaybar_workspace *ws, double *x, uint32_t height) {
|
||||
const char *name = ws->name;
|
||||
if (config->strip_workspace_numbers) {
|
||||
name = strip_workspace_number(ws->name);
|
||||
|
@ -156,8 +163,18 @@ static uint32_t render_workspace_button(cairo_t *cairo,
|
|||
cairo_move_to(cairo, *x + width / 2 - text_width / 2, (int)floor(text_y));
|
||||
pango_printf(cairo, config->font, 1, true, "%s", name);
|
||||
|
||||
struct swaybar_hotspot *hotspot = calloc(1, sizeof(struct swaybar_hotspot));
|
||||
hotspot->x = *x;
|
||||
hotspot->y = 0;
|
||||
hotspot->height = height;
|
||||
hotspot->width = width;
|
||||
hotspot->callback = workspace_hotspot_callback;
|
||||
hotspot->destroy = free;
|
||||
hotspot->data = strdup(name);
|
||||
wl_list_insert(&output->hotspots, &hotspot->link);
|
||||
|
||||
*x += width;
|
||||
return ideal_height;
|
||||
return height;
|
||||
}
|
||||
|
||||
static uint32_t render_to_cairo(cairo_t *cairo,
|
||||
|
@ -184,8 +201,8 @@ static uint32_t render_to_cairo(cairo_t *cairo,
|
|||
if (config->workspace_buttons) {
|
||||
struct swaybar_workspace *ws;
|
||||
wl_list_for_each_reverse(ws, &output->workspaces, link) {
|
||||
uint32_t h = render_workspace_button(
|
||||
cairo, config, ws, &x, output->height);
|
||||
uint32_t h = render_workspace_button(cairo,
|
||||
output, config, ws, &x, output->height);
|
||||
max_height = h > max_height ? h : max_height;
|
||||
}
|
||||
}
|
||||
|
@ -203,8 +220,16 @@ static uint32_t render_to_cairo(cairo_t *cairo,
|
|||
return max_height > output->height ? max_height : output->height;
|
||||
}
|
||||
|
||||
void render_frame(struct swaybar *bar,
|
||||
struct swaybar_output *output) {
|
||||
void render_frame(struct swaybar *bar, struct swaybar_output *output) {
|
||||
struct swaybar_hotspot *hotspot, *tmp;
|
||||
wl_list_for_each_safe(hotspot, tmp, &output->hotspots, link) {
|
||||
if (hotspot->destroy) {
|
||||
hotspot->destroy(hotspot->data);
|
||||
}
|
||||
wl_list_remove(&hotspot->link);
|
||||
free(hotspot);
|
||||
}
|
||||
|
||||
cairo_surface_t *recorder = cairo_recording_surface_create(
|
||||
CAIRO_CONTENT_COLOR_ALPHA, NULL);
|
||||
cairo_t *cairo = cairo_create(recorder);
|
||||
|
|
Loading…
Reference in a new issue