Merge pull request #743 from deklov/panel-as-shell-03

Set panels/backgrounds' geometries correctly and don't render them ex…
This commit is contained in:
Drew DeVault 2016-07-14 18:57:37 -04:00 committed by GitHub
commit 6abbe04e75
12 changed files with 157 additions and 74 deletions

View file

@ -32,6 +32,9 @@ struct workspace {
bool urgent;
};
/** Global bar state */
extern struct bar swaybar;
/**
* Setup bar.
*/

View file

@ -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 */

View file

@ -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 */

View file

@ -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 {

View file

@ -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 {

View file

@ -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;

View file

@ -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;
struct panel_config *panel_config = NULL;
if (client_is_background(client) || client_is_panel(client)) {
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;
}

View file

@ -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);
}

View file

@ -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;

View file

@ -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);
pango_printf(window->cairo, window->font, false, "%s", stripped_name);
*x += width + ws_horizontal_padding * 2 + ws_spacing;
free(name);
*x += width + ws_spacing;
}
static void render_binding_mode_indicator(struct window *window, struct config *config, double pos) {

View file

@ -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

View file

@ -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,