Browse Source

Restructure decorations so bounds can be window-specific (for fullscreen)

K. Lange 2 years ago
parent
commit
6e6675dd0a
10 changed files with 214 additions and 86 deletions
  1. 13 3
      apps/about.c
  2. 27 13
      apps/file-browser.c
  3. 12 6
      apps/help-browser.c
  4. 29 1
      apps/julia.c
  5. 16 5
      apps/plasma.c
  6. 9 3
      apps/sdf-demo.c
  7. 33 10
      apps/terminal.c
  8. 15 8
      base/usr/include/toaru/decorations.h
  9. 28 10
      lib/decor-fancy.c
  10. 32 27
      lib/decorations.c

+ 13 - 3
apps/about.c

@@ -36,13 +36,20 @@ static int center_x(int x) {
 }
 
 static void draw_string(int y, const char * string, int font, uint32_t color) {
-	draw_sdf_string(ctx, decor_left_width + center_x(draw_sdf_string_width(string, 16, font)), decor_top_height + 10 + logo.height + 10 + y, string, 16, color, font);
+
+	struct decor_bounds bounds;
+	decor_get_bounds(window, &bounds);
+
+	draw_sdf_string(ctx, bounds.left_width + center_x(draw_sdf_string_width(string, 16, font)), bounds.top_height + 10 + logo.height + 10 + y, string, 16, color, font);
 }
 
 static void redraw(void) {
 
+	struct decor_bounds bounds;
+	decor_get_bounds(window, &bounds);
+
 	draw_fill(ctx, rgb(204,204,204));
-	draw_sprite(ctx, &logo, decor_left_width + center_x(logo.width), decor_top_height + 10);
+	draw_sprite(ctx, &logo, bounds.left_width + center_x(logo.width), bounds.top_height + 10);
 
 	draw_string(0, version_str, SDF_FONT_BOLD, rgb(0,0,0));
 
@@ -101,7 +108,10 @@ int main(int argc, char * argv[]) {
 	}
 	init_decorations();
 
-	window = yutani_window_create(yctx, width + decor_width(), height + decor_height());
+	struct decor_bounds bounds;
+	decor_get_bounds(NULL, &bounds);
+
+	window = yutani_window_create(yctx, width + bounds.width, height + bounds.height);
 	req_center_x = yctx->display_width / 2;
 	req_center_y = yctx->display_height / 2;
 

+ 27 - 13
apps/file-browser.c

@@ -214,7 +214,10 @@ static void reinitialize_contents(void) {
 	/* Calculate height for current directory */
 	int calculated_height = file_pointers_len * 24;
 
-	contents_sprite = create_sprite(main_window->width - decor_width(), calculated_height, ALPHA_EMBEDDED);
+	struct decor_bounds bounds;
+	decor_get_bounds(main_window, &bounds);
+
+	contents_sprite = create_sprite(main_window->width - bounds.width, calculated_height, ALPHA_EMBEDDED);
 	contents = init_graphics_sprite(contents_sprite);
 
 	draw_fill(contents, rgb(255,255,255));
@@ -228,15 +231,18 @@ static void redraw_window(void) {
 
 	render_decorations(main_window, ctx, APPLICATION_TITLE);
 
-	menu_bar.x = decor_left_width;
-	menu_bar.y = decor_top_height;
-	menu_bar.width = ctx->width - decor_width();
+	struct decor_bounds bounds;
+	decor_get_bounds(main_window, &bounds);
+
+	menu_bar.x = bounds.left_width;
+	menu_bar.y = bounds.top_height;
+	menu_bar.width = ctx->width - bounds.width;
 	menu_bar.window = main_window;
 	menu_bar_render(&menu_bar, ctx);
 
 	gfx_clear_clip(ctx);
-	gfx_add_clip(ctx, decor_left_width, decor_top_height + MENU_BAR_HEIGHT, ctx->width - decor_width(), available_height);
-	draw_sprite(ctx, contents_sprite, decor_left_width, decor_top_height + MENU_BAR_HEIGHT - scroll_offset);
+	gfx_add_clip(ctx, bounds.left_width, bounds.top_height + MENU_BAR_HEIGHT, ctx->width - bounds.width, available_height);
+	draw_sprite(ctx, contents_sprite, bounds.left_width, bounds.top_height + MENU_BAR_HEIGHT - scroll_offset);
 	gfx_clear_clip(ctx);
 	gfx_add_clip(ctx, 0, 0, ctx->width, ctx->height);
 
@@ -251,7 +257,10 @@ static void resize_finish(int w, int h) {
 	yutani_window_resize_accept(yctx, main_window, w, h);
 	reinit_graphics_yutani(ctx, main_window);
 
-	available_height = ctx->height - MENU_BAR_HEIGHT - decor_height();
+	struct decor_bounds bounds;
+	decor_get_bounds(main_window, &bounds);
+
+	available_height = ctx->height - MENU_BAR_HEIGHT - bounds.height;
 
 	if (width_changed) {
 		reinitialize_contents();
@@ -320,6 +329,9 @@ int main(int argc, char * argv[]) {
 	yutani_window_move(yctx, main_window, yctx->display_width / 2 - main_window->width / 2, yctx->display_height / 2 - main_window->height / 2);
 	ctx = init_graphics_yutani_double_buffer(main_window);
 
+	struct decor_bounds bounds;
+	decor_get_bounds(main_window, &bounds);
+
 	yutani_window_advertise_icon(yctx, main_window, APPLICATION_TITLE, "folder");
 
 	menu_bar.entries = menu_entries;
@@ -348,7 +360,7 @@ int main(int argc, char * argv[]) {
 	menu_insert(m, menu_create_normal("star",NULL,"About " APPLICATION_TITLE,_menu_action_about));
 	menu_set_insert(menu_bar.set, "help", m);
 
-	available_height = ctx->height - MENU_BAR_HEIGHT - decor_height();
+	available_height = ctx->height - MENU_BAR_HEIGHT - bounds.height;
 	load_directory("/usr/share");
 	reinitialize_contents();
 	redraw_window();
@@ -390,6 +402,8 @@ int main(int argc, char * argv[]) {
 					{
 						struct yutani_msg_window_mouse_event * me = (void*)m->data;
 						yutani_window_t * win = hashmap_get(yctx->windows, (void*)me->wid);
+						struct decor_bounds bounds;
+						decor_get_bounds(win, &bounds);
 
 						if (win == main_window) {
 							int result = decor_handle_event(yctx, m);
@@ -409,10 +423,10 @@ int main(int argc, char * argv[]) {
 							/* Menu bar */
 							menu_bar_mouse_event(yctx, main_window, &menu_bar, me, me->new_x, me->new_y);
 
-							if (me->new_y > (int)(decor_top_height + MENU_BAR_HEIGHT) &&
-								me->new_y < (int)(main_window->height - decor_bottom_height) &&
-								me->new_x > (int)(decor_left_width) &&
-								me->new_x < (int)(main_window->width - decor_right_width)) {
+							if (me->new_y > (int)(bounds.top_height + MENU_BAR_HEIGHT) &&
+								me->new_y < (int)(main_window->height - bounds.bottom_height) &&
+								me->new_x > (int)(bounds.left_width) &&
+								me->new_x < (int)(main_window->width - bounds.right_width)) {
 								if (me->buttons & YUTANI_MOUSE_SCROLL_UP) {
 									/* Scroll up */
 									scroll_offset -= SCROLL_AMOUNT;
@@ -433,7 +447,7 @@ int main(int argc, char * argv[]) {
 								}
 
 								/* Get offset into contents */
-								int y_into = me->new_y - decor_top_height - MENU_BAR_HEIGHT + scroll_offset;
+								int y_into = me->new_y - bounds.top_height - MENU_BAR_HEIGHT + scroll_offset;
 								int offset = y_into / 24;
 								if (offset != hilighted_offset) {
 									int old_offset = hilighted_offset;

+ 12 - 6
apps/help-browser.c

@@ -59,7 +59,10 @@ static void reinitialize_contents(void) {
 	/* Calculate height for current directory */
 	int calculated_height = 200;
 
-	contents_sprite = create_sprite(main_window->width - decor_width(), calculated_height, ALPHA_EMBEDDED);
+	struct decor_bounds bounds;
+	decor_get_bounds(main_window, &bounds);
+
+	contents_sprite = create_sprite(main_window->width - bounds.width, calculated_height, ALPHA_EMBEDDED);
 	contents = init_graphics_sprite(contents_sprite);
 
 	draw_fill(contents, rgb(255,255,255));
@@ -73,15 +76,18 @@ static void redraw_window(void) {
 
 	render_decorations(main_window, ctx, APPLICATION_TITLE);
 
-	menu_bar.x = decor_left_width;
-	menu_bar.y = decor_top_height;
-	menu_bar.width = ctx->width - decor_width();
+	struct decor_bounds bounds;
+	decor_get_bounds(main_window, &bounds);
+
+	menu_bar.x = bounds.left_width;
+	menu_bar.y = bounds.top_height;
+	menu_bar.width = ctx->width - bounds.width;
 	menu_bar.window = main_window;
 	menu_bar_render(&menu_bar, ctx);
 
 	gfx_clear_clip(ctx);
-	gfx_add_clip(ctx, decor_left_width, decor_top_height + MENU_BAR_HEIGHT, ctx->width - decor_width(), ctx->height - MENU_BAR_HEIGHT - decor_height());
-	draw_sprite(ctx, contents_sprite, decor_left_width, decor_top_height + MENU_BAR_HEIGHT);
+	gfx_add_clip(ctx, bounds.left_width, bounds.top_height + MENU_BAR_HEIGHT, ctx->width - bounds.width, ctx->height - MENU_BAR_HEIGHT - bounds.height);
+	draw_sprite(ctx, contents_sprite, bounds.left_width, bounds.top_height + MENU_BAR_HEIGHT);
 	gfx_clear_clip(ctx);
 	gfx_add_clip(ctx, 0, 0, ctx->width, ctx->height);
 

+ 29 - 1
apps/julia.c

@@ -29,6 +29,14 @@ static yutani_t * yctx;
 static yutani_window_t * window = NULL;
 static gfx_context_t * ctx = NULL;
 
+static int decor_left_width = 0;
+static int decor_top_height = 0;
+static int decor_right_width = 0;
+static int decor_bottom_height = 0;
+static int decor_width = 0;
+static int decor_height = 0;
+
+
 /* Julia fractals elements */
 float conx = -0.74;  /* real part of c */
 float cony = 0.1;    /* imag part of c */
@@ -161,6 +169,16 @@ void resize_finish(int w, int h) {
 	yutani_window_resize_accept(yctx, window, w, h);
 	reinit_graphics_yutani(ctx, window);
 
+	struct decor_bounds bounds;
+	decor_get_bounds(window, &bounds);
+
+	decor_left_width = bounds.left_width;
+	decor_top_height = bounds.top_height;
+	decor_right_width = bounds.right_width;
+	decor_bottom_height = bounds.bottom_height;
+	decor_width = bounds.width;
+	decor_height = bounds.height;
+
 	width  = w - decor_left_width - decor_right_width;
 	height = h - decor_top_height - decor_bottom_height;
 
@@ -240,7 +258,17 @@ int main(int argc, char * argv[]) {
 	}
 	init_decorations();
 
-	window = yutani_window_create(yctx, width + decor_width(), height + decor_height());
+	struct decor_bounds bounds;
+	decor_get_bounds(NULL, &bounds);
+
+	decor_left_width = bounds.left_width;
+	decor_top_height = bounds.top_height;
+	decor_right_width = bounds.right_width;
+	decor_bottom_height = bounds.bottom_height;
+	decor_width = bounds.width;
+	decor_height = bounds.height;
+
+	window = yutani_window_create(yctx, width + decor_width, height + decor_height);
 	yutani_window_move(yctx, window, left, top);
 
 	yutani_window_advertise_icon(yctx, window, "Julia Fractals", "julia");

+ 16 - 5
apps/plasma.c

@@ -93,8 +93,13 @@ void resize_finish(int w, int h) {
 	yutani_window_resize_accept(yctx, wina, w, h);
 	reinit_graphics_yutani(ctx, wina);
 
-	win_width  = w - decor_width();
-	win_height = h - decor_height();
+	struct decor_bounds bounds;
+	decor_get_bounds(wina, &bounds);
+
+	win_width  = w - bounds.width;
+	win_height = h - bounds.height;
+	off_x = bounds.left_width;
+	off_y = bounds.top_height;
 
 	yutani_window_resize_done(yctx, wina);
 }
@@ -111,13 +116,19 @@ int main (int argc, char ** argv) {
 
 	init_decorations();
 
-	off_x = decor_left_width;
-	off_y = decor_top_height;
+	struct decor_bounds bounds;
+	decor_get_bounds(NULL, &bounds);
 
 	/* Do something with a window */
-	wina = yutani_window_create(yctx, win_width + decor_width(), win_height + decor_height());
+	wina = yutani_window_create(yctx, win_width + bounds.width, win_height + bounds.height);
 	yutani_window_move(yctx, wina, 300, 300);
 
+	decor_get_bounds(wina, &bounds);
+	off_x = bounds.left_width;
+	off_y = bounds.top_height;
+	win_width  = wina->width - bounds.width;
+	win_height = wina->height - bounds.height;
+
 	ctx = init_graphics_yutani_double_buffer(wina);
 
 	draw_fill(ctx, rgb(0,0,0));

+ 9 - 3
apps/sdf-demo.c

@@ -50,8 +50,11 @@ void resize_finish(int w, int h) {
 	yutani_window_resize_accept(yctx, window, w, h);
 	reinit_graphics_yutani(ctx, window);
 
-	width  = w - decor_left_width - decor_right_width;
-	height = h - decor_top_height - decor_bottom_height;
+	struct decor_bounds bounds;
+	decor_get_bounds(window, &bounds);
+
+	width  = w - bounds.left_width - bounds.right_width;
+	height = h - bounds.top_height - bounds.bottom_height;
 
 	redraw();
 
@@ -69,7 +72,10 @@ int main(int argc, char * argv[]) {
 	}
 	init_decorations();
 
-	window = yutani_window_create(yctx, width + decor_width(), height + decor_height());
+	struct decor_bounds bounds;
+	decor_get_bounds(NULL, &bounds);
+
+	window = yutani_window_create(yctx, width + bounds.width, height + bounds.height);
 	yutani_window_move(yctx, window, left, top);
 
 	yutani_window_advertise_icon(yctx, window, "SDF Demo", "sdf");

+ 33 - 10
apps/terminal.c

@@ -149,6 +149,13 @@ static void term_clear();
 static void reinit();
 static void term_redraw_cursor();
 
+static int decor_left_width = 0;
+static int decor_top_height = 0;
+static int decor_right_width = 0;
+static int decor_bottom_height = 0;
+static int decor_width = 0;
+static int decor_height = 0;
+
 struct scrollback_row {
 	unsigned short width;
 	term_cell_t cells[];
@@ -1438,8 +1445,8 @@ static void key_event(int ret, key_event_t * event) {
 				/* Toggle decorations */
 				if (!_fullscreen) {
 					_no_frame = !_no_frame;
-					window_width = window->width - decor_width() * (!_no_frame);
-					window_height = window->height - (decor_height() + menu_bar_height) * (!_no_frame);
+					window_width = window->width - decor_width * (!_no_frame);
+					window_height = window->height - (decor_height + menu_bar_height) * (!_no_frame);
 					reinit(1);
 				}
 				break;
@@ -1663,6 +1670,18 @@ static void reinit(int send_sig) {
 	}
 }
 
+static void update_bounds(void) {
+	struct decor_bounds bounds;
+	decor_get_bounds(window, &bounds);
+
+	decor_left_width = bounds.left_width;
+	decor_top_height = bounds.top_height;
+	decor_right_width = bounds.right_width;
+	decor_bottom_height = bounds.bottom_height;
+	decor_width = bounds.width;
+	decor_height = bounds.height;
+}
+
 /* Handle window resize event. */
 static void resize_finish(int width, int height) {
 	static int resize_attempts = 0;
@@ -1672,8 +1691,10 @@ static void resize_finish(int width, int height) {
 
 	/* Calculate window size */
 	if (!_no_frame) {
-		extra_x = decor_width();
-		extra_y = decor_height() + menu_bar_height;
+		update_bounds();
+
+		extra_x = decor_width;
+		extra_y = decor_height + menu_bar_height;
 	}
 
 	int t_window_width  = width  - extra_x;
@@ -1815,8 +1836,8 @@ static void * handle_incoming(void) {
 
 					if (me->new_x < 0 || me->new_y < 0) break;
 					if (!_no_frame) {
-						if (me->new_x >= (int)window_width + (int)decor_width()) break;
-						if (me->new_y >= (int)window_height + (int)decor_height()) break;
+						if (me->new_x >= (int)window_width + (int)decor_width) break;
+						if (me->new_y >= (int)window_height + (int)decor_height) break;
 						if (me->new_y < (int)decor_top_height+menu_bar_height) break;
 						if (me->new_y >= (int)(window_height + decor_top_height+menu_bar_height)) break;
 						if (me->new_x < (int)decor_left_width) break;
@@ -1948,8 +1969,8 @@ static struct MenuEntry * _menu_toggle_borders_bar = NULL;
 
 static void _menu_action_hide_borders(struct MenuEntry * self) {
 	_no_frame = !(_no_frame);
-	window_width = window->width - decor_width() * (!_no_frame);
-	window_height = window->height - (decor_height() + menu_bar_height) * (!_no_frame);
+	window_width = window->width - decor_width * (!_no_frame);
+	window_height = window->height - (decor_height + menu_bar_height) * (!_no_frame);
 	menu_update_title(_menu_toggle_borders_context, _no_frame ? "Show borders" : "Hide borders");
 	menu_update_title(_menu_toggle_borders_bar, _no_frame ? "Show borders" : "Hide borders");
 	reinit(1);
@@ -2078,8 +2099,10 @@ int main(int argc, char ** argv) {
 		window = yutani_window_create(yctx, window_width, window_height);
 	} else {
 		init_decorations();
-		window = yutani_window_create(yctx, window_width + decor_left_width + decor_right_width, window_height + decor_top_height+menu_bar_height + decor_bottom_height);
-
+		struct decor_bounds bounds;
+		decor_get_bounds(NULL, &bounds);
+		window = yutani_window_create(yctx, window_width + bounds.width, window_height + bounds.height + menu_bar_height);
+		update_bounds();
 	}
 
 	if (_fullscreen) {

+ 15 - 8
base/usr/include/toaru/decorations.h

@@ -9,11 +9,6 @@
 #include <toaru/graphics.h>
 #include <toaru/yutani.h>
 
-extern uint32_t decor_top_height;
-extern uint32_t decor_bottom_height;
-extern uint32_t decor_left_width;
-extern uint32_t decor_right_width;
-
 /*
  * Render decorations to a window. A buffer pointer is
  * provided so that you may render in double-buffered mode.
@@ -24,20 +19,32 @@ extern uint32_t decor_right_width;
 extern void render_decorations(yutani_window_t * window, gfx_context_t * ctx, char * title);
 extern void render_decorations_inactive(yutani_window_t * window, gfx_context_t * ctx, char * title);
 
+/**
+ * Decoration boundaries
+ */
+struct decor_bounds {
+	int top_height;
+	int bottom_height;
+	int left_width;
+	int right_width;
+
+	/* Convenience */
+	int width;
+	int height;
+};
+
 /*
  * Used by decoration libraries to set callbacks
  */
 extern void (*decor_render_decorations)(yutani_window_t *, gfx_context_t *, char *, int);
 extern int  (*decor_check_button_press)(yutani_window_t *, int x, int y);
+extern int  (*decor_get_bounds)(yutani_window_t *, struct decor_bounds *);
 
 /*
  * Run me once to set things up
  */
 extern void init_decorations();
 
-extern uint32_t decor_width();
-extern uint32_t decor_height();
-
 extern int decor_handle_event(yutani_t * yctx, yutani_msg_t * m);
 
 /* Callbacks for handle_event */

+ 28 - 10
lib/decor-fancy.c

@@ -37,26 +37,48 @@ static void init_sprite(int id, char * path) {
 	sprites[id]->alpha = ALPHA_EMBEDDED;
 }
 
+static int get_bounds_fancy(yutani_window_t * window, struct decor_bounds * bounds) {
+	if (window == NULL) {
+		bounds->top_height = 33;
+		bounds->bottom_height = 6;
+		bounds->left_width = 6;
+		bounds->right_width = 6;
+	} else {
+		/* TODO: Window type */
+		bounds->top_height = 33;
+		bounds->bottom_height = 6;
+		bounds->left_width = 6;
+		bounds->right_width = 6;
+	}
+
+	bounds->width = bounds->left_width + bounds->right_width;
+	bounds->height = bounds->top_height + bounds->bottom_height;
+	return 0;
+}
+
 static void render_decorations_fancy(yutani_window_t * window, gfx_context_t * ctx, char * title, int decors_active) {
 	int width = window->width;
 	int height = window->height;
 
-	for (int j = 0; j < (int)decor_top_height; ++j) {
+	struct decor_bounds bounds;
+	get_bounds_fancy(window, &bounds);
+
+	for (int j = 0; j < (int)bounds.top_height; ++j) {
 		for (int i = 0; i < width; ++i) {
 			GFX(ctx,i,j) = 0;
 		}
 	}
 
-	for (int j = (int)decor_top_height; j < height - (int)decor_bottom_height; ++j) {
-		for (int i = 0; i < (int)decor_left_width; ++i) {
+	for (int j = (int)bounds.top_height; j < height - (int)bounds.bottom_height; ++j) {
+		for (int i = 0; i < (int)bounds.left_width; ++i) {
 			GFX(ctx,i,j) = 0;
 		}
-		for (int i = width - (int)decor_right_width; i < width; ++i) {
+		for (int i = width - (int)bounds.right_width; i < width; ++i) {
 			GFX(ctx,i,j) = 0;
 		}
 	}
 
-	for (int j = height - (int)decor_bottom_height; j < height; ++j) {
+	for (int j = height - (int)bounds.bottom_height; j < height; ++j) {
 		for (int i = 0; i < width; ++i) {
 			GFX(ctx,i,j) = 0;
 		}
@@ -148,12 +170,8 @@ void decor_init() {
 	init_sprite(INACTIVE + 8, TTK_FANCY_PATH "inactive/button-close.bmp");
 	init_sprite(INACTIVE + 9, TTK_FANCY_PATH "inactive/button-maximize.bmp");
 
-	decor_top_height     = 33;
-	decor_bottom_height  = 6;
-	decor_left_width     = 6;
-	decor_right_width    = 6;
-
 	decor_render_decorations = render_decorations_fancy;
 	decor_check_button_press = check_button_press_fancy;
+	decor_get_bounds = get_bounds_fancy;
 }
 

+ 32 - 27
lib/decorations.c

@@ -16,11 +16,6 @@
 #include <toaru/sdf.h>
 #include <toaru/menu.h>
 
-uint32_t decor_top_height     = 33;
-uint32_t decor_bottom_height  = 6;
-uint32_t decor_left_width     = 6;
-uint32_t decor_right_width    = 6;
-
 #define TEXT_OFFSET_X 10
 #define TEXT_OFFSET_Y 3
 
@@ -31,6 +26,7 @@ uint32_t decor_right_width    = 6;
 
 void (*decor_render_decorations)(yutani_window_t *, gfx_context_t *, char *, int) = NULL;
 int  (*decor_check_button_press)(yutani_window_t *, int x, int y) = NULL;
+int  (*decor_get_bounds)(yutani_window_t *, struct decor_bounds *) = NULL;
 
 static void (*callback_close)(yutani_window_t *) = NULL;
 static void (*callback_resize)(yutani_window_t *) = NULL;
@@ -54,7 +50,7 @@ static void render_decorations_simple(yutani_window_t * window, gfx_context_t *
 		GFX(ctx, window->width - 1, i) = color;
 	}
 
-	for (int i = 1; i < (int)decor_top_height; ++i) {
+	for (int i = 1; i < (int)24; ++i) {
 		for (int j = 1; j < (int)window->width - 1; ++j) {
 			GFX(ctx, j, i) = color;
 		}
@@ -70,7 +66,7 @@ static void render_decorations_simple(yutani_window_t * window, gfx_context_t *
 
 	for (uint32_t i = 0; i < window->width; ++i) {
 		GFX(ctx, i, 0) = color;
-		GFX(ctx, i, decor_top_height - 1) = color;
+		GFX(ctx, i, 24 - 1) = color;
 		GFX(ctx, i, window->height - 1) = color;
 	}
 }
@@ -83,14 +79,23 @@ static int check_button_press_simple(yutani_window_t * window, int x, int y) {
 	return 0;
 }
 
-static void initialize_simple() {
-	decor_top_height     = 24;
-	decor_bottom_height  = 1;
-	decor_left_width     = 1;
-	decor_right_width    = 1;
+static int get_bounds_simple(yutani_window_t * window, struct decor_bounds * bounds) {
+	/* Does not change with window state */
+	bounds->top_height = 24;
+	bounds->bottom_height = 1;
+	bounds->left_width = 1;
+	bounds->right_width = 1;
 
+	bounds->width = bounds->left_width + bounds->right_width;
+	bounds->height = bounds->top_height + bounds->bottom_height;
+
+	return 0;
+}
+
+static void initialize_simple() {
 	decor_render_decorations = render_decorations_simple;
 	decor_check_button_press = check_button_press_simple;
+	decor_get_bounds         = get_bounds_simple;
 }
 
 void render_decorations(yutani_window_t * window, gfx_context_t * ctx, char * title) {
@@ -190,14 +195,6 @@ _theme_error:
 	}
 }
 
-uint32_t decor_width() {
-	return decor_left_width + decor_right_width;
-}
-
-uint32_t decor_height() {
-	return decor_top_height + decor_bottom_height;
-}
-
 void decor_set_close_callback(void (*callback)(yutani_window_t *)) {
 	callback_close = callback;
 }
@@ -211,18 +208,24 @@ void decor_set_maximize_callback(void (*callback)(yutani_window_t *)) {
 }
 
 static int within_decors(yutani_window_t * window, int x, int y) {
-	if ((x <= (int)decor_left_width || x >= (int)window->width - (int)decor_right_width) && (x > 0 && x < (int)window->width)) return 1;
-	if ((y <= (int)decor_top_height || y >= (int)window->height - (int)decor_bottom_height) && (y > 0 && y < (int)window->height)) return 1;
+	struct decor_bounds bounds;
+	decor_get_bounds(window, &bounds);
+
+	if ((x <= (int)bounds.left_width || x >= (int)window->width - (int)bounds.right_width) && (x > 0 && x < (int)window->width)) return 1;
+	if ((y <= (int)bounds.top_height || y >= (int)window->height - (int)bounds.bottom_height) && (y > 0 && y < (int)window->height)) return 1;
 	return 0;
 }
 
-#define LEFT_SIDE (me->new_x <= (int)decor_left_width)
-#define RIGHT_SIDE (me->new_x >= (int)window->width - (int)decor_right_width)
-#define TOP_SIDE (me->new_y <= (int)decor_top_height)
-#define BOTTOM_SIDE (me->new_y >= (int)window->height - (int)decor_bottom_height)
+#define LEFT_SIDE (me->new_x <= (int)bounds.left_width)
+#define RIGHT_SIDE (me->new_x >= (int)window->width - (int)bounds.right_width)
+#define TOP_SIDE (me->new_y <= (int)bounds.top_height)
+#define BOTTOM_SIDE (me->new_y >= (int)window->height - (int)bounds.bottom_height)
 
 static yutani_scale_direction_t check_resize_direction(struct yutani_msg_window_mouse_event * me, yutani_window_t * window) {
+	struct decor_bounds bounds;
+	decor_get_bounds(window, &bounds);
 	yutani_scale_direction_t resize_direction = SCALE_NONE;
+
 	if (LEFT_SIDE && !TOP_SIDE && !BOTTOM_SIDE) {
 		resize_direction = SCALE_LEFT;
 	} else if (RIGHT_SIDE && !TOP_SIDE && !BOTTOM_SIDE) {
@@ -252,6 +255,8 @@ int decor_handle_event(yutani_t * yctx, yutani_msg_t * m) {
 				{
 					struct yutani_msg_window_mouse_event * me = (void*)m->data;
 					yutani_window_t * window = hashmap_get(yctx->windows, (void*)me->wid);
+					struct decor_bounds bounds;
+					decor_get_bounds(window, &bounds);
 					if (!window) return 0;
 					if (!(window->decorator_flags & DECOR_FLAG_DECORATED)) return 0;
 					if (within_decors(window, me->new_x, me->new_y)) {
@@ -265,7 +270,7 @@ int decor_handle_event(yutani_t * yctx, yutani_msg_t * m) {
 									yutani_window_resize_start(yctx, window, resize_direction);
 								}
 
-								if (me->new_y < (int)decor_top_height && resize_direction == SCALE_NONE) {
+								if (me->new_y < (int)bounds.top_height && resize_direction == SCALE_NONE) {
 									yutani_window_drag_start(yctx, window);
 								}
 								return DECOR_OTHER;