aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/bar/bar.h3
-rw-r--r--include/bar/ipc.h6
-rw-r--r--include/bar/render.h5
-rw-r--r--include/client/window.h6
-rw-r--r--include/extensions.h4
-rw-r--r--sway/extensions.c1
-rw-r--r--sway/handlers.c126
-rw-r--r--swaybar/bar.c34
-rw-r--r--swaybar/ipc.c9
-rw-r--r--swaybar/render.c34
-rw-r--r--swaybg/main.c1
-rw-r--r--wayland/window.c4
12 files changed, 158 insertions, 75 deletions
diff --git a/include/bar/bar.h b/include/bar/bar.h
index c20efc55..a3c511d9 100644
--- a/include/bar/bar.h
+++ b/include/bar/bar.h
@@ -32,6 +32,9 @@ struct workspace {
bool urgent;
};
+/** Global bar state */
+extern struct bar swaybar;
+
/**
* Setup bar.
*/
diff --git a/include/bar/ipc.h b/include/bar/ipc.h
index 741c067b..c11931d0 100644
--- a/include/bar/ipc.h
+++ b/include/bar/ipc.h
@@ -13,5 +13,11 @@ void ipc_bar_init(struct bar *bar, const char *bar_id);
*/
bool handle_ipc_event(struct bar *bar);
+
+/**
+ * Send workspace command to sway
+ */
+void ipc_send_workspace_command(const char *workspace_name);
+
#endif /* _SWAYBAR_IPC_H */
diff --git a/include/bar/render.h b/include/bar/render.h
index 931a1cdd..114f43f4 100644
--- a/include/bar/render.h
+++ b/include/bar/render.h
@@ -14,4 +14,9 @@ void render(struct output *output, struct config *config, struct status_line *li
*/
void set_window_height(struct window *window, int height);
+/**
+ * Compute the size of a workspace name
+ */
+void workspace_button_size(struct window *window, const char *workspace_name, int *width, int *height);
+
#endif /* _SWAYBAR_RENDER_H */
diff --git a/include/client/window.h b/include/client/window.h
index 7be4fff3..55a12225 100644
--- a/include/client/window.h
+++ b/include/client/window.h
@@ -28,10 +28,10 @@ struct cursor {
};
struct pointer_input {
- wl_fixed_t last_x;
- wl_fixed_t last_y;
+ int last_x;
+ int last_y;
- void (*notify)(struct window *window, wl_fixed_t x, wl_fixed_t y, uint32_t button);
+ void (*notify)(struct window *window, int x, int y, uint32_t button);
};
struct window {
diff --git a/include/extensions.h b/include/extensions.h
index 7c508b5e..d26e95c1 100644
--- a/include/extensions.h
+++ b/include/extensions.h
@@ -11,8 +11,6 @@ struct background_config {
wlc_resource surface;
// we need the wl_resource of the surface in the destructor
struct wl_resource *wl_surface_res;
- // used to determine if client is a background
- struct wl_client *client;
};
struct panel_config {
@@ -25,6 +23,8 @@ struct panel_config {
enum desktop_shell_panel_position panel_position;
// used to determine if client is a panel
struct wl_client *client;
+ // wlc handle for this panel's surface, not set until panel is created
+ wlc_handle handle;
};
struct desktop_shell_state {
diff --git a/sway/extensions.c b/sway/extensions.c
index 1fe15ac5..ab425fa7 100644
--- a/sway/extensions.c
+++ b/sway/extensions.c
@@ -73,7 +73,6 @@ static void set_background(struct wl_client *client, struct wl_resource *resourc
}
sway_log(L_DEBUG, "Setting surface %p as background for output %d", surface, (int)output);
struct background_config *config = malloc(sizeof(struct background_config));
- config->client = client;
config->output = output;
config->surface = wlc_resource_from_wl_surface_resource(surface);
config->wl_surface_res = surface;
diff --git a/sway/handlers.c b/sway/handlers.c
index 4336b6c7..a7a87564 100644
--- a/sway/handlers.c
+++ b/sway/handlers.c
@@ -33,6 +33,66 @@
// Event handled by sway and should not be sent to client
#define EVENT_HANDLED true
+static struct panel_config *if_panel_find_config(struct wl_client *client) {
+ int i;
+ for (i = 0; i < desktop_shell.panels->length; i++) {
+ struct panel_config *config = desktop_shell.panels->items[i];
+ if (config->client == client) {
+ return config;
+ }
+ }
+ return NULL;
+}
+
+static struct wlc_geometry compute_panel_geometry(struct panel_config *config) {
+ const struct wlc_size resolution = *wlc_output_get_resolution(config->output);
+ const struct wlc_geometry *old = wlc_view_get_geometry(config->handle);
+ struct wlc_geometry new;
+
+ switch (config->panel_position) {
+ case DESKTOP_SHELL_PANEL_POSITION_TOP:
+ new.origin.x = 0;
+ new.origin.y = 0;
+ new.size.w = resolution.w;
+ new.size.h = old->size.h;
+ break;
+ case DESKTOP_SHELL_PANEL_POSITION_BOTTOM:
+ new.origin.x = 0;
+ new.origin.y = resolution.h - old->size.h;
+ new.size.w = resolution.w;
+ new.size.h = old->size.h;
+ break;
+ case DESKTOP_SHELL_PANEL_POSITION_LEFT:
+ new.origin.x = 0;
+ new.origin.y = 0;
+ new.size.w = old->size.w;
+ new.size.h = resolution.h;
+ break;
+ case DESKTOP_SHELL_PANEL_POSITION_RIGHT:
+ new.origin.x = resolution.w - old->size.w;
+ new.origin.y = 0;
+ new.size.w = old->size.w;
+ new.size.h = resolution.h;
+ break;
+ }
+
+ return new;
+}
+
+static void update_panel_geometry(struct panel_config *config) {
+ struct wlc_geometry geometry = compute_panel_geometry(config);
+ wlc_view_set_geometry(config->handle, 0, &geometry);
+}
+
+static void update_panel_geometries(wlc_handle output) {
+ for (int i = 0; i < desktop_shell.panels->length; i++) {
+ struct panel_config *config = desktop_shell.panels->items[i];
+ if (config->output == output) {
+ update_panel_geometry(config);
+ }
+ }
+}
+
/* Handles */
static bool handle_input_created(struct libinput_device *device) {
@@ -119,32 +179,6 @@ static void handle_output_pre_render(wlc_handle output) {
break;
}
}
-
- for (i = 0; i < desktop_shell.panels->length; ++i) {
- struct panel_config *config = desktop_shell.panels->items[i];
- if (config->output == output) {
- struct wlc_size size = *wlc_surface_get_size(config->surface);
- struct wlc_geometry geo = {
- .size = size
- };
- switch (config->panel_position) {
- case DESKTOP_SHELL_PANEL_POSITION_TOP:
- geo.origin = (struct wlc_point){ 0, 0 };
- break;
- case DESKTOP_SHELL_PANEL_POSITION_BOTTOM:
- geo.origin = (struct wlc_point){ 0, resolution.h - size.h };
- break;
- case DESKTOP_SHELL_PANEL_POSITION_LEFT:
- geo.origin = (struct wlc_point){ 0, 0 };
- break;
- case DESKTOP_SHELL_PANEL_POSITION_RIGHT:
- geo.origin = (struct wlc_point){ resolution.w - size.w, 0 };
- break;
- }
- wlc_surface_render(config->surface, &geo);
- break;
- }
- }
}
static void handle_output_post_render(wlc_handle output) {
@@ -158,10 +192,16 @@ static void handle_view_pre_render(wlc_handle view) {
static void handle_output_resolution_change(wlc_handle output, const struct wlc_size *from, const struct wlc_size *to) {
sway_log(L_DEBUG, "Output %u resolution changed to %d x %d", (unsigned int)output, to->w, to->h);
+
swayc_t *c = swayc_by_handle(output);
- if (!c) return;
+ if (!c) {
+ return;
+ }
c->width = to->w;
c->height = to->h;
+
+ update_panel_geometries(output);
+
arrange_windows(&root_container, -1, -1);
}
@@ -176,28 +216,6 @@ static void handle_output_focused(wlc_handle output, bool focus) {
}
}
-static bool client_is_background(struct wl_client *client) {
- int i;
- for (i = 0; i < desktop_shell.backgrounds->length; i++) {
- struct background_config *config = desktop_shell.backgrounds->items[i];
- if (config->client == client) {
- return true;
- }
- }
- return false;
-}
-
-static bool client_is_panel(struct wl_client *client) {
- int i;
- for (i = 0; i < desktop_shell.panels->length; i++) {
- struct panel_config *config = desktop_shell.panels->items[i];
- if (config->client == client) {
- return true;
- }
- }
- return false;
-}
-
static void ws_cleanup() {
swayc_t *op, *ws;
int i = 0, j;
@@ -228,8 +246,14 @@ static bool handle_view_created(wlc_handle handle) {
bool return_to_workspace = false;
struct wl_client *client = wlc_view_get_wl_client(handle);
pid_t pid;
-
- if (client_is_background(client) || client_is_panel(client)) {
+ struct panel_config *panel_config = NULL;
+
+ panel_config = if_panel_find_config(client);
+ if (panel_config) {
+ panel_config->handle = handle;
+ update_panel_geometry(panel_config);
+ wlc_view_set_mask(handle, VISIBLE);
+ wlc_view_set_output(handle, panel_config->output);
return true;
}
diff --git a/swaybar/bar.c b/swaybar/bar.c
index 6d858f92..4f8063ac 100644
--- a/swaybar/bar.c
+++ b/swaybar/bar.c
@@ -58,6 +58,37 @@ struct output *new_output(const char *name) {
return output;
}
+static void mouse_button_notify(struct window *window, int x, int y, uint32_t button) {
+ sway_log(L_DEBUG, "Mouse button %d clicked at %d %d\n", button, x, y);
+
+ struct output *clicked_output = NULL;
+ for (int i = 0; i < swaybar.outputs->length; i++) {
+ struct output *output = swaybar.outputs->items[i];
+ if (window == output->window) {
+ clicked_output = output;
+ break;
+ }
+ }
+
+ if (!sway_assert(clicked_output != NULL, "Got pointer event for non-existing output")) {
+ return;
+ }
+
+ double button_x = 0.5;
+ for (int i = 0; i < clicked_output->workspaces->length; i++) {
+ struct workspace *workspace = clicked_output->workspaces->items[i];
+ int button_width, button_height;
+
+ workspace_button_size(window, workspace->name, &button_width, &button_height);
+
+ button_x += button_width;
+ if (x <= button_x) {
+ ipc_send_workspace_command(workspace->name);
+ break;
+ }
+ }
+}
+
void bar_setup(struct bar *bar, const char *socket_path, const char *bar_id) {
/* initialize bar with default values */
bar_init(bar);
@@ -92,6 +123,9 @@ void bar_setup(struct bar *bar, const char *socket_path, const char *bar_id) {
/* set font */
bar_output->window->font = bar->config->font;
+ /* set font */
+ bar_output->window->pointer_input.notify = mouse_button_notify;
+
/* set window height */
set_window_height(bar_output->window, bar->config->height);
}
diff --git a/swaybar/ipc.c b/swaybar/ipc.c
index dacee4c2..15f40508 100644
--- a/swaybar/ipc.c
+++ b/swaybar/ipc.c
@@ -7,6 +7,15 @@
#include "bar/config.h"
#include "bar/ipc.h"
+void ipc_send_workspace_command(const char *workspace_name) {
+ uint32_t size = strlen("workspace ") + strlen(workspace_name) + 1;
+
+ char command[size];
+ sprintf(command, "workspace %s", workspace_name);
+
+ ipc_single_command(swaybar.ipc_socketfd, IPC_COMMAND, command, &size);
+}
+
static void ipc_parse_config(struct config *config, const char *payload) {
json_object *bar_config = json_tokener_parse(payload);
json_object *tray_output, *mode, *hidden_bar, *position, *status_command;
diff --git a/swaybar/render.c b/swaybar/render.c
index 273bd4f0..cea36f52 100644
--- a/swaybar/render.c
+++ b/swaybar/render.c
@@ -172,7 +172,7 @@ static void render_block(struct window *window, struct config *config, struct st
}
-static char *handle_workspace_number(bool strip_num, const char *ws_name) {
+static const char *strip_workspace_name(bool strip_num, const char *ws_name) {
bool strip = false;
int i;
@@ -190,18 +190,23 @@ static char *handle_workspace_number(bool strip_num, const char *ws_name) {
}
if (strip) {
- return strdup(ws_name + i);
+ return ws_name + i;
}
- return strdup(ws_name);
+ return ws_name;
+}
+
+void workspace_button_size(struct window *window, const char *workspace_name, int *width, int *height) {
+ const char *stripped_name = strip_workspace_name(swaybar.config->strip_workspace_numbers, workspace_name);
+
+ get_text_size(window->cairo, window->font, width, height, false, "%s", stripped_name);
+ *width += 2 * ws_horizontal_padding;
+ *height += 2 * ws_vertical_padding;
}
static void render_workspace_button(struct window *window, struct config *config, struct workspace *ws, double *x) {
- // strip workspace numbers if required
- char *name = handle_workspace_number(config->strip_workspace_numbers, ws->name);
+ const char *stripped_name = strip_workspace_name(config->strip_workspace_numbers, ws->name);
- int width, height;
- get_text_size(window->cairo, window->font, &width, &height, false, "%s", name);
struct box_colors box_colors;
if (ws->urgent) {
box_colors = config->colors.urgent_workspace;
@@ -213,26 +218,25 @@ static void render_workspace_button(struct window *window, struct config *config
box_colors = config->colors.inactive_workspace;
}
+ int width, height;
+ workspace_button_size(window, stripped_name, &width, &height);
+
// background
cairo_set_source_u32(window->cairo, box_colors.background);
- cairo_rectangle(window->cairo, *x, 1.5, width + ws_horizontal_padding * 2 - 1,
- height + ws_vertical_padding * 2);
+ cairo_rectangle(window->cairo, *x, 1.5, width - 1, height);
cairo_fill(window->cairo);
// border
cairo_set_source_u32(window->cairo, box_colors.border);
- cairo_rectangle(window->cairo, *x, 1.5, width + ws_horizontal_padding * 2 - 1,
- height + ws_vertical_padding * 2);
+ cairo_rectangle(window->cairo, *x, 1.5, width - 1, height);
cairo_stroke(window->cairo);
// text
cairo_set_source_u32(window->cairo, box_colors.text);
cairo_move_to(window->cairo, (int)*x + ws_horizontal_padding, margin);
- pango_printf(window->cairo, window->font, false, "%s", name);
-
- *x += width + ws_horizontal_padding * 2 + ws_spacing;
+ pango_printf(window->cairo, window->font, false, "%s", stripped_name);
- free(name);
+ *x += width + ws_spacing;
}
static void render_binding_mode_indicator(struct window *window, struct config *config, double pos) {
diff --git a/swaybg/main.c b/swaybg/main.c
index 4e0cc4b3..fbd0d16b 100644
--- a/swaybg/main.c
+++ b/swaybg/main.c
@@ -54,7 +54,6 @@ int main(int argc, const char **argv) {
sway_abort("Failed to create surfaces.");
}
desktop_shell_set_background(registry->desktop_shell, output->output, window->surface);
- window_make_shell(window);
list_add(surfaces, window);
#ifdef WITH_GDK_PIXBUF
diff --git a/wayland/window.c b/wayland/window.c
index e055e244..9b6e5b00 100644
--- a/wayland/window.c
+++ b/wayland/window.c
@@ -32,8 +32,8 @@ static void pointer_handle_motion(void *data, struct wl_pointer *pointer,
uint32_t time, wl_fixed_t sx_w, wl_fixed_t sy_w) {
struct window *window = data;
- window->pointer_input.last_x = sx_w;
- window->pointer_input.last_y = sy_w;
+ window->pointer_input.last_x = wl_fixed_to_int(sx_w);
+ window->pointer_input.last_y = wl_fixed_to_int(sy_w);
}
static void pointer_handle_button(void *data, struct wl_pointer *pointer, uint32_t serial,