[PATCH weston v4] toytoolkit: Don't draw shadows for maximized windows.

Kristian Høgsberg hoegsberg at gmail.com
Wed Oct 10 09:57:58 PDT 2012


On Fri, Sep 28, 2012 at 02:45:06AM -0600, Scott Moreau wrote:
> Add THEME_FRAME_MAXIMIZED flag so the theming system can know not to draw
> shadows for maximized windows. This allows maximized surfaces' content to be
> sized and placed in a more expectable fashion.
> 
> ---
> 
> >On Tue, Aug 07, 2012 at 06:16:14AM -0600, Scott Moreau wrote:
> >> 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.
> >> ---
> >>
> >> v3:
> >>
> >> * Applied the same logic to both instances of theme_get_location() so the resize
> >> cursors show properly for maximized windows
> >> * Fixed window-manager.c flags
> >> * Fixed a small indentation mishap
> >> * Simplified the assignment case in theme_get_location()
> >
> >What we need here is to tell the theme code "draw maximized window
> >decorations" not a "no shadow" flag.
> >
> >Kristian
> 
> I agree, this makes more sense.
> 
> One thing I was thinking about is what to do in the case where a
> window has a maximum (or minimum?) size that is inconsistent with
> the maximized area determined by the compositor. For instance,
> weston-terminal snaps to character cell increments and may not
> always agree with the maximized size. Should the toolkit go ahead
> and resize the decorations to the mazimized size always, centering
> the client content if it doesn't match and just solid color the rest
> (black)? Should a client be expected to resize it's content to the
> lesser maximized diminsion (width or height) if it wants to maintain
> a certain aspect ratio? For instance, gears rendered width and
> height are interdependent. I guess I'm wondering what should be
> responsible for handling this, the toolkit or client.  Another
> consideration is, do we want to handle fullscreen windows in a
> similar way?

That looks good, applied.  As for resizing constraints, the
application should just disable those when maximized or fullscreen and
fill the extra space somehow.  I fixed terminal to not adjust the resize
in case of maximized as well.

Kristian

> v4:
> 
> * Changed THEME_FRAME_NO_SHADOW to THEME_FRAME_MAXIMIZED.
> * Removed the opacity flag value change.
> 
> 
>  clients/window.c              | 75 +++++++++++++++++++++++++++++--------------
>  shared/cairo-util.c           | 51 +++++++++++++++++------------
>  shared/cairo-util.h           |  7 ++--
>  src/xwayland/window-manager.c |  4 +--
>  4 files changed, 88 insertions(+), 49 deletions(-)
> 
> diff --git a/clients/window.c b/clients/window.c
> index f3b61de..41f9d2c 100644
> --- a/clients/window.c
> +++ b/clients/window.c
> @@ -1381,9 +1381,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 = 1;
> +		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 = 0;
> +		break;
> +	default:
>  		decoration_width = (t->width + t->margin) * 2;
>  		decoration_height = t->width +
>  			t->titlebar_height + t->margin * 2;
> @@ -1397,18 +1425,7 @@ frame_resize_handler(struct widget *widget,
>  
>  		wl_list_for_each(button, &frame->buttons_list, link)
>  			button->widget->opaque = 0;
> -	} 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 = 1;
> +		break;
>  	}
>  
>  	widget_set_allocation(child, allocation.x, allocation.y,
> @@ -1423,13 +1440,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);
> +			      shadow_margin, shadow_margin,
> +			      width - 2 * shadow_margin,
> +			      height - 2 * shadow_margin);
>  	}
>  
>  	widget_set_allocation(widget, 0, 0, width, height);
> @@ -1444,9 +1463,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);
> @@ -1673,6 +1692,8 @@ frame_redraw_handler(struct widget *widget, void *data)
>  
>  	if (window->focus_count)
>  		flags |= THEME_FRAME_ACTIVE;
> +	if (window->type == TYPE_MAXIMIZED)
> +		flags |= THEME_FRAME_MAXIMIZED;
>  	theme_render_frame(t, cr, widget->allocation.width,
>  			   widget->allocation.height, window->title, flags);
>  
> @@ -1683,11 +1704,14 @@ static int
>  frame_get_pointer_image_for_location(struct frame *frame, struct input *input)
>  {
>  	struct theme *t = frame->widget->window->display->theme;
> +	struct window *window = frame->widget->window;
>  	int location;
>  
>  	location = theme_get_location(t, input->sx, input->sy,
>  				      frame->widget->allocation.width,
> -				      frame->widget->allocation.height);
> +				      frame->widget->allocation.height,
> +				      window->type == TYPE_MAXIMIZED ?
> +				      THEME_FRAME_MAXIMIZED : 0);
>  
>  	switch (location) {
>  	case THEME_LOCATION_RESIZING_TOP:
> @@ -1794,7 +1818,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_MAXIMIZED : 0);
>  
>  	if (window->display->shell && button == BTN_LEFT &&
>  	    state == WL_POINTER_BUTTON_STATE_PRESSED) {
> @@ -1884,11 +1910,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..360099e 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_MAXIMIZED)
> +		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,33 @@ 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;
> +
> +	margin = (flags & THEME_FRAME_MAXIMIZED) ? 0 : 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 +474,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..3a760a4 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_MAXIMIZED,
> +};
>  
>  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 65eb11a..063460f 100644
> --- a/src/xwayland/window-manager.c
> +++ b/src/xwayland/window-manager.c
> @@ -1009,7 +1009,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, 0);
>  
>  	switch (location) {
>  		case THEME_LOCATION_RESIZING_TOP:
> @@ -1076,7 +1076,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.4
> 
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel


More information about the wayland-devel mailing list