[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