diff options
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | button.c | 22 | ||||
-rw-r--r-- | button.h | 3 | ||||
-rw-r--r-- | decorate-core.c | 3 | ||||
-rw-r--r-- | decorate-render.c | 3 | ||||
-rw-r--r-- | frame.c | 334 | ||||
-rw-r--r-- | frame.h | 19 | ||||
-rw-r--r-- | gwm.c | 216 | ||||
-rw-r--r-- | gwm.h | 18 | ||||
-rw-r--r-- | managed.c | 38 |
10 files changed, 387 insertions, 279 deletions
@@ -1,3 +1,13 @@ +2009-08-31 Gary Wong <gtw@gnu.org> + + * button.c (button_size, button_xb): New functions. All references + to former constants updated. + * frame.c (frame_t, frame_b, frame_l, frame_r, frame_xb): New + functions. All references to former constants updated. + (translate_child_to_frame, translate_frame_to_child): Moved + from gwm.c. + (apply_size_constraints): Likewise. + 2009-08-30 Gary Wong <gtw@gnu.org> * frame.c (frame_button_release): Ignore the event unless the @@ -23,6 +23,7 @@ #include <config.h> +#include <assert.h> #include <xcb/xcb.h> #include "gwm.h" @@ -30,6 +31,23 @@ #include "button.h" #include "window-table.h" +#define BUTTON_SIZE 12 /* size of buttons in title bar; excludes X border */ +#define BUTTON_X_BORDER 1 + +extern int button_size( struct gwm_window *window, int include_x_border ) { + + assert( window->type == WINDOW_BUTTON ); + + return BUTTON_SIZE + ( include_x_border ? BUTTON_X_BORDER << 1 : 0 ); +} + +extern int button_xb( struct gwm_window *window ) { + + assert( window->type == WINDOW_BUTTON ); + + return BUTTON_X_BORDER; +} + static int button_active; static void set_button_active( struct gwm_window *window, int new ) { @@ -44,8 +62,8 @@ static void set_button_active( struct gwm_window *window, int new ) { COL_BUTTON_INACTIVE ]; xcb_change_window_attributes( c, window->w, XCB_CW_BACK_PIXEL, &n ); - queue_window_update( window, 0, 0, FRAME_BUTTON_SIZE, FRAME_BUTTON_SIZE, - FALSE ); + queue_window_update( window, 0, 0, button_size( window, FALSE ), + button_size( window, FALSE ), FALSE ); } static void button_button_press( struct gwm_window *window, @@ -1,6 +1,9 @@ #ifndef BUTTON_H #define BUTTON_H +extern int button_size( struct gwm_window *window, int include_x_border ); +extern int button_xb( struct gwm_window *window ); + extern event_handler button_handlers[]; #endif diff --git a/decorate-core.c b/decorate-core.c index 77b7436..c3c3b73 100644 --- a/decorate-core.c +++ b/decorate-core.c @@ -31,6 +31,7 @@ #include "gwm.h" +#include "button.h" #include "decorate-core.h" #define FONT_SIZE 12 @@ -141,7 +142,7 @@ extern void core_update_window( struct gwm_window *window ) { core_text( window->w, window->screen, window == focus_frame ? COL_TITLE_ACTIVE : COL_TITLE_INACTIVE, - FRAME_BUTTON_SIZE + FRAME_BORDER_WIDTH * 3, + button_size( window->u.frame.button, TRUE ) + 4, FONT_SIZE, name ? name : "(Untitled)" ); } else if( window->type == WINDOW_FEEDBACK ) { char *p, text[ 32 ]; diff --git a/decorate-render.c b/decorate-render.c index 57dfa9b..b30f25a 100644 --- a/decorate-render.c +++ b/decorate-render.c @@ -36,6 +36,7 @@ #include "gwm.h" +#include "button.h" #include "decorate-render.h" enum style_id { @@ -568,7 +569,7 @@ extern void render_update_window( struct gwm_window *window ) { render_text( window->w, window->screen, window == focus_frame ? COL_TITLE_ACTIVE : COL_TITLE_INACTIVE, - FRAME_BUTTON_SIZE + FRAME_BORDER_WIDTH * 3, + button_size( window->u.frame.button, TRUE ) + 4, TITLE_FONT_SIZE, name ? name : "(Untitled)", STYLE_TITLE, &window->update ); } else if( window->type == WINDOW_FEEDBACK ) { @@ -35,6 +35,263 @@ #define EDGE_RESIST 8 +#define FRAME_X_BORDER 1 /* X border added to all four sides of frame */ +#define FRAME_BORDER_WIDTH 2 /* pixels added to left, right and bottom; + includes padding but excludes X border */ +#define FRAME_TITLE_HEIGHT 16 /* pixels added to top; includes title + bar but excludes X border */ + +extern int frame_t( struct gwm_window *window, int include_x_border ) { + + assert( window->type == WINDOW_FRAME ); + + return FRAME_TITLE_HEIGHT + ( include_x_border ? FRAME_X_BORDER : 0 ); +} + +extern int frame_b( struct gwm_window *window, int include_x_border ) { + + assert( window->type == WINDOW_FRAME ); + + return FRAME_BORDER_WIDTH + ( include_x_border ? FRAME_X_BORDER : 0 ); +} + +extern int frame_l( struct gwm_window *window, int include_x_border ) { + + assert( window->type == WINDOW_FRAME ); + + return FRAME_BORDER_WIDTH + ( include_x_border ? FRAME_X_BORDER : 0 ); +} + +extern int frame_r( struct gwm_window *window, int include_x_border ) { + + assert( window->type == WINDOW_FRAME ); + + return FRAME_BORDER_WIDTH + ( include_x_border ? FRAME_X_BORDER : 0 ); +} + +extern int frame_xb( struct gwm_window *window ) { + + assert( window->type == WINDOW_FRAME ); + + return FRAME_X_BORDER; +} + +extern void translate_child_to_frame( struct gwm_window *frame, + int *fx, int *fy, int *fwidth, + int *fheight, int cx, int cy, + int cwidth, int cheight, + int cborder, int win_gravity ) { + + *fwidth = cwidth + frame_l( frame, FALSE ) + frame_r( frame, FALSE ); + *fheight = cheight + frame_t( frame, FALSE ) + frame_b( frame, FALSE ); + + switch( win_gravity ) { + case XCB_GRAVITY_NORTH_WEST: + case XCB_GRAVITY_WEST: + case XCB_GRAVITY_SOUTH_WEST: + default: + *fx = cx; + break; + + case XCB_GRAVITY_NORTH: + case XCB_GRAVITY_CENTER: + case XCB_GRAVITY_SOUTH: + *fx = cx + cborder - ( ( frame_l( frame, TRUE ) + + frame_r( frame, TRUE ) ) >> 1 ); + break; + + case XCB_GRAVITY_NORTH_EAST: + case XCB_GRAVITY_EAST: + case XCB_GRAVITY_SOUTH_EAST: + *fx = cx + ( cborder << 1 ) - frame_l( frame, TRUE ) - + frame_r( frame, TRUE ); + break; + + case XCB_GRAVITY_STATIC: + *fx = cx + cborder - frame_l( frame, TRUE ); + } + + switch( win_gravity ) { + case XCB_GRAVITY_NORTH_WEST: + case XCB_GRAVITY_NORTH: + case XCB_GRAVITY_NORTH_EAST: + default: + *fy = cy; + break; + + case XCB_GRAVITY_WEST: + case XCB_GRAVITY_CENTER: + case XCB_GRAVITY_EAST: + *fy = cy + cborder - ( ( frame_t( frame, TRUE ) + + frame_b( frame, TRUE ) ) >> 1 ); + break; + + case XCB_GRAVITY_SOUTH_WEST: + case XCB_GRAVITY_SOUTH: + case XCB_GRAVITY_SOUTH_EAST: + *fy = cy + ( cborder << 1 ) - frame_t( frame, TRUE ) - + frame_b( frame, TRUE ); + break; + + case XCB_GRAVITY_STATIC: + *fy = cy + cborder - frame_t( frame, TRUE ); + break; + } +} + +extern void translate_frame_to_child( struct gwm_window *frame, + int *cx, int *cy, int fx, int fy, + int cborder, int win_gravity ) { + + switch( win_gravity ) { + case XCB_GRAVITY_NORTH_WEST: + case XCB_GRAVITY_WEST: + case XCB_GRAVITY_SOUTH_WEST: + default: + *cx = fx; + break; + + case XCB_GRAVITY_NORTH: + case XCB_GRAVITY_CENTER: + case XCB_GRAVITY_SOUTH: + *cx = fx - cborder + ( ( frame_l( frame, TRUE ) + + frame_r( frame, TRUE ) ) >> 1 ); + break; + + case XCB_GRAVITY_NORTH_EAST: + case XCB_GRAVITY_EAST: + case XCB_GRAVITY_SOUTH_EAST: + *cx = fx - ( cborder << 1 ) + frame_l( frame, TRUE ) + + frame_r( frame, TRUE ); + break; + + case XCB_GRAVITY_STATIC: + *cx = fx - cborder + frame_l( frame, TRUE ); + break; + } + + switch( win_gravity ) { + case XCB_GRAVITY_NORTH_WEST: + case XCB_GRAVITY_NORTH: + case XCB_GRAVITY_NORTH_EAST: + default: + *cy = fy; + break; + + case XCB_GRAVITY_WEST: + case XCB_GRAVITY_CENTER: + case XCB_GRAVITY_EAST: + *cy = fy - cborder + ( ( frame_t( frame, TRUE ) + + frame_b( frame, TRUE ) ) >> 1 ); + break; + + case XCB_GRAVITY_SOUTH_WEST: + case XCB_GRAVITY_SOUTH: + case XCB_GRAVITY_SOUTH_EAST: + *cy = fy - ( cborder << 1 ) + frame_t( frame, TRUE ) + + frame_b( frame, TRUE ); + break; + + case XCB_GRAVITY_STATIC: + *cy = fy - cborder + frame_t( frame, TRUE ); + break; + } +} + +extern void apply_size_constraints( struct gwm_window *window, int *width, + int *height ) { + + int eff_base_width = window->u.managed.base_width ? + window->u.managed.base_width : window->u.managed.min_width, + eff_base_height = window->u.managed.base_height ? + window->u.managed.base_height : window->u.managed.min_height; + + /* Apply the minimum and maximum constraints. These are already known + to be compatible. */ + if( *width < window->u.managed.min_width ) + *width = window->u.managed.min_width; + + if( *height < window->u.managed.min_height ) + *height = window->u.managed.min_height; + + if( *width > window->u.managed.max_width ) + *width = window->u.managed.max_width; + + if( *height > window->u.managed.max_height ) + *height = window->u.managed.max_height; + + /* Now round down each dimension to an integer multiple of increments. + Rounding down cannot violate the maximum constraint, and since + eff_base_* >= min_*, it will not reduce below the minimum constraint. */ + *width -= ( *width - eff_base_width ) % window->u.managed.width_inc; + *height -= ( *height - eff_base_height ) % window->u.managed.height_inc; + + if( window->u.managed.min_aspect_x * *height > + window->u.managed.min_aspect_y * *width ) { + /* Minimum aspect ratio violated. Attempt to either increase the + width or decrease the height (whichever is a smaller change), but + don't do either if it would go outside the min/max bounds. + Both division operations are safe (min_aspect_y is always + positive, and min_aspect_x must be positive if there is a + violation). Note that an exact solution might not be possible + (e.g. certain cases where the aspect ratio and increments are + coprime). */ + int min_x, max_y; + + min_x = ( window->u.managed.min_aspect_x * *height + + ( window->u.managed.min_aspect_y - 1 ) ) / + window->u.managed.min_aspect_y + window->u.managed.width_inc - 1; + min_x -= ( min_x - eff_base_width ) % window->u.managed.width_inc; + + max_y = window->u.managed.min_aspect_y * *width / + window->u.managed.min_aspect_x; + max_y -= ( max_y - eff_base_height ) % window->u.managed.height_inc; + + if( min_x - *width < *height - max_y ) { + /* The width change is smaller: prefer it if possible. */ + if( min_x >= window->u.managed.min_width ) + *width = min_x; + else if( max_y < window->u.managed.max_height ) + *height = max_y; + } else { + /* The height change is smaller: prefer it if possible. */ + if( max_y < window->u.managed.max_height ) + *height = max_y; + else if( min_x >= window->u.managed.min_width ) + *width = min_x; + } + } + + if( window->u.managed.max_aspect_x * *height < + window->u.managed.max_aspect_y * *width ) { + /* Maximum aspect ratio violated. Much like the case above... */ + int min_y, max_x; + + min_y = ( window->u.managed.max_aspect_y * *width + + ( window->u.managed.max_aspect_x - 1 ) ) / + window->u.managed.max_aspect_x + window->u.managed.height_inc - 1; + min_y -= ( min_y - eff_base_height ) % window->u.managed.height_inc; + + max_x = window->u.managed.max_aspect_x * *height / + window->u.managed.max_aspect_y; + max_x -= ( max_x - eff_base_width ) % window->u.managed.width_inc; + + if( min_y - *height < *width - max_x ) { + /* The height change is smaller: prefer it if possible. */ + if( min_y >= window->u.managed.min_height ) + *height = min_y; + else if( max_x < window->u.managed.max_width ) + *width = max_x; + } else { + /* The width change is smaller: prefer it if possible. */ + if( max_x < window->u.managed.max_width ) + *width = max_x; + else if( min_y >= window->u.managed.min_height ) + *height = min_y; + } + } +} + static enum _window_operation { OP_NONE, OP_MOVE, OP_RESIZE } window_op; @@ -104,10 +361,10 @@ static void build_edges( int screen ) { window->screen == screen ) { int t = window->u.frame.y, b = window->u.frame.y + window->u.frame.height + - ( FRAME_X_BORDER << 1 ), + ( frame_xb( window ) << 1 ), l = window->u.frame.x, r = window->u.frame.x + window->u.frame.width + - ( FRAME_X_BORDER << 1 ); + ( frame_xb( window ) << 1 ); if( t >= screens[ screen ]->height_in_pixels || b <= 0 || l >= screens[ screen ]->width_in_pixels || r <= 0 ) @@ -266,9 +523,9 @@ static void recalc_size( struct gwm_window *window, int x, int y, int old_t, old_b, old_l, old_r, new_t, new_b, new_l, new_r; old_t = window->u.frame.y; - old_b = old_t + window->u.frame.height + ( FRAME_X_BORDER << 1 ); + old_b = old_t + window->u.frame.height + ( frame_xb( window ) << 1 ); old_l = window->u.frame.x; - old_r = old_l + window->u.frame.width + ( FRAME_X_BORDER << 1 ); + old_r = old_l + window->u.frame.width + ( frame_xb( window ) << 1 ); if( size_x == SIZE_LESSER ) { new_l = x - dx; @@ -342,21 +599,25 @@ static void recalc_size( struct gwm_window *window, int x, int y, new_b += ey; } - new_width = new_r - new_l - ( FRAME_X_BORDER << 1 ); - new_height = new_b - new_t - ( FRAME_X_BORDER << 1 ); + new_width = new_r - new_l - ( frame_xb( window ) << 1 ); + new_height = new_b - new_t - ( frame_xb( window ) << 1 ); - child_width = new_width - ( FRAME_BORDER_WIDTH << 1 ); - child_height = new_height - FRAME_TITLE_HEIGHT - FRAME_BORDER_WIDTH; + child_width = new_width - frame_l( window, FALSE ) - + frame_r( window, FALSE ); + child_height = new_height - frame_t( window, FALSE ) - + frame_b( window, FALSE ); apply_size_constraints( window->u.frame.child, &child_width, &child_height ); - new_width = child_width + ( FRAME_BORDER_WIDTH << 1 ); - new_height = child_height + FRAME_TITLE_HEIGHT + FRAME_BORDER_WIDTH; + new_width = child_width + frame_l( window, FALSE ) + + frame_r( window, FALSE ); + new_height = child_height + frame_t( window, FALSE ) + + frame_b( window, FALSE ); if( size_x == SIZE_LESSER ) - new_l = new_r - new_width - ( FRAME_X_BORDER << 1 ); + new_l = new_r - new_width - ( frame_xb( window ) << 1 ); if( size_y == SIZE_LESSER ) - new_t = new_b - new_height - ( FRAME_X_BORDER << 1 ); + new_t = new_b - new_height - ( frame_xb( window ) << 1 ); if( new_l != window->u.frame.x || new_t != window->u.frame.y || new_width != window->u.frame.width || @@ -368,8 +629,10 @@ static void recalc_size( struct gwm_window *window, int x, int y, XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, values ); - values[ 0 ] = new_width - ( FRAME_BORDER_WIDTH << 1 ); - values[ 1 ] = new_height - FRAME_TITLE_HEIGHT - FRAME_BORDER_WIDTH; + values[ 0 ] = new_width - frame_l( window, FALSE ) - + frame_r( window, FALSE ); + values[ 1 ] = new_height - frame_t( window, FALSE ) - + frame_b( window, FALSE ); /* FIXME See _NET_WM_SYNC_REQUEST in the EWMH to avoid resizing the window faster than the client can redraw it. */ xcb_configure_window( c, window->u.frame.child->w, @@ -431,8 +694,8 @@ static void frame_button_press( struct gwm_window *window, if( !initial_press( ev ) || ev->child ) return; - window_op = ( ev->detail > 1 ) == ( ev->event_y < FRAME_TITLE_HEIGHT ) ? - OP_RESIZE : OP_MOVE; + window_op = ( ev->detail > 1 ) == + ( ev->event_y < frame_t( window, FALSE ) ) ? OP_RESIZE : OP_MOVE; init_x = ev->root_x; init_y = ev->root_y; @@ -482,13 +745,13 @@ static void frame_motion_notify( struct gwm_window *window, case OP_MOVE: old_t = window->u.frame.y; - old_b = old_t + window->u.frame.height + ( FRAME_X_BORDER << 1 ); + old_b = old_t + window->u.frame.height + ( frame_xb( window ) << 1 ); old_l = window->u.frame.x; - old_r = old_l + window->u.frame.width + ( FRAME_X_BORDER << 1 ); - new_t = ev->root_y - dy - FRAME_X_BORDER; - new_b = new_t + window->u.frame.height + ( FRAME_X_BORDER << 1 ); - new_l = ev->root_x - dx - FRAME_X_BORDER; - new_r = new_l + window->u.frame.width + ( FRAME_X_BORDER << 1 ); + old_r = old_l + window->u.frame.width + ( frame_xb( window ) << 1 ); + new_t = ev->root_y - dy - frame_xb( window ); + new_b = new_t + window->u.frame.height + ( frame_xb( window ) << 1 ); + new_l = ev->root_x - dx - frame_xb( window ); + new_r = new_l + window->u.frame.width + ( frame_xb( window ) << 1 ); if( !( ev->state & XCB_MOD_MASK_CONTROL ) ) { int ex, ey; @@ -647,13 +910,14 @@ extern void synthetic_configure_notify( struct gwm_window *window ) { msg.response_type = XCB_CONFIGURE_NOTIFY; msg.event = msg.window = window->u.frame.child->w; msg.above_sibling = XCB_NONE; - msg.x = window->u.frame.x + FRAME_BORDER_WIDTH + FRAME_X_BORDER - + msg.x = window->u.frame.x + frame_l( window, TRUE ) - window->u.frame.child->u.managed.border_width; - msg.y = window->u.frame.y + FRAME_TITLE_HEIGHT + FRAME_X_BORDER - + msg.y = window->u.frame.y + frame_t( window, TRUE ) - window->u.frame.child->u.managed.border_width; - msg.width = window->u.frame.width - ( FRAME_BORDER_WIDTH << 1 ); - msg.height = window->u.frame.height - FRAME_TITLE_HEIGHT - - FRAME_BORDER_WIDTH; + msg.width = window->u.frame.width - frame_l( window, FALSE ) - + frame_r( window, FALSE ); + msg.height = window->u.frame.height - frame_t( window, FALSE ) - + frame_b( window, FALSE ); msg.border_width = window->u.frame.child->u.managed.border_width; msg.override_redirect = FALSE; xcb_send_event( c, FALSE, window->u.frame.child->w, @@ -684,16 +948,17 @@ static void frame_configure_request( struct gwm_window *window, /* Ignore border width request, but remember what was asked for. */ window->u.frame.child->u.managed.border_width = ev->border_width; - translate_frame_to_child( &child_x, &child_y, window->u.frame.x, - window->u.frame.y, + translate_frame_to_child( window, &child_x, &child_y, + window->u.frame.x, window->u.frame.y, window->u.frame.child->u.managed.border_width, window->u.frame.child->u.managed.win_gravity ); x = ev->value_mask & XCB_CONFIG_WINDOW_X ? ev->x : child_x; y = ev->value_mask & XCB_CONFIG_WINDOW_Y ? ev->y : child_y; - translate_child_to_frame( &frame_x, &frame_y, &frame_width, &frame_height, - x, y, ev->width, ev->height, + translate_child_to_frame( window, &frame_x, &frame_y, + &frame_width, &frame_height, x, y, + ev->width, ev->height, window->u.frame.child->u.managed.border_width, window->u.frame.child->u.managed.win_gravity ); @@ -717,9 +982,10 @@ static void frame_configure_request( struct gwm_window *window, if( frame_width != window->u.frame.width || frame_height != window->u.frame.height ) { - values[ 0 ] = frame_width - ( FRAME_BORDER_WIDTH << 1 ); - values[ 1 ] = frame_height - FRAME_TITLE_HEIGHT - - FRAME_BORDER_WIDTH; + values[ 0 ] = frame_width - frame_l( window, FALSE ) - + frame_r( window, FALSE ); + values[ 1 ] = frame_height - frame_t( window, FALSE ) - + frame_b( window, FALSE ); xcb_configure_window( c, ev->window, XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, values ); } @@ -1,6 +1,25 @@ #ifndef FRAME_H #define FRAME_H +extern int frame_t( struct gwm_window *window, int include_x_border ); +extern int frame_b( struct gwm_window *window, int include_x_border ); +extern int frame_l( struct gwm_window *window, int include_x_border ); +extern int frame_r( struct gwm_window *window, int include_x_border ); +extern int frame_xb( struct gwm_window *window ); + +extern void translate_child_to_frame( struct gwm_window *frame, + int *fx, int *fy, int *fwidth, + int *fheight, int cx, int cy, + int cwidth, int cheight, + int cborder, int win_gravity ); + +extern void translate_frame_to_child( struct gwm_window *frame, + int *cx, int *cy, int fx, int fy, + int cborder, int win_gravity ); + +extern void apply_size_constraints( struct gwm_window *window, int *width, + int *height ); + extern void synthetic_configure_notify( struct gwm_window *window ); extern event_handler frame_handlers[], childless_handlers[]; @@ -979,211 +979,6 @@ extern CONST int final_release( xcb_button_release_event_t *ev ) { return ( ev->state & 0x1F00 ) == ( 0x80 << ev->detail ); } -extern void translate_child_to_frame( int *fx, int *fy, int *fwidth, - int *fheight, int cx, int cy, - int cwidth, int cheight, - int cborder, int win_gravity ) { - - *fwidth = cwidth + FRAME_BORDER_WIDTH * 2; - *fheight = cheight + FRAME_BORDER_WIDTH + FRAME_TITLE_HEIGHT; - - switch( win_gravity ) { - case XCB_GRAVITY_NORTH_WEST: - case XCB_GRAVITY_WEST: - case XCB_GRAVITY_SOUTH_WEST: - default: - *fx = cx; - break; - - case XCB_GRAVITY_NORTH: - case XCB_GRAVITY_CENTER: - case XCB_GRAVITY_SOUTH: - case XCB_GRAVITY_STATIC: - *fx = cx + cborder - FRAME_BORDER_WIDTH - FRAME_X_BORDER; - break; - - case XCB_GRAVITY_NORTH_EAST: - case XCB_GRAVITY_EAST: - case XCB_GRAVITY_SOUTH_EAST: - *fx = cx + ( ( cborder - FRAME_BORDER_WIDTH - FRAME_X_BORDER ) << 1 ); - break; - } - - switch( win_gravity ) { - case XCB_GRAVITY_NORTH_WEST: - case XCB_GRAVITY_NORTH: - case XCB_GRAVITY_NORTH_EAST: - default: - *fy = cy; - break; - - case XCB_GRAVITY_WEST: - case XCB_GRAVITY_CENTER: - case XCB_GRAVITY_EAST: - *fy = cy + cborder - ( ( FRAME_BORDER_WIDTH + - FRAME_TITLE_HEIGHT ) >> 1 ) - FRAME_X_BORDER; - break; - - case XCB_GRAVITY_SOUTH_WEST: - case XCB_GRAVITY_SOUTH: - case XCB_GRAVITY_SOUTH_EAST: - *fy = cy + ( cborder << 1 ) - FRAME_TITLE_HEIGHT - FRAME_BORDER_WIDTH - - ( FRAME_X_BORDER << 1 ); - break; - - case XCB_GRAVITY_STATIC: - *fy = cy + cborder - FRAME_TITLE_HEIGHT - FRAME_X_BORDER; - break; - } -} - -extern void translate_frame_to_child( int *cx, int *cy, int fx, int fy, - int cborder, int win_gravity ) { - - switch( win_gravity ) { - case XCB_GRAVITY_NORTH_WEST: - case XCB_GRAVITY_WEST: - case XCB_GRAVITY_SOUTH_WEST: - default: - *cx = fx; - break; - - case XCB_GRAVITY_NORTH: - case XCB_GRAVITY_CENTER: - case XCB_GRAVITY_SOUTH: - case XCB_GRAVITY_STATIC: - *cx = fx - cborder + FRAME_BORDER_WIDTH + FRAME_X_BORDER; - break; - - case XCB_GRAVITY_NORTH_EAST: - case XCB_GRAVITY_EAST: - case XCB_GRAVITY_SOUTH_EAST: - *cx = fx + ( ( FRAME_BORDER_WIDTH + FRAME_X_BORDER - cborder ) << 1 ); - break; - } - - switch( win_gravity ) { - case XCB_GRAVITY_NORTH_WEST: - case XCB_GRAVITY_NORTH: - case XCB_GRAVITY_NORTH_EAST: - default: - *cy = fy; - break; - - case XCB_GRAVITY_WEST: - case XCB_GRAVITY_CENTER: - case XCB_GRAVITY_EAST: - *cy = fy - cborder + ( ( FRAME_BORDER_WIDTH + - FRAME_TITLE_HEIGHT ) >> 1 ) + FRAME_X_BORDER; - break; - - case XCB_GRAVITY_SOUTH_WEST: - case XCB_GRAVITY_SOUTH: - case XCB_GRAVITY_SOUTH_EAST: - *cy = fy - ( cborder << 1 ) + FRAME_TITLE_HEIGHT + FRAME_BORDER_WIDTH + - ( FRAME_X_BORDER << 1 ); - break; - - case XCB_GRAVITY_STATIC: - *cy = fy - cborder + FRAME_TITLE_HEIGHT + FRAME_X_BORDER; - break; - } -} - -extern void apply_size_constraints( struct gwm_window *window, int *width, - int *height ) { - - int eff_base_width = window->u.managed.base_width ? - window->u.managed.base_width : window->u.managed.min_width, - eff_base_height = window->u.managed.base_height ? - window->u.managed.base_height : window->u.managed.min_height; - - /* Apply the minimum and maximum constraints. These are already known - to be compatible. */ - if( *width < window->u.managed.min_width ) - *width = window->u.managed.min_width; - - if( *height < window->u.managed.min_height ) - *height = window->u.managed.min_height; - - if( *width > window->u.managed.max_width ) - *width = window->u.managed.max_width; - - if( *height > window->u.managed.max_height ) - *height = window->u.managed.max_height; - - /* Now round down each dimension to an integer multiple of increments. - Rounding down cannot violate the maximum constraint, and since - eff_base_* >= min_*, it will not reduce below the minimum constraint. */ - *width -= ( *width - eff_base_width ) % window->u.managed.width_inc; - *height -= ( *height - eff_base_height ) % window->u.managed.height_inc; - - if( window->u.managed.min_aspect_x * *height > - window->u.managed.min_aspect_y * *width ) { - /* Minimum aspect ratio violated. Attempt to either increase the - width or decrease the height (whichever is a smaller change), but - don't do either if it would go outside the min/max bounds. - Both division operations are safe (min_aspect_y is always - positive, and min_aspect_x must be positive if there is a - violation). Note that an exact solution might not be possible - (e.g. certain cases where the aspect ratio and increments are - coprime). */ - int min_x, max_y; - - min_x = ( window->u.managed.min_aspect_x * *height + - ( window->u.managed.min_aspect_y - 1 ) ) / - window->u.managed.min_aspect_y + window->u.managed.width_inc - 1; - min_x -= ( min_x - eff_base_width ) % window->u.managed.width_inc; - - max_y = window->u.managed.min_aspect_y * *width / - window->u.managed.min_aspect_x; - max_y -= ( max_y - eff_base_height ) % window->u.managed.height_inc; - - if( min_x - *width < *height - max_y ) { - /* The width change is smaller: prefer it if possible. */ - if( min_x >= window->u.managed.min_width ) - *width = min_x; - else if( max_y < window->u.managed.max_height ) - *height = max_y; - } else { - /* The height change is smaller: prefer it if possible. */ - if( max_y < window->u.managed.max_height ) - *height = max_y; - else if( min_x >= window->u.managed.min_width ) - *width = min_x; - } - } - - if( window->u.managed.max_aspect_x * *height < - window->u.managed.max_aspect_y * *width ) { - /* Maximum aspect ratio violated. Much like the case above... */ - int min_y, max_x; - - min_y = ( window->u.managed.max_aspect_y * *width + - ( window->u.managed.max_aspect_x - 1 ) ) / - window->u.managed.max_aspect_x + window->u.managed.height_inc - 1; - min_y -= ( min_y - eff_base_height ) % window->u.managed.height_inc; - - max_x = window->u.managed.max_aspect_x * *height / - window->u.managed.max_aspect_y; - max_x -= ( max_x - eff_base_width ) % window->u.managed.width_inc; - - if( min_y - *height < *width - max_x ) { - /* The height change is smaller: prefer it if possible. */ - if( min_y >= window->u.managed.min_height ) - *height = min_y; - else if( max_x < window->u.managed.max_width ) - *width = max_x; - } else { - /* The width change is smaller: prefer it if possible. */ - if( max_x < window->u.managed.max_width ) - *width = max_x; - else if( min_y >= window->u.managed.min_height ) - *height = min_y; - } - } -} - static void stop_listening( struct gwm_window *window ) { uint32_t value; @@ -1279,7 +1074,7 @@ static void start_managing_window( struct gwm_window *window, for( i = 0; i < NUM_PROPS; i++ ) managed_property_change( window, i, props[ i ] ); - translate_child_to_frame( &frame->u.frame.x, &frame->u.frame.y, + translate_child_to_frame( frame, &frame->u.frame.x, &frame->u.frame.y, &frame->u.frame.width, &frame->u.frame.height, geom->x, geom->y, geom->width, geom->height, geom->border_width, @@ -1339,7 +1134,8 @@ static void start_managing_window( struct gwm_window *window, values[ 2 ] = TRUE; /* override redirect */ values[ 3 ] = XCB_EVENT_MASK_EXPOSURE; xcb_create_window( c, XCB_COPY_FROM_PARENT, button->w, frame->w, - 2, 1, FRAME_BUTTON_SIZE, FRAME_BUTTON_SIZE, 1, + 2, 1, button_size( button, FALSE ), + button_size( button, FALSE ), button_xb( button ), XCB_WINDOW_CLASS_INPUT_OUTPUT, XCB_COPY_FROM_PARENT, XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL | XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK, values ); @@ -1365,8 +1161,8 @@ static void start_managing_window( struct gwm_window *window, xcb_change_window_attributes( c, w, XCB_CW_EVENT_MASK, values ); } - xcb_reparent_window( c, w, frame->w, FRAME_BORDER_WIDTH, - FRAME_TITLE_HEIGHT ); + xcb_reparent_window( c, w, frame->w, frame_l( frame, FALSE ), + frame_t( frame, FALSE ) ); if( !map_request ) { values[ 0 ] = XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_PROPERTY_CHANGE | @@ -1576,7 +1372,7 @@ extern void unmanage_window( struct gwm_window *window ) { /* Reparent the window back to the root; delete its WM_STATE property (see ICCCM 4.1.4); and map it if it was iconic. */ - translate_frame_to_child( &x, &y, frame->u.frame.x, frame->u.frame.y, + translate_frame_to_child( frame, &x, &y, frame->u.frame.x, frame->u.frame.y, border_width, window->u.managed.win_gravity ); handle_error_reply( xcb_reparent_window_checked( c, w, screens[ window->screen ]->root, @@ -302,17 +302,6 @@ extern xcb_window_t passive_grab; extern void install_window_colormap( int screen, struct gwm_window *window, xcb_timestamp_t t ); -extern void translate_child_to_frame( int *fx, int *fy, int *fwidth, - int *fheight, int cx, int cy, - int cwidth, int cheight, - int cborder, int win_gravity ); - -extern void translate_frame_to_child( int *cx, int *cy, int fx, int fy, - int cborder, int win_gravity ); - -extern void apply_size_constraints( struct gwm_window *window, int *width, - int *height ); - extern void generic_expose( struct gwm_window *window, xcb_expose_event_t *ev ); @@ -328,13 +317,6 @@ extern void unmanage_window( struct gwm_window *window ); asynchronous callbacks scheduled for replies and errors. */ extern xcb_generic_event_t *wait_for_event( void ); -#define FRAME_X_BORDER 1 /* X border added to all four sides of frame */ -#define FRAME_BORDER_WIDTH 2 /* pixels added to left, right and bottom; - includes padding but excludes X border */ -#define FRAME_TITLE_HEIGHT 16 /* pixels added to top; includes title - bar but excludes X border */ -#define FRAME_BUTTON_SIZE 12 /* size of buttons in title bar; excludes - X border */ #define FEEDBACK_WIDTH 96 /* width of size feedback window */ #define FEEDBACK_HEIGHT 24 /* height of size feedback window */ @@ -170,7 +170,8 @@ extern void managed_property_change( struct gwm_window *window, int prop, if( window->u.managed.state == STATE_NORMAL ) queue_window_update( window->u.managed.frame, 0, 0, window->u.managed.frame->u.frame.width, - FRAME_TITLE_HEIGHT, FALSE ); + frame_t( window->u.managed.frame, FALSE ), + FALSE ); } else { window->u.managed.name = NULL; window->u.managed.net_wm_name = 0; @@ -245,15 +246,18 @@ extern void managed_property_change( struct gwm_window *window, int prop, if( window->u.managed.state == STATE_NORMAL ) queue_window_update( window->u.managed.frame, 0, 0, window->u.managed.frame->u.frame.width, - FRAME_TITLE_HEIGHT, FALSE ); + frame_t( window->u.managed.frame, FALSE ), + FALSE ); break; case PROP_WM_NORMAL_HINTS: /* WM_NORMAL_HINTS property (see ICCCM 2.0, section 4.1.2.3). */ window->u.managed.hints &= ~HINT_POSITION; - window->u.managed.min_width = FRAME_TITLE_HEIGHT; - window->u.managed.min_height = FRAME_TITLE_HEIGHT >> 1; + window->u.managed.min_width = frame_t( window->u.managed.frame, + FALSE ); + window->u.managed.min_height = frame_t( window->u.managed.frame, + FALSE ) >> 1; window->u.managed.max_width = 0x7FFF; window->u.managed.max_height = 0x7FFF; window->u.managed.width_inc = 1; @@ -335,13 +339,17 @@ extern void managed_property_change( struct gwm_window *window, int prop, /* Sanity check. */ screen = screens[ window->screen ]; - if( window->u.managed.min_width < FRAME_TITLE_HEIGHT ) - window->u.managed.min_width = FRAME_TITLE_HEIGHT; + if( window->u.managed.min_width < frame_t( window->u.managed.frame, + FALSE ) ) + window->u.managed.min_width = frame_t( window->u.managed.frame, + FALSE ); if( window->u.managed.min_width > screen->width_in_pixels ) window->u.managed.min_width = screen->width_in_pixels; - - if( window->u.managed.min_height < FRAME_TITLE_HEIGHT >> 1 ) - window->u.managed.min_height = FRAME_TITLE_HEIGHT >> 1; + + if( window->u.managed.min_height < frame_t( window->u.managed.frame, + FALSE ) >> 1 ) + window->u.managed.min_height = frame_t( window->u.managed.frame, + FALSE ) >> 1; if( window->u.managed.min_height > screen->height_in_pixels ) window->u.managed.min_height = screen->height_in_pixels; @@ -382,9 +390,11 @@ extern void managed_property_change( struct gwm_window *window, int prop, if( window->u.managed.state == STATE_NORMAL ) { /* Recalculate constraints. */ int width = window->u.managed.frame->u.frame.width - - ( FRAME_BORDER_WIDTH << 1 ); + frame_l( window->u.managed.frame, FALSE ) - + frame_r( window->u.managed.frame, FALSE ); int height = window->u.managed.frame->u.frame.height - - FRAME_TITLE_HEIGHT - FRAME_BORDER_WIDTH; + frame_t( window->u.managed.frame, FALSE ) - + frame_b( window->u.managed.frame, FALSE ); int old_width, old_height; old_width = width; @@ -471,13 +481,15 @@ extern void match_managed_shape( struct gwm_window *window, int shaped ) { rect.x = rect.y = 0; rect.width = window->u.managed.frame->u.frame.width; - rect.height = FRAME_TITLE_HEIGHT; + rect.height = frame_t( window->u.managed.frame, FALSE ); xcb_shape_rectangles( c, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING, 0, window->u.managed.frame->w, 0, 0, 1, &rect ); xcb_shape_combine( c, XCB_SHAPE_SO_UNION, XCB_SHAPE_SK_BOUNDING, XCB_SHAPE_SK_BOUNDING, window->u.managed.frame->w, - FRAME_BORDER_WIDTH, FRAME_TITLE_HEIGHT, window->w ); + frame_l( window->u.managed.frame, FALSE ), + frame_t( window->u.managed.frame, FALSE ), + window->w ); } else xcb_shape_mask( c, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING, window->u.managed.frame->w, 0, 0, XCB_NONE ); |