summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Drew DeVault <sir@cmpwn.com>2016-07-14 18:57:37 -0400
committerLibravatar GitHub <noreply@github.com>2016-07-14 18:57:37 -0400
commit6abbe04e7590f3bfba13351eb87ada70ac3d506e (patch)
treef7c64d6e9d082bd080960c42e21e54edf01839de
parentMerge pull request #726 from Hummer12007/hwc (diff)
parentSend command to sway to change workspace when workspace button is clicked (diff)
downloadsway-6abbe04e7590f3bfba13351eb87ada70ac3d506e.tar.gz
sway-6abbe04e7590f3bfba13351eb87ada70ac3d506e.tar.zst
sway-6abbe04e7590f3bfba13351eb87ada70ac3d506e.zip
Merge pull request #743 from deklov/panel-as-shell-03
Set panels/backgrounds' geometries correctly and don't render them ex…
-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 {
32 bool urgent; 32 bool urgent;
33}; 33};
34 34
35/** Global bar state */
36extern struct bar swaybar;
37
35/** 38/**
36 * Setup bar. 39 * Setup bar.
37 */ 40 */
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);
13 */ 13 */
14bool handle_ipc_event(struct bar *bar); 14bool handle_ipc_event(struct bar *bar);
15 15
16
17/**
18 * Send workspace command to sway
19 */
20void ipc_send_workspace_command(const char *workspace_name);
21
16#endif /* _SWAYBAR_IPC_H */ 22#endif /* _SWAYBAR_IPC_H */
17 23
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
14 */ 14 */
15void set_window_height(struct window *window, int height); 15void set_window_height(struct window *window, int height);
16 16
17/**
18 * Compute the size of a workspace name
19 */
20void workspace_button_size(struct window *window, const char *workspace_name, int *width, int *height);
21
17#endif /* _SWAYBAR_RENDER_H */ 22#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 {
28}; 28};
29 29
30struct pointer_input { 30struct pointer_input {
31 wl_fixed_t last_x; 31 int last_x;
32 wl_fixed_t last_y; 32 int last_y;
33 33
34 void (*notify)(struct window *window, wl_fixed_t x, wl_fixed_t y, uint32_t button); 34 void (*notify)(struct window *window, int x, int y, uint32_t button);
35}; 35};
36 36
37struct window { 37struct 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 {
11 wlc_resource surface; 11 wlc_resource surface;
12 // we need the wl_resource of the surface in the destructor 12 // we need the wl_resource of the surface in the destructor
13 struct wl_resource *wl_surface_res; 13 struct wl_resource *wl_surface_res;
14 // used to determine if client is a background
15 struct wl_client *client;
16}; 14};
17 15
18struct panel_config { 16struct panel_config {
@@ -25,6 +23,8 @@ struct panel_config {
25 enum desktop_shell_panel_position panel_position; 23 enum desktop_shell_panel_position panel_position;
26 // used to determine if client is a panel 24 // used to determine if client is a panel
27 struct wl_client *client; 25 struct wl_client *client;
26 // wlc handle for this panel's surface, not set until panel is created
27 wlc_handle handle;
28}; 28};
29 29
30struct desktop_shell_state { 30struct 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
73 } 73 }
74 sway_log(L_DEBUG, "Setting surface %p as background for output %d", surface, (int)output); 74 sway_log(L_DEBUG, "Setting surface %p as background for output %d", surface, (int)output);
75 struct background_config *config = malloc(sizeof(struct background_config)); 75 struct background_config *config = malloc(sizeof(struct background_config));
76 config->client = client;
77 config->output = output; 76 config->output = output;
78 config->surface = wlc_resource_from_wl_surface_resource(surface); 77 config->surface = wlc_resource_from_wl_surface_resource(surface);
79 config->wl_surface_res = surface; 78 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 @@
33// Event handled by sway and should not be sent to client 33// Event handled by sway and should not be sent to client
34#define EVENT_HANDLED true 34#define EVENT_HANDLED true
35 35
36static struct panel_config *if_panel_find_config(struct wl_client *client) {
37 int i;
38 for (i = 0; i < desktop_shell.panels->length; i++) {
39 struct panel_config *config = desktop_shell.panels->items[i];
40 if (config->client == client) {
41 return config;
42 }
43 }
44 return NULL;
45}
46
47static struct wlc_geometry compute_panel_geometry(struct panel_config *config) {
48 const struct wlc_size resolution = *wlc_output_get_resolution(config->output);
49 const struct wlc_geometry *old = wlc_view_get_geometry(config->handle);
50 struct wlc_geometry new;
51
52 switch (config->panel_position) {
53 case DESKTOP_SHELL_PANEL_POSITION_TOP:
54 new.origin.x = 0;
55 new.origin.y = 0;
56 new.size.w = resolution.w;
57 new.size.h = old->size.h;
58 break;
59 case DESKTOP_SHELL_PANEL_POSITION_BOTTOM:
60 new.origin.x = 0;
61 new.origin.y = resolution.h - old->size.h;
62 new.size.w = resolution.w;
63 new.size.h = old->size.h;
64 break;
65 case DESKTOP_SHELL_PANEL_POSITION_LEFT:
66 new.origin.x = 0;
67 new.origin.y = 0;
68 new.size.w = old->size.w;
69 new.size.h = resolution.h;
70 break;
71 case DESKTOP_SHELL_PANEL_POSITION_RIGHT:
72 new.origin.x = resolution.w - old->size.w;
73 new.origin.y = 0;
74 new.size.w = old->size.w;
75 new.size.h = resolution.h;
76 break;
77 }
78
79 return new;
80}
81
82static void update_panel_geometry(struct panel_config *config) {
83 struct wlc_geometry geometry = compute_panel_geometry(config);
84 wlc_view_set_geometry(config->handle, 0, &geometry);
85}
86
87static void update_panel_geometries(wlc_handle output) {
88 for (int i = 0; i < desktop_shell.panels->length; i++) {
89 struct panel_config *config = desktop_shell.panels->items[i];
90 if (config->output == output) {
91 update_panel_geometry(config);
92 }
93 }
94}
95
36/* Handles */ 96/* Handles */
37 97
38static bool handle_input_created(struct libinput_device *device) { 98static bool handle_input_created(struct libinput_device *device) {
@@ -119,32 +179,6 @@ static void handle_output_pre_render(wlc_handle output) {
119 break; 179 break;
120 } 180 }
121 } 181 }
122
123 for (i = 0; i < desktop_shell.panels->length; ++i) {
124 struct panel_config *config = desktop_shell.panels->items[i];
125 if (config->output == output) {
126 struct wlc_size size = *wlc_surface_get_size(config->surface);
127 struct wlc_geometry geo = {
128 .size = size
129 };
130 switch (config->panel_position) {
131 case DESKTOP_SHELL_PANEL_POSITION_TOP:
132 geo.origin = (struct wlc_point){ 0, 0 };
133 break;
134 case DESKTOP_SHELL_PANEL_POSITION_BOTTOM:
135 geo.origin = (struct wlc_point){ 0, resolution.h - size.h };
136 break;
137 case DESKTOP_SHELL_PANEL_POSITION_LEFT:
138 geo.origin = (struct wlc_point){ 0, 0 };
139 break;
140 case DESKTOP_SHELL_PANEL_POSITION_RIGHT:
141 geo.origin = (struct wlc_point){ resolution.w - size.w, 0 };
142 break;
143 }
144 wlc_surface_render(config->surface, &geo);
145 break;
146 }
147 }
148} 182}
149 183
150static void handle_output_post_render(wlc_handle output) { 184static void handle_output_post_render(wlc_handle output) {
@@ -158,10 +192,16 @@ static void handle_view_pre_render(wlc_handle view) {
158 192
159static void handle_output_resolution_change(wlc_handle output, const struct wlc_size *from, const struct wlc_size *to) { 193static void handle_output_resolution_change(wlc_handle output, const struct wlc_size *from, const struct wlc_size *to) {
160 sway_log(L_DEBUG, "Output %u resolution changed to %d x %d", (unsigned int)output, to->w, to->h); 194 sway_log(L_DEBUG, "Output %u resolution changed to %d x %d", (unsigned int)output, to->w, to->h);
195
161 swayc_t *c = swayc_by_handle(output); 196 swayc_t *c = swayc_by_handle(output);
162 if (!c) return; 197 if (!c) {
198 return;
199 }
163 c->width = to->w; 200 c->width = to->w;
164 c->height = to->h; 201 c->height = to->h;
202
203 update_panel_geometries(output);
204
165 arrange_windows(&root_container, -1, -1); 205 arrange_windows(&root_container, -1, -1);
166} 206}
167 207
@@ -176,28 +216,6 @@ static void handle_output_focused(wlc_handle output, bool focus) {
176 } 216 }
177} 217}
178 218
179static bool client_is_background(struct wl_client *client) {
180 int i;
181 for (i = 0; i < desktop_shell.backgrounds->length; i++) {
182 struct background_config *config = desktop_shell.backgrounds->items[i];
183 if (config->client == client) {
184 return true;
185 }
186 }
187 return false;
188}
189
190static bool client_is_panel(struct wl_client *client) {
191 int i;
192 for (i = 0; i < desktop_shell.panels->length; i++) {
193 struct panel_config *config = desktop_shell.panels->items[i];
194 if (config->client == client) {
195 return true;
196 }
197 }
198 return false;
199}
200
201static void ws_cleanup() { 219static void ws_cleanup() {
202 swayc_t *op, *ws; 220 swayc_t *op, *ws;
203 int i = 0, j; 221 int i = 0, j;
@@ -228,8 +246,14 @@ static bool handle_view_created(wlc_handle handle) {
228 bool return_to_workspace = false; 246 bool return_to_workspace = false;
229 struct wl_client *client = wlc_view_get_wl_client(handle); 247 struct wl_client *client = wlc_view_get_wl_client(handle);
230 pid_t pid; 248 pid_t pid;
231 249 struct panel_config *panel_config = NULL;
232 if (client_is_background(client) || client_is_panel(client)) { 250
251 panel_config = if_panel_find_config(client);
252 if (panel_config) {
253 panel_config->handle = handle;
254 update_panel_geometry(panel_config);
255 wlc_view_set_mask(handle, VISIBLE);
256 wlc_view_set_output(handle, panel_config->output);
233 return true; 257 return true;
234 } 258 }
235 259
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) {
58 return output; 58 return output;
59} 59}
60 60
61static void mouse_button_notify(struct window *window, int x, int y, uint32_t button) {
62 sway_log(L_DEBUG, "Mouse button %d clicked at %d %d\n", button, x, y);
63
64 struct output *clicked_output = NULL;
65 for (int i = 0; i < swaybar.outputs->length; i++) {
66 struct output *output = swaybar.outputs->items[i];
67 if (window == output->window) {
68 clicked_output = output;
69 break;
70 }
71 }
72
73 if (!sway_assert(clicked_output != NULL, "Got pointer event for non-existing output")) {
74 return;
75 }
76
77 double button_x = 0.5;
78 for (int i = 0; i < clicked_output->workspaces->length; i++) {
79 struct workspace *workspace = clicked_output->workspaces->items[i];
80 int button_width, button_height;
81
82 workspace_button_size(window, workspace->name, &button_width, &button_height);
83
84 button_x += button_width;
85 if (x <= button_x) {
86 ipc_send_workspace_command(workspace->name);
87 break;
88 }
89 }
90}
91
61void bar_setup(struct bar *bar, const char *socket_path, const char *bar_id) { 92void bar_setup(struct bar *bar, const char *socket_path, const char *bar_id) {
62 /* initialize bar with default values */ 93 /* initialize bar with default values */
63 bar_init(bar); 94 bar_init(bar);
@@ -92,6 +123,9 @@ void bar_setup(struct bar *bar, const char *socket_path, const char *bar_id) {
92 /* set font */ 123 /* set font */
93 bar_output->window->font = bar->config->font; 124 bar_output->window->font = bar->config->font;
94 125
126 /* set font */
127 bar_output->window->pointer_input.notify = mouse_button_notify;
128
95 /* set window height */ 129 /* set window height */
96 set_window_height(bar_output->window, bar->config->height); 130 set_window_height(bar_output->window, bar->config->height);
97 } 131 }
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 @@
7#include "bar/config.h" 7#include "bar/config.h"
8#include "bar/ipc.h" 8#include "bar/ipc.h"
9 9
10void ipc_send_workspace_command(const char *workspace_name) {
11 uint32_t size = strlen("workspace ") + strlen(workspace_name) + 1;
12
13 char command[size];
14 sprintf(command, "workspace %s", workspace_name);
15
16 ipc_single_command(swaybar.ipc_socketfd, IPC_COMMAND, command, &size);
17}
18
10static void ipc_parse_config(struct config *config, const char *payload) { 19static void ipc_parse_config(struct config *config, const char *payload) {
11 json_object *bar_config = json_tokener_parse(payload); 20 json_object *bar_config = json_tokener_parse(payload);
12 json_object *tray_output, *mode, *hidden_bar, *position, *status_command; 21 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
172 172
173} 173}
174 174
175static char *handle_workspace_number(bool strip_num, const char *ws_name) { 175static const char *strip_workspace_name(bool strip_num, const char *ws_name) {
176 bool strip = false; 176 bool strip = false;
177 int i; 177 int i;
178 178
@@ -190,18 +190,23 @@ static char *handle_workspace_number(bool strip_num, const char *ws_name) {
190 } 190 }
191 191
192 if (strip) { 192 if (strip) {
193 return strdup(ws_name + i); 193 return ws_name + i;
194 } 194 }
195 195
196 return strdup(ws_name); 196 return ws_name;
197}
198
199void workspace_button_size(struct window *window, const char *workspace_name, int *width, int *height) {
200 const char *stripped_name = strip_workspace_name(swaybar.config->strip_workspace_numbers, workspace_name);
201
202 get_text_size(window->cairo, window->font, width, height, false, "%s", stripped_name);
203 *width += 2 * ws_horizontal_padding;
204 *height += 2 * ws_vertical_padding;
197} 205}
198 206
199static void render_workspace_button(struct window *window, struct config *config, struct workspace *ws, double *x) { 207static void render_workspace_button(struct window *window, struct config *config, struct workspace *ws, double *x) {
200 // strip workspace numbers if required 208 const char *stripped_name = strip_workspace_name(config->strip_workspace_numbers, ws->name);
201 char *name = handle_workspace_number(config->strip_workspace_numbers, ws->name);
202 209
203 int width, height;
204 get_text_size(window->cairo, window->font, &width, &height, false, "%s", name);
205 struct box_colors box_colors; 210 struct box_colors box_colors;
206 if (ws->urgent) { 211 if (ws->urgent) {
207 box_colors = config->colors.urgent_workspace; 212 box_colors = config->colors.urgent_workspace;
@@ -213,26 +218,25 @@ static void render_workspace_button(struct window *window, struct config *config
213 box_colors = config->colors.inactive_workspace; 218 box_colors = config->colors.inactive_workspace;
214 } 219 }
215 220
221 int width, height;
222 workspace_button_size(window, stripped_name, &width, &height);
223
216 // background 224 // background
217 cairo_set_source_u32(window->cairo, box_colors.background); 225 cairo_set_source_u32(window->cairo, box_colors.background);
218 cairo_rectangle(window->cairo, *x, 1.5, width + ws_horizontal_padding * 2 - 1, 226 cairo_rectangle(window->cairo, *x, 1.5, width - 1, height);
219 height + ws_vertical_padding * 2);
220 cairo_fill(window->cairo); 227 cairo_fill(window->cairo);
221 228
222 // border 229 // border
223 cairo_set_source_u32(window->cairo, box_colors.border); 230 cairo_set_source_u32(window->cairo, box_colors.border);
224 cairo_rectangle(window->cairo, *x, 1.5, width + ws_horizontal_padding * 2 - 1, 231 cairo_rectangle(window->cairo, *x, 1.5, width - 1, height);
225 height + ws_vertical_padding * 2);
226 cairo_stroke(window->cairo); 232 cairo_stroke(window->cairo);
227 233
228 // text 234 // text
229 cairo_set_source_u32(window->cairo, box_colors.text); 235 cairo_set_source_u32(window->cairo, box_colors.text);
230 cairo_move_to(window->cairo, (int)*x + ws_horizontal_padding, margin); 236 cairo_move_to(window->cairo, (int)*x + ws_horizontal_padding, margin);
231 pango_printf(window->cairo, window->font, false, "%s", name); 237 pango_printf(window->cairo, window->font, false, "%s", stripped_name);
232
233 *x += width + ws_horizontal_padding * 2 + ws_spacing;
234 238
235 free(name); 239 *x += width + ws_spacing;
236} 240}
237 241
238static void render_binding_mode_indicator(struct window *window, struct config *config, double pos) { 242static 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) {
54 sway_abort("Failed to create surfaces."); 54 sway_abort("Failed to create surfaces.");
55 } 55 }
56 desktop_shell_set_background(registry->desktop_shell, output->output, window->surface); 56 desktop_shell_set_background(registry->desktop_shell, output->output, window->surface);
57 window_make_shell(window);
58 list_add(surfaces, window); 57 list_add(surfaces, window);
59 58
60#ifdef WITH_GDK_PIXBUF 59#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,
32 uint32_t time, wl_fixed_t sx_w, wl_fixed_t sy_w) { 32 uint32_t time, wl_fixed_t sx_w, wl_fixed_t sy_w) {
33 struct window *window = data; 33 struct window *window = data;
34 34
35 window->pointer_input.last_x = sx_w; 35 window->pointer_input.last_x = wl_fixed_to_int(sx_w);
36 window->pointer_input.last_y = sy_w; 36 window->pointer_input.last_y = wl_fixed_to_int(sy_w);
37} 37}
38 38
39static void pointer_handle_button(void *data, struct wl_pointer *pointer, uint32_t serial, 39static void pointer_handle_button(void *data, struct wl_pointer *pointer, uint32_t serial,