[PATCH 2/2 weston v2] toytoolkit: Don't draw shadows for maximized windows.

Scott Moreau oreaus at gmail.com
Tue Aug 7 04:06:14 PDT 2012


This effectively fixes a bug where maximized windows appear to not maximize fully
bacause of the shadow margin. Instead, we maximize the window to the input region.
---

Hi Ander, thanks for your review. You are right, changing theme data directly
is wrong. In this v2 patch, it's fixed so the user can set THEME_FRAME_NO_SHADOW
to have a frame without a shadow.

v2: Remove hack of changing theme data directly and introduce a new flag
THEME_FRAME_NO_SHADOW to implement this more properly.

---
 clients/window.c              | 74 ++++++++++++++++++++++++++++---------------
 shared/cairo-util.c           | 54 +++++++++++++++++++------------
 shared/cairo-util.h           |  7 ++--
 src/xwayland/window-manager.c |  4 +--
 4 files changed, 89 insertions(+), 50 deletions(-)

diff --git a/clients/window.c b/clients/window.c
index 30a6167..483289e 100644
--- a/clients/window.c
+++ b/clients/window.c
@@ -1244,9 +1244,37 @@ frame_resize_handler(struct widget *widget,
 	struct theme *t = display->theme;
 	int x_l, x_r, y, w, h;
 	int decoration_width, decoration_height;
-	int opaque_margin;
+	int opaque_margin, shadow_margin;
 
-	if (widget->window->type != TYPE_FULLSCREEN) {
+	switch (widget->window->type) {
+	case TYPE_FULLSCREEN:
+		decoration_width = 0;
+		decoration_height = 0;
+
+		allocation.x = 0;
+		allocation.y = 0;
+		allocation.width = width;
+		allocation.height = height;
+		opaque_margin = 0;
+
+		wl_list_for_each(button, &frame->buttons_list, link)
+			button->widget->opaque = 0;
+		break;
+	case TYPE_MAXIMIZED:
+		decoration_width = t->width * 2;
+		decoration_height = t->width + t->titlebar_height;
+
+		allocation.x = t->width;
+		allocation.y = t->titlebar_height;
+		allocation.width = width - decoration_width;
+		allocation.height = height - decoration_height;
+
+		opaque_margin = 0;
+
+		wl_list_for_each(button, &frame->buttons_list, link)
+			button->widget->opaque = 1;
+		break;
+	default:
 		decoration_width = (t->width + t->margin) * 2;
 		decoration_height = t->width +
 			t->titlebar_height + t->margin * 2;
@@ -1260,18 +1288,7 @@ frame_resize_handler(struct widget *widget,
 
 		wl_list_for_each(button, &frame->buttons_list, link)
 			button->widget->opaque = 1;
-	} else {
-		decoration_width = 0;
-		decoration_height = 0;
-
-		allocation.x = 0;
-		allocation.y = 0;
-		allocation.width = width;
-		allocation.height = height;
-		opaque_margin = 0;
-
-		wl_list_for_each(button, &frame->buttons_list, link)
-			button->widget->opaque = 0;
+		break;
 	}
 
 	widget_set_allocation(child, allocation.x, allocation.y,
@@ -1286,13 +1303,15 @@ frame_resize_handler(struct widget *widget,
 	width = child->allocation.width + decoration_width;
 	height = child->allocation.height + decoration_height;
 
+	shadow_margin = widget->window->type == TYPE_MAXIMIZED ? 0 : t->margin;
+
 	if (widget->window->type != TYPE_FULLSCREEN) {
 		widget->window->input_region =
 			wl_compositor_create_region(display->compositor);
-		wl_region_add(widget->window->input_region,
-			      t->margin, t->margin,
-			      width - 2 * t->margin,
-			      height - 2 * t->margin);
+			wl_region_add(widget->window->input_region,
+				      shadow_margin, shadow_margin,
+				      width - 2 * shadow_margin,
+				      height - 2 * shadow_margin);
 	}
 
 	widget_set_allocation(widget, 0, 0, width, height);
@@ -1307,9 +1326,9 @@ frame_resize_handler(struct widget *widget,
 	}
 
 	/* frame internal buttons */
-	x_r = frame->widget->allocation.width - t->width - t->margin;
-	x_l = t->width + t->margin;
-	y = t->width + t->margin;
+	x_r = frame->widget->allocation.width - t->width - shadow_margin;
+	x_l = t->width + shadow_margin;
+	y = t->width + shadow_margin;
 	wl_list_for_each(button, &frame->buttons_list, link) {
 		const int button_padding = 4;
 		w = cairo_image_surface_get_width(button->icon);
@@ -1504,6 +1523,8 @@ frame_redraw_handler(struct widget *widget, void *data)
 
 	if (window->keyboard_device)
 		flags |= THEME_FRAME_ACTIVE;
+	if (window->type == TYPE_MAXIMIZED)
+		flags |= THEME_FRAME_NO_SHADOW;
 	theme_render_frame(t, cr, widget->allocation.width,
 			   widget->allocation.height, window->title, flags);
 
@@ -1518,7 +1539,7 @@ frame_get_pointer_image_for_location(struct frame *frame, struct input *input)
 
 	location = theme_get_location(t, input->sx, input->sy,
 				      frame->widget->allocation.width,
-				      frame->widget->allocation.height);
+				      frame->widget->allocation.height, 0);
 
 	switch (location) {
 	case THEME_LOCATION_RESIZING_TOP:
@@ -1610,7 +1631,9 @@ frame_button_handler(struct widget *widget,
 
 	location = theme_get_location(display->theme, input->sx, input->sy,
 				      frame->widget->allocation.width,
-				      frame->widget->allocation.height);
+				      frame->widget->allocation.height,
+				      window->type == TYPE_MAXIMIZED ?
+				      THEME_FRAME_NO_SHADOW : 0);
 
 	if (window->display->shell && button == BTN_LEFT &&
 	    state == WL_POINTER_BUTTON_STATE_PRESSED) {
@@ -1700,11 +1723,12 @@ frame_set_child_size(struct widget *widget, int child_width, int child_height)
 	struct theme *t = display->theme;
 	int decoration_width, decoration_height;
 	int width, height;
+	int margin = widget->window->type == TYPE_MAXIMIZED ? 0 : t->margin;
 
 	if (widget->window->type != TYPE_FULLSCREEN) {
-		decoration_width = (t->width + t->margin) * 2;
+		decoration_width = (t->width + margin) * 2;
 		decoration_height = t->width +
-			t->titlebar_height + t->margin * 2;
+			t->titlebar_height + margin * 2;
 
 		width = child_width + decoration_width;
 		height = child_height + decoration_height;
diff --git a/shared/cairo-util.c b/shared/cairo-util.c
index c64ace2..1f1bf36 100644
--- a/shared/cairo-util.c
+++ b/shared/cairo-util.c
@@ -373,23 +373,28 @@ theme_destroy(struct theme *t)
 }
 
 void
-theme_render_frame(struct theme *t, 
+theme_render_frame(struct theme *t,
 		   cairo_t *cr, int width, int height,
 		   const char *title, uint32_t flags)
 {
 	cairo_text_extents_t extents;
 	cairo_font_extents_t font_extents;
 	cairo_surface_t *source;
-	int x, y;
+	int x, y, margin;
 
 	cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
 	cairo_set_source_rgba(cr, 0, 0, 0, 0);
 	cairo_paint(cr);
 
-	cairo_set_source_rgba(cr, 0, 0, 0, 0.45);
-	tile_mask(cr, t->shadow,
-		  2, 2, width + 8, height + 8,
-		  64, 64);
+	if (flags & THEME_FRAME_NO_SHADOW)
+		margin = 0;
+	else {
+		cairo_set_source_rgba(cr, 0, 0, 0, 0.45);
+		tile_mask(cr, t->shadow,
+			  2, 2, width + 8, height + 8,
+			  64, 64);
+		margin = t->margin;
+	}
 
 	if (flags & THEME_FRAME_ACTIVE)
 		source = t->active_frame;
@@ -397,12 +402,12 @@ theme_render_frame(struct theme *t,
 		source = t->inactive_frame;
 
 	tile_source(cr, source,
-		    t->margin, t->margin,
-		    width - t->margin * 2, height - t->margin * 2,
+		    margin, margin,
+		    width - margin * 2, height - margin * 2,
 		    t->width, t->titlebar_height);
 
-	cairo_rectangle (cr, t->margin + t->width, t->margin,
-			 width - (t->margin + t->width) * 2,
+	cairo_rectangle (cr, margin + t->width, margin,
+			 width - (margin + t->width) * 2,
 			 t->titlebar_height - t->width);
 	cairo_clip(cr);
 
@@ -414,7 +419,7 @@ theme_render_frame(struct theme *t,
 	cairo_text_extents(cr, title, &extents);
 	cairo_font_extents (cr, &font_extents);
 	x = (width - extents.width) / 2;
-	y = t->margin +
+	y = margin +
 		(t->titlebar_height -
 		 font_extents.ascent - font_extents.descent) / 2 +
 		font_extents.ascent;
@@ -434,29 +439,36 @@ theme_render_frame(struct theme *t,
 }
 
 enum theme_location
-theme_get_location(struct theme *t, int x, int y, int width, int height)
+theme_get_location(struct theme *t, int x, int y,
+				int width, int height, int flags)
 {
 	int vlocation, hlocation, location;
 	const int grip_size = 8;
+	int margin;
+
+	if (flags & THEME_FRAME_NO_SHADOW)
+		margin = 0;
+	else
+		margin = t->margin;
 
-	if (x < t->margin)
+	if (x < margin)
 		hlocation = THEME_LOCATION_EXTERIOR;
-	else if (t->margin <= x && x < t->margin + grip_size)
+	else if (margin <= x && x < margin + grip_size)
 		hlocation = THEME_LOCATION_RESIZING_LEFT;
-	else if (x < width - t->margin - grip_size)
+	else if (x < width - margin - grip_size)
 		hlocation = THEME_LOCATION_INTERIOR;
-	else if (x < width - t->margin)
+	else if (x < width - margin)
 		hlocation = THEME_LOCATION_RESIZING_RIGHT;
 	else
 		hlocation = THEME_LOCATION_EXTERIOR;
 
-	if (y < t->margin)
+	if (y < margin)
 		vlocation = THEME_LOCATION_EXTERIOR;
-	else if (t->margin <= y && y < t->margin + grip_size)
+	else if (margin <= y && y < margin + grip_size)
 		vlocation = THEME_LOCATION_RESIZING_TOP;
-	else if (y < height - t->margin - grip_size)
+	else if (y < height - margin - grip_size)
 		vlocation = THEME_LOCATION_INTERIOR;
-	else if (y < height - t->margin)
+	else if (y < height - margin)
 		vlocation = THEME_LOCATION_RESIZING_BOTTOM;
 	else
 		vlocation = THEME_LOCATION_EXTERIOR;
@@ -465,7 +477,7 @@ theme_get_location(struct theme *t, int x, int y, int width, int height)
 	if (location & THEME_LOCATION_EXTERIOR)
 		location = THEME_LOCATION_EXTERIOR;
 	if (location == THEME_LOCATION_INTERIOR &&
-	    y < t->margin + t->titlebar_height)
+	    y < margin + t->titlebar_height)
 		location = THEME_LOCATION_TITLEBAR;
 	else if (location == THEME_LOCATION_INTERIOR)
 		location = THEME_LOCATION_CLIENT_AREA;
diff --git a/shared/cairo-util.h b/shared/cairo-util.h
index 2fec389..16d7fb4 100644
--- a/shared/cairo-util.h
+++ b/shared/cairo-util.h
@@ -58,7 +58,10 @@ theme_create(void);
 void
 theme_destroy(struct theme *t);
 
-#define THEME_FRAME_ACTIVE 1
+enum {
+	THEME_FRAME_ACTIVE = 1,
+	THEME_FRAME_NO_SHADOW,
+};
 
 void
 theme_render_frame(struct theme *t, 
@@ -82,6 +85,6 @@ enum theme_location {
 };
 
 enum theme_location
-theme_get_location(struct theme *t, int x, int y, int width, int height);
+theme_get_location(struct theme *t, int x, int y, int width, int height, int flags);
 
 #endif
diff --git a/src/xwayland/window-manager.c b/src/xwayland/window-manager.c
index d724d47..3fbfa0c 100644
--- a/src/xwayland/window-manager.c
+++ b/src/xwayland/window-manager.c
@@ -998,7 +998,7 @@ weston_wm_destroy_cursors(struct weston_wm *wm)
 static int
 get_cursor_for_location(struct theme *t, int width, int height, int x, int y)
 {
-	int location = theme_get_location(t, x, y, width, height);
+	int location = theme_get_location(t, x, y, width, height, t->margin);
 
 	switch (location) {
 		case THEME_LOCATION_RESIZING_TOP:
@@ -1064,7 +1064,7 @@ weston_wm_handle_button(struct weston_wm *wm, xcb_generic_event_t *event)
 		location = theme_get_location(t,
 					      button->event_x,
 					      button->event_y,
-					      width, height);
+					      width, height, 0);
 
 		switch (location) {
 		case THEME_LOCATION_TITLEBAR:
-- 
1.7.11.2



More information about the wayland-devel mailing list