[PATCH weston v4] toytoolkit: Don't draw shadows for maximized windows.
Scott Moreau
oreaus at gmail.com
Fri Sep 28 01:45:06 PDT 2012
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?
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
More information about the wayland-devel
mailing list