This commit is contained in:
Drew DeVault 2016-01-29 10:08:37 +00:00
commit 53dea65cd0
11 changed files with 130 additions and 68 deletions

View file

@ -77,6 +77,9 @@ struct sway_container {
bool is_focused;
bool sticky; // floating view always visible on its output
// Custom arrange function
void (*arrange)(struct sway_container *, double width, double height);
// Attributes that mostly views have.
char *name;
char *class;

View file

@ -5,40 +5,43 @@
#include <wlc/wlc-wayland.h>
#include "wayland-desktop-shell-server-protocol.h"
#include "list.h"
#include "container.h"
struct background_config {
wlc_handle output;
wlc_resource surface;
// we need the wl_resource of the surface in the destructor
struct wl_resource *wl_surface_res;
wlc_handle output;
wlc_handle handle;
wlc_resource surface;
// we need the wl_resource of the surface in the destructor
struct wl_resource *wl_surface_res;
};
struct panel_config {
// wayland resource used in callbacks, is used to track this panel
struct wl_resource *wl_resource;
wlc_handle output;
wlc_resource surface;
// we need the wl_resource of the surface in the destructor
struct wl_resource *wl_surface_res;
enum desktop_shell_panel_position panel_position;
// wayland resource used in callbacks, is used to track this panel
struct wl_resource *wl_resource;
wlc_handle output;
wlc_resource surface;
// we need the wl_resource of the surface in the destructor
struct wl_resource *wl_surface_res;
enum desktop_shell_panel_position panel_position;
};
struct desktop_shell_state {
list_t *backgrounds;
list_t *panels;
list_t *lock_surfaces;
bool is_locked;
struct wlc_size panel_size;
list_t *backgrounds;
list_t *panels;
list_t *lock_surfaces;
bool is_locked;
struct wlc_size panel_size;
};
struct swaylock_state {
bool active;
wlc_handle output;
wlc_resource surface;
bool active;
wlc_handle output;
wlc_resource surface;
};
extern struct desktop_shell_state desktop_shell;
void register_extensions(void);
void arrange_background_view(swayc_t *view, double width, double height);
#endif

View file

@ -16,4 +16,6 @@ void get_absolute_position(swayc_t *container, struct wlc_point *point);
// given wlc_point.
void get_absolute_center_position(swayc_t *container, struct wlc_point *point);
struct output_config *config_for_output(wlc_handle output);
#endif

View file

@ -686,6 +686,7 @@ void apply_output_config(struct output_config *oc, swayc_t *output) {
snprintf(output_id, bufsize, "%d", output_i);
output_id[bufsize-1] = 0;
#ifdef NDEBUG
char *const cmd[] = {
"swaybg",
output_id,
@ -693,6 +694,15 @@ void apply_output_config(struct output_config *oc, swayc_t *output) {
oc->background_option,
NULL,
};
#else
char *const cmd[] = {
"./bin/swaybg",
output_id,
oc->background,
oc->background_option,
NULL,
};
#endif
output->bg_pid = fork();
if (output->bg_pid == 0) {

View file

@ -11,6 +11,7 @@
#include "layout.h"
#include "input_state.h"
#include "log.h"
#include "output.h"
#define ASSERT_NONNULL(PTR) \
sway_assert (PTR, #PTR "must be non-null")
@ -90,21 +91,7 @@ swayc_t *new_output(wlc_handle handle) {
sway_log(L_DEBUG, "New output %lu:%s", handle, name);
struct output_config *oc = NULL;
int i;
for (i = 0; i < config->output_configs->length; ++i) {
struct output_config *cur = config->output_configs->items[i];
if (strcasecmp(name, cur->name) == 0) {
sway_log(L_DEBUG, "Matched output config for %s", name);
oc = cur;
break;
}
if (strcasecmp("*", cur->name) == 0) {
sway_log(L_DEBUG, "Matched wildcard output config for %s", name);
oc = cur;
break;
}
}
struct output_config *oc = config_for_output(handle);
if (oc && !oc->enabled) {
return NULL;
@ -125,6 +112,7 @@ swayc_t *new_output(wlc_handle handle) {
// Create workspace
char *ws_name = NULL;
if (name) {
int i;
for (i = 0; i < config->workspace_outputs->length; ++i) {
struct workspace_output *wso = config->workspace_outputs->items[i];
if (strcasecmp(wso->output, name) == 0) {

View file

@ -24,18 +24,6 @@ static struct panel_config *find_or_create_panel_config(struct wl_resource *reso
return config;
}
void background_surface_destructor(struct wl_resource *resource) {
sway_log(L_DEBUG, "Background surface killed");
int i;
for (i = 0; i < desktop_shell.backgrounds->length; ++i) {
struct background_config *config = desktop_shell.backgrounds->items[i];
if (config->wl_surface_res == resource) {
list_del(desktop_shell.backgrounds, i);
break;
}
}
}
void panel_surface_destructor(struct wl_resource *resource) {
sway_log(L_DEBUG, "Panel surface killed");
int i;
@ -63,6 +51,19 @@ void lock_surface_destructor(struct wl_resource *resource) {
}
}
void arrange_background_view(swayc_t *view, double width, double height) {
sway_log(L_DEBUG, "Arranging background view %p", view);
int i;
for (i = 0; i < desktop_shell.backgrounds->length; ++i) {
struct background_config *config = desktop_shell.backgrounds->items[i];
if (config->handle == view->handle) {
struct wlc_size resolution = *wlc_output_get_resolution(config->output);
wlc_view_set_geometry(view->handle, WLC_RESIZE_EDGE_NONE, &(struct wlc_geometry){ wlc_origin_zero, resolution });
wlc_view_send_to_back(view->handle);
}
}
}
static void set_background(struct wl_client *client, struct wl_resource *resource,
struct wl_resource *_output, struct wl_resource *surface) {
wlc_handle output = wlc_handle_from_wl_output_resource(_output);
@ -73,9 +74,14 @@ static void set_background(struct wl_client *client, struct wl_resource *resourc
struct background_config *config = malloc(sizeof(struct background_config));
config->output = output;
config->surface = wlc_resource_from_wl_surface_resource(surface);
config->handle = wlc_handle_from_wl_surface_resource(surface);
config->wl_surface_res = surface;
list_add(desktop_shell.backgrounds, config);
wl_resource_set_destructor(surface, background_surface_destructor);
swayc_t *view = swayc_by_handle(config->handle);
if (view) {
view->arrange = arrange_background_view;
}
}
static void set_panel(struct wl_client *client, struct wl_resource *resource,

View file

@ -106,18 +106,10 @@ static void handle_output_destroyed(wlc_handle output) {
}
}
static void handle_output_pre_render(wlc_handle output) {
static void handle_output_post_render(wlc_handle output) {
struct wlc_size resolution = *wlc_output_get_resolution(output);
int i;
for (i = 0; i < desktop_shell.backgrounds->length; ++i) {
struct background_config *config = desktop_shell.backgrounds->items[i];
if (config->output == output) {
wlc_surface_render(config->surface, &(struct wlc_geometry){ wlc_origin_zero, resolution });
break;
}
}
for (i = 0; i < desktop_shell.panels->length; ++i) {
struct panel_config *config = desktop_shell.panels->items[i];
if (config->output == output) {
@ -153,6 +145,10 @@ static void handle_output_resolution_change(wlc_handle output, const struct wlc_
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;
struct output_config *oc = config_for_output(output);
if (oc) {
apply_output_config(oc, c);
}
c->width = to->w;
c->height = to->h;
arrange_windows(&root_container, -1, -1);
@ -237,12 +233,25 @@ static bool handle_view_created(wlc_handle handle) {
}
if (newview) {
int i;
set_focused_container(newview);
// Check if this view has a special role
wlc_resource resource = wlc_view_get_surface(handle);
for (i = 0; i < desktop_shell.backgrounds->length; ++i) {
struct background_config *config = desktop_shell.backgrounds->items[i];
if (config->surface == resource) {
sway_log(L_DEBUG, "Setting view %p as background", newview);
newview->handle = handle;
newview->arrange = arrange_background_view;
}
}
swayc_t *output = swayc_parent_by_type(newview, C_OUTPUT);
arrange_windows(output, -1, -1);
// check if it matches for_window in config and execute if so
list_t *criteria = criteria_for(newview);
for (int i = 0; i < criteria->length; i++) {
for (i = 0; i < criteria->length; i++) {
struct criteria *crit = criteria->items[i];
sway_log(L_DEBUG, "for_window '%s' matches new view %p, cmd: '%s'",
crit->crit_raw, newview, crit->cmdlist);
@ -674,7 +683,7 @@ struct wlc_interface interface = {
.resolution = handle_output_resolution_change,
.focus = handle_output_focused,
.render = {
.pre = handle_output_pre_render
.post = handle_output_post_render
}
},
.view = {

View file

@ -445,6 +445,12 @@ static void arrange_windows_r(swayc_t *container, double width, double height) {
sway_log(L_DEBUG, "Arranging layout for %p %s %fx%f+%f,%f", container,
container->name, container->width, container->height, container->x, container->y);
if (container->arrange) {
sway_log(L_DEBUG, "Invoking arrangement override handler for container %p", container);
container->arrange(container, width, height);
return;
}
double x = 0, y = 0;
switch (container->type) {
case C_ROOT:
@ -524,6 +530,14 @@ static void arrange_windows_r(swayc_t *container, double width, double height) {
y = container->y;
break;
}
int total_children = 0; // not including arrangement override containers
for (i = 0; i < container->children->length; ++i) {
swayc_t *child = container->children->items[i];
if (!child->arrange) {
total_children++;
}
}
double scale = 0;
switch (container->layout) {
@ -531,10 +545,12 @@ static void arrange_windows_r(swayc_t *container, double width, double height) {
default:
// Calculate total width
for (i = 0; i < container->children->length; ++i) {
double *old_width = &((swayc_t *)container->children->items[i])->width;
swayc_t *child = container->children->items[i];
if (child->arrange) continue;
double *old_width = &child->width;
if (*old_width <= 0) {
if (container->children->length > 1) {
*old_width = width / (container->children->length - 1);
if (total_children > 1) {
*old_width = width / (total_children - 1);
} else {
*old_width = width;
}
@ -547,6 +563,7 @@ static void arrange_windows_r(swayc_t *container, double width, double height) {
sway_log(L_DEBUG, "Arranging %p horizontally", container);
for (i = 0; i < container->children->length; ++i) {
swayc_t *child = container->children->items[i];
if (child->arrange) continue;
sway_log(L_DEBUG, "Calculating arrangement for %p:%d (will scale %f by %f)", child, child->type, width, scale);
child->x = x;
child->y = y;
@ -563,10 +580,12 @@ static void arrange_windows_r(swayc_t *container, double width, double height) {
case L_VERT:
// Calculate total height
for (i = 0; i < container->children->length; ++i) {
double *old_height = &((swayc_t *)container->children->items[i])->height;
swayc_t *child = container->children->items[i];
if (child->arrange) continue;
double *old_height = &child->height;
if (*old_height <= 0) {
if (container->children->length > 1) {
*old_height = height / (container->children->length - 1);
if (total_children > 1) {
*old_height = height / (total_children - 1);
} else {
*old_height = height;
}
@ -579,6 +598,7 @@ static void arrange_windows_r(swayc_t *container, double width, double height) {
sway_log(L_DEBUG, "Arranging %p vertically", container);
for (i = 0; i < container->children->length; ++i) {
swayc_t *child = container->children->items[i];
if (child->arrange) continue;
sway_log(L_DEBUG, "Calculating arrangement for %p:%d (will scale %f by %f)", child, child->type, height, scale);
child->x = x;
child->y = y;

View file

@ -1,4 +1,5 @@
#include <strings.h>
#include "config.h"
#include "output.h"
#include "log.h"
@ -22,6 +23,26 @@ swayc_t *output_by_name(const char* name, const struct wlc_point *abs_pos) {
return NULL;
}
struct output_config *config_for_output(wlc_handle output) {
const char *name = wlc_output_get_name(output);
struct output_config *oc = NULL;
int i;
for (i = 0; i < config->output_configs->length; ++i) {
struct output_config *cur = config->output_configs->items[i];
if (strcasecmp(name, cur->name) == 0) {
sway_log(L_DEBUG, "Matched output config for %s", name);
oc = cur;
break;
}
if (strcasecmp("*", cur->name) == 0) {
sway_log(L_DEBUG, "Matched wildcard output config for %s", name);
oc = cur;
break;
}
}
return oc;
}
// Position is where on the edge (as absolute position) the adjacent output should be searched for.
swayc_t *swayc_adjacent_output(swayc_t *output, enum movement_direction dir,
const struct wlc_point *abs_pos, bool pick_closest) {

View file

@ -46,10 +46,10 @@ int main(int argc, const char **argv) {
}
int desired_output = atoi(argv[1]);
sway_log(L_INFO, "Using output %d of %d", desired_output, registry->outputs->length);
int i;
struct output_state *output = registry->outputs->items[desired_output];
struct window *window = window_setup(registry, output->width, output->height, false);
sway_log(L_INFO, "Using output %d of %d (%dx%d)", desired_output, registry->outputs->length, output->width, output->height);
int i;
struct window *window = window_setup(registry, output->width, output->height, true);
if (!window) {
sway_abort("Failed to create surfaces.");
}

View file

@ -69,7 +69,7 @@ struct window *window_setup(struct registry *registry, uint32_t width, uint32_t
window->surface = wl_compositor_create_surface(registry->compositor);
if (shell_surface) {
window->shell_surface = wl_shell_get_shell_surface(registry->shell, window->surface);
window->shell_surface = wl_shell_get_shell_surface(window->registry->shell, window->surface);
wl_shell_surface_add_listener(window->shell_surface, &surface_listener, window);
wl_shell_surface_set_toplevel(window->shell_surface);
}