summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGary Wong <gtw@gnu.org>2009-08-31 17:30:02 -0600
committerGary Wong <gtw@gnu.org>2009-08-31 17:30:02 -0600
commit6d9d33354b9ac4ef25708d13e385c0c24a1fa2f3 (patch)
treeeddbef2c8ff038707f1f0e0ef26445e945066266
parent69b03632ad36228490e30e79852f8b922fb22c74 (diff)
Show different cursors over various parts of frame borders.
-rw-r--r--ChangeLog12
-rw-r--r--decorate-core.c6
-rw-r--r--decorate-render.c6
-rw-r--r--frame.c73
-rw-r--r--gwm.c11
-rw-r--r--gwm.h17
6 files changed, 116 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index f13da1d..53c1d79 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,17 @@
2009-08-31 Gary Wong <gtw@gnu.org>
+ * gwm.c (start_managing_window): Create "border region" input-only
+ windows, to allow setting different cursors on various border parts.
+ * frame.c (frame_configure_notify): Update the geometry of the
+ border regions.
+ * decorate-core.c (decorate_core_init): Cursor indices were rearranged.
+ * decorate-render.c (decorate_compat_init): Likewise.
+
+ * frame.c (frame_button_press): Do not recognise a passive grab
+ propagated from the client.
+
+2009-08-31 Gary Wong <gtw@gnu.org>
+
* frame.c (frame_t, frame_xb): Make window decorations optional.
(frame_blr): New function.
(frame_b, frame_l, frame_r): Invoke frame_blr().
diff --git a/decorate-core.c b/decorate-core.c
index 52f5837..8613d12 100644
--- a/decorate-core.c
+++ b/decorate-core.c
@@ -332,8 +332,6 @@ extern void decorate_core_init( void ) {
union callback_param p;
xcb_font_t cursor_font;
static const int cursor_glyphs[ NUM_CURSORS ] = {
- 68, /* CURSOR_ARROW */
- 88, /* CURSOR_DESTROY */
134, /* CURSOR_TL */
138, /* CURSOR_T */
136, /* CURSOR_TR */
@@ -342,7 +340,9 @@ extern void decorate_core_init( void ) {
96, /* CURSOR_R */
12, /* CURSOR_BL */
16, /* CURSOR_B */
- 14 /* CURSOR_BR */
+ 14, /* CURSOR_BR */
+ 68, /* CURSOR_ARROW */
+ 88 /* CURSOR_DESTROY */
};
font = xcb_generate_id( c );
diff --git a/decorate-render.c b/decorate-render.c
index b844973..6012ca3 100644
--- a/decorate-render.c
+++ b/decorate-render.c
@@ -725,8 +725,6 @@ static void decorate_compat_init( void ) {
const char *cursor_font_name = "cursor";
xcb_font_t cursor_font;
static const int cursor_glyphs[ NUM_CURSORS ] = {
- 68, /* CURSOR_ARROW */
- 88, /* CURSOR_DESTROY */
134, /* CURSOR_TL */
138, /* CURSOR_T */
136, /* CURSOR_TR */
@@ -735,7 +733,9 @@ static void decorate_compat_init( void ) {
96, /* CURSOR_R */
12, /* CURSOR_BL */
16, /* CURSOR_B */
- 14 /* CURSOR_BR */
+ 14, /* CURSOR_BR */
+ 68, /* CURSOR_ARROW */
+ 88 /* CURSOR_DESTROY */
};
cursor_font = xcb_generate_id( c );
diff --git a/frame.c b/frame.c
index f6a6bcc..41d5714 100644
--- a/frame.c
+++ b/frame.c
@@ -731,9 +731,15 @@ static void recalc_size( struct gwm_window *window, int x, int y,
static void frame_button_press( struct gwm_window *window,
xcb_button_press_event_t *ev ) {
- if( !initial_press( ev ) || ev->child )
+ if( !initial_press( ev ) )
return;
+ if( ev->child == window->u.frame.child->w ) {
+ passive_grab = XCB_NONE;
+
+ return;
+ }
+
window_op = ( ev->detail > 1 ) ==
( ( window->u.frame.decoration & DEC_TITLE ) &&
ev->event_y < frame_t( window, FALSE ) ) ? OP_RESIZE : OP_MOVE;
@@ -971,6 +977,8 @@ extern void synthetic_configure_notify( struct gwm_window *window ) {
static void frame_configure_notify( struct gwm_window *window,
xcb_configure_notify_event_t *ev ) {
+ int i;
+
if( ev->window != window->w )
return;
@@ -979,6 +987,69 @@ static void frame_configure_notify( struct gwm_window *window,
window->u.frame.width = ev->width;
window->u.frame.height = ev->height;
+ for( i = 0; i < NUM_BORDER_REGIONS; i++ ) {
+ uint32_t values[ 4 ]; /* x, y, width and height respectively */
+
+ switch( i ) {
+ case BR_TL:
+ case BR_L:
+ case BR_BL:
+ values[ 0 ] = 0;
+ values[ 2 ] = window->u.frame.width >> 2;
+ break;
+
+ case BR_T:
+ case BR_B:
+ values[ 0 ] = window->u.frame.width >> 2;
+ values[ 2 ] = window->u.frame.width - ( values[ 0 ] << 1 );
+ break;
+
+ case BR_TR:
+ case BR_R:
+ case BR_BR:
+ values[ 2 ] = window->u.frame.width >> 2;
+ values[ 0 ] = window->u.frame.width - values[ 2 ];
+ break;
+ }
+
+ switch( i ) {
+ case BR_TL:
+ case BR_T:
+ case BR_TR:
+ if( window->u.frame.decoration & DEC_TITLE ) {
+ values[ 1 ] = frame_t( window, FALSE );
+ values[ 3 ] = ( window->u.frame.height >> 2 ) - values[ 1 ];
+ } else {
+ values[ 1 ] = 0;
+ values[ 3 ] = window->u.frame.height >> 2;
+ }
+ break;
+
+ case BR_L:
+ case BR_R:
+ values[ 1 ] = window->u.frame.height >> 2;
+ values[ 3 ] = window->u.frame.height - ( values[ 1 ] << 1 );
+ break;
+
+ case BR_BL:
+ case BR_B:
+ case BR_BR:
+ values[ 3 ] = window->u.frame.height >> 2;
+ values[ 1 ] = window->u.frame.height - values[ 3 ];
+ }
+
+ if( window->u.frame.decoration & DEC_BORDER &&
+ values[ 2 ] > 0 && values[ 3 ] > 0 &&
+ !( i == BR_T && ( window->u.frame.decoration & DEC_TITLE ) ) ) {
+ xcb_configure_window( c, window->u.frame.border_regions[ i ],
+ XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y |
+ XCB_CONFIG_WINDOW_WIDTH |
+ XCB_CONFIG_WINDOW_HEIGHT, values );
+ xcb_map_window( c, window->u.frame.border_regions[ i ] );
+ } else
+ xcb_unmap_window( c, window->u.frame.border_regions[ i ] );
+ }
+
synthetic_configure_notify( window );
}
diff --git a/gwm.c b/gwm.c
index 2a3585b..10b6f8d 100644
--- a/gwm.c
+++ b/gwm.c
@@ -1073,6 +1073,8 @@ static void start_managing_window( struct gwm_window *window,
frame->u.frame.child = window;
frame->u.frame.button = button;
frame->u.frame.decoration = DEC_DEFAULT;
+ for( i = 0; i < NUM_BORDER_REGIONS; i++ )
+ frame->u.frame.border_regions[ i ] = xcb_generate_id( c );
button->screen = window->screen;
button->type = WINDOW_BUTTON;
button->u.button.frame = frame;
@@ -1156,6 +1158,15 @@ static void start_managing_window( struct gwm_window *window,
if( frame->u.frame.decoration & DEC_TITLE )
xcb_map_window( c, button->w );
+ for( i = 0; i < NUM_BORDER_REGIONS; i++ ) {
+ values[ 0 ] = cursors[ i < BR_R ? i : i + 1 ];
+ /* Temporary positions: these windows will be moved, sized and
+ mapped if necessary in the frame ConfigureNotify handler. */
+ xcb_create_window( c, 0, frame->u.frame.border_regions[ i ], frame->w,
+ 0, 0, 1, 1, 0, XCB_WINDOW_CLASS_INPUT_ONLY,
+ XCB_COPY_FROM_PARENT, XCB_CW_CURSOR, values );
+ }
+
xcb_change_save_set( c, XCB_SET_MODE_INSERT, w );
if( !map_request ) {
diff --git a/gwm.h b/gwm.h
index 9cf219c..ca80a36 100644
--- a/gwm.h
+++ b/gwm.h
@@ -160,9 +160,19 @@ struct gwm_screen {
extern struct gwm_screen *gwm_screens;
+enum border_region {
+ BR_TL,
+ BR_T,
+ BR_TR,
+ BR_L,
+ BR_R,
+ BR_BL,
+ BR_B,
+ BR_BR,
+ NUM_BORDER_REGIONS
+};
+
enum gwm_cursor {
- CURSOR_ARROW,
- CURSOR_DESTROY,
CURSOR_TL,
CURSOR_T,
CURSOR_TR,
@@ -172,6 +182,8 @@ enum gwm_cursor {
CURSOR_BL,
CURSOR_B,
CURSOR_BR,
+ CURSOR_ARROW,
+ CURSOR_DESTROY,
NUM_CURSORS
};
extern xcb_cursor_t cursors[ NUM_CURSORS ];
@@ -229,6 +241,7 @@ struct gwm_window {
struct gwm_window *child, *button;
int x, y, width, height;
int decoration; /* see DEC_* above */
+ xcb_window_t border_regions[ NUM_BORDER_REGIONS ];
} frame;
struct _gwm_button {
struct gwm_window *frame;