implement configure requests, adapt testcase
testcase does not pass 100% due to clients not being reparented correctly yet.
This commit is contained in:
parent
0723876429
commit
8f7bd538d8
|
@ -129,4 +129,12 @@ int con_orientation(Con *con);
|
||||||
*/
|
*/
|
||||||
Con *con_next_focused(Con *con);
|
Con *con_next_focused(Con *con);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns a "relative" Rect which contains the amount of pixels that need to
|
||||||
|
* be added to the original Rect to get the final position (obviously the
|
||||||
|
* amount of pixels for normal, 1pixel and borderless are different).
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Rect con_border_style_rect(Con *con);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -79,6 +79,7 @@ int handle_configure_event(void *prophs, xcb_connection_t *conn, xcb_configure_n
|
||||||
*/
|
*/
|
||||||
int handle_screen_change(void *prophs, xcb_connection_t *conn,
|
int handle_screen_change(void *prophs, xcb_connection_t *conn,
|
||||||
xcb_generic_event_t *e);
|
xcb_generic_event_t *e);
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configure requests are received when the application wants to resize
|
* Configure requests are received when the application wants to resize
|
||||||
|
@ -90,7 +91,7 @@ int handle_screen_change(void *prophs, xcb_connection_t *conn,
|
||||||
*/
|
*/
|
||||||
int handle_configure_request(void *prophs, xcb_connection_t *conn,
|
int handle_configure_request(void *prophs, xcb_connection_t *conn,
|
||||||
xcb_configure_request_event_t *event);
|
xcb_configure_request_event_t *event);
|
||||||
#endif
|
|
||||||
/**
|
/**
|
||||||
* Our window decorations were unmapped. That means, the window will be killed
|
* Our window decorations were unmapped. That means, the window will be killed
|
||||||
* now, so we better clean up before.
|
* now, so we better clean up before.
|
||||||
|
|
|
@ -37,6 +37,7 @@ while (0)
|
||||||
int min(int a, int b);
|
int min(int a, int b);
|
||||||
int max(int a, int b);
|
int max(int a, int b);
|
||||||
bool rect_contains(Rect rect, uint32_t x, uint32_t y);
|
bool rect_contains(Rect rect, uint32_t x, uint32_t y);
|
||||||
|
Rect rect_add(Rect a, Rect b);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates *destination with new_value and returns true if it was changed or false
|
* Updates *destination with new_value and returns true if it was changed or false
|
||||||
|
|
17
src/con.c
17
src/con.c
|
@ -430,3 +430,20 @@ Con *con_next_focused(Con *con) {
|
||||||
|
|
||||||
return next;
|
return next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns a "relative" Rect which contains the amount of pixels that need to
|
||||||
|
* be added to the original Rect to get the final position (obviously the
|
||||||
|
* amount of pixels for normal, 1pixel and borderless are different).
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Rect con_border_style_rect(Con *con) {
|
||||||
|
if (con->border_style == BS_NORMAL)
|
||||||
|
return (Rect){2, 0, -(2 * 2), -2};
|
||||||
|
|
||||||
|
if (con->border_style == BS_1PIXEL)
|
||||||
|
return (Rect){1, 1, -2, -2};
|
||||||
|
|
||||||
|
if (con->border_style == BS_NONE)
|
||||||
|
return (Rect){0, 0, 0, 0};
|
||||||
|
}
|
||||||
|
|
|
@ -274,7 +274,7 @@ int handle_map_request(void *prophs, xcb_connection_t *conn, xcb_map_request_eve
|
||||||
x_push_changes(croot);
|
x_push_changes(croot);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#if 0
|
|
||||||
/*
|
/*
|
||||||
* Configure requests are received when the application wants to resize windows on their own.
|
* Configure requests are received when the application wants to resize windows on their own.
|
||||||
*
|
*
|
||||||
|
@ -282,11 +282,16 @@ int handle_map_request(void *prophs, xcb_connection_t *conn, xcb_map_request_eve
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int handle_configure_request(void *prophs, xcb_connection_t *conn, xcb_configure_request_event_t *event) {
|
int handle_configure_request(void *prophs, xcb_connection_t *conn, xcb_configure_request_event_t *event) {
|
||||||
|
Con *con;
|
||||||
|
|
||||||
DLOG("window 0x%08x wants to be at %dx%d with %dx%d\n",
|
DLOG("window 0x%08x wants to be at %dx%d with %dx%d\n",
|
||||||
event->window, event->x, event->y, event->width, event->height);
|
event->window, event->x, event->y, event->width, event->height);
|
||||||
|
|
||||||
Client *client = table_get(&by_child, event->window);
|
/* For unmanaged windows, we just execute the configure request. As soon as
|
||||||
if (client == NULL) {
|
* it gets mapped, we will take over anyways. */
|
||||||
|
if ((con = con_by_window_id(event->window)) == NULL) {
|
||||||
|
DLOG("Configure request for unmanaged window, can do that.\n");
|
||||||
|
|
||||||
uint32_t mask = 0;
|
uint32_t mask = 0;
|
||||||
uint32_t values[7];
|
uint32_t values[7];
|
||||||
int c = 0;
|
int c = 0;
|
||||||
|
@ -311,79 +316,36 @@ int handle_configure_request(void *prophs, xcb_connection_t *conn, xcb_configure
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (client->fullscreen) {
|
DLOG("Configure request!\n");
|
||||||
DLOG("Client is in fullscreen mode\n");
|
if (con_is_floating(con) && con_is_leaf(con)) {
|
||||||
|
/* we actually need to apply the size/position changes to the *parent*
|
||||||
Rect child_rect = client->workspace->rect;
|
* container */
|
||||||
child_rect.x = child_rect.y = 0;
|
Rect bsr = con_border_style_rect(con);
|
||||||
fake_configure_notify(conn, child_rect, client->child);
|
if (con->border_style == BS_NORMAL)
|
||||||
|
bsr.height -= 17;
|
||||||
return 1;
|
con = con->parent;
|
||||||
}
|
DLOG("Container is a floating leaf node, will do that.\n");
|
||||||
|
|
||||||
/* Floating clients can be reconfigured */
|
|
||||||
if (client_is_floating(client)) {
|
|
||||||
i3Font *font = load_font(conn, config.font);
|
|
||||||
int mode = (client->container != NULL ? client->container->mode : MODE_DEFAULT);
|
|
||||||
/* TODO: refactor this code. we need a function to translate
|
|
||||||
* coordinates of child_rect/rect. */
|
|
||||||
|
|
||||||
if (event->value_mask & XCB_CONFIG_WINDOW_X) {
|
if (event->value_mask & XCB_CONFIG_WINDOW_X) {
|
||||||
if (mode == MODE_STACK || mode == MODE_TABBED) {
|
con->rect.x = event->x + (-1) * bsr.x;
|
||||||
client->rect.x = event->x - 2;
|
DLOG("proposed x = %d, new x is %d\n", event->x, con->rect.x);
|
||||||
} else {
|
|
||||||
if (client->titlebar_position == TITLEBAR_OFF && client->borderless)
|
|
||||||
client->rect.x = event->x;
|
|
||||||
else if (client->titlebar_position == TITLEBAR_OFF && !client->borderless)
|
|
||||||
client->rect.x = event->x - 1;
|
|
||||||
else client->rect.x = event->x - 2;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (event->value_mask & XCB_CONFIG_WINDOW_Y) {
|
if (event->value_mask & XCB_CONFIG_WINDOW_Y) {
|
||||||
if (mode == MODE_STACK || mode == MODE_TABBED) {
|
con->rect.y = event->y + (-1) * bsr.y;
|
||||||
client->rect.y = event->y - 2;
|
DLOG("proposed y = %d, new y is %d\n", event->y, con->rect.y);
|
||||||
} else {
|
|
||||||
if (client->titlebar_position == TITLEBAR_OFF && client->borderless)
|
|
||||||
client->rect.y = event->y;
|
|
||||||
else if (client->titlebar_position == TITLEBAR_OFF && !client->borderless)
|
|
||||||
client->rect.y = event->y - 1;
|
|
||||||
else client->rect.y = event->y - font->height - 2 - 2;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (event->value_mask & XCB_CONFIG_WINDOW_WIDTH) {
|
if (event->value_mask & XCB_CONFIG_WINDOW_WIDTH) {
|
||||||
if (mode == MODE_STACK || mode == MODE_TABBED) {
|
con->rect.width = event->width + (-1) * bsr.width;
|
||||||
client->rect.width = event->width + 2 + 2;
|
DLOG("proposed width = %d, new width is %d\n", event->width, con->rect.width);
|
||||||
} else {
|
|
||||||
if (client->titlebar_position == TITLEBAR_OFF && client->borderless)
|
|
||||||
client->rect.width = event->width;
|
|
||||||
else if (client->titlebar_position == TITLEBAR_OFF && !client->borderless)
|
|
||||||
client->rect.width = event->width + (1 + 1);
|
|
||||||
else client->rect.width = event->width + (2 + 2);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (event->value_mask & XCB_CONFIG_WINDOW_HEIGHT) {
|
if (event->value_mask & XCB_CONFIG_WINDOW_HEIGHT) {
|
||||||
if (mode == MODE_STACK || mode == MODE_TABBED) {
|
con->rect.height = event->height + (-1) * bsr.height;
|
||||||
client->rect.height = event->height + 2;
|
DLOG("proposed height = %d, new height is %d\n", event->height, con->rect.height);
|
||||||
} else {
|
|
||||||
if (client->titlebar_position == TITLEBAR_OFF && client->borderless)
|
|
||||||
client->rect.height = event->height;
|
|
||||||
else if (client->titlebar_position == TITLEBAR_OFF && !client->borderless)
|
|
||||||
client->rect.height = event->height + (1 + 1);
|
|
||||||
else client->rect.height = event->height + (font->height + 2 + 2) + 2;
|
|
||||||
}
|
}
|
||||||
|
tree_render();
|
||||||
}
|
}
|
||||||
|
|
||||||
DLOG("Accepted new position/size for floating client: (%d, %d) size %d x %d\n",
|
|
||||||
client->rect.x, client->rect.y, client->rect.width, client->rect.height);
|
|
||||||
|
|
||||||
/* Push the new position/size to X11 */
|
|
||||||
reposition_client(conn, client);
|
|
||||||
resize_client(conn, client);
|
|
||||||
xcb_flush(conn);
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
#if 0
|
||||||
|
|
||||||
/* Dock clients can be reconfigured in their height */
|
/* Dock clients can be reconfigured in their height */
|
||||||
if (client->dock) {
|
if (client->dock) {
|
||||||
DLOG("Reconfiguring height of this dock client\n");
|
DLOG("Reconfiguring height of this dock client\n");
|
||||||
|
@ -413,7 +375,9 @@ int handle_configure_request(void *prophs, xcb_connection_t *conn, xcb_configure
|
||||||
fake_absolute_configure_notify(conn, client);
|
fake_absolute_configure_notify(conn, client);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Configuration notifies are only handled because we need to set up ignore for
|
* Configuration notifies are only handled because we need to set up ignore for
|
||||||
|
|
|
@ -218,6 +218,9 @@ int main(int argc, char *argv[]) {
|
||||||
for us is _NET_WM_STATE, we honour _NET_WM_STATE_FULLSCREEN */
|
for us is _NET_WM_STATE, we honour _NET_WM_STATE_FULLSCREEN */
|
||||||
xcb_event_set_client_message_handler(&evenths, handle_client_message, NULL);
|
xcb_event_set_client_message_handler(&evenths, handle_client_message, NULL);
|
||||||
|
|
||||||
|
/* Configure request = window tried to change size on its own */
|
||||||
|
xcb_event_set_configure_request_handler(&evenths, handle_configure_request, NULL);
|
||||||
|
|
||||||
/* Setup NetWM atoms */
|
/* Setup NetWM atoms */
|
||||||
#define GET_ATOM(name) \
|
#define GET_ATOM(name) \
|
||||||
do { \
|
do { \
|
||||||
|
|
|
@ -51,12 +51,8 @@ void render_con(Con *con) {
|
||||||
/* depending on the border style, the rect of the child window
|
/* depending on the border style, the rect of the child window
|
||||||
* needs to be smaller */
|
* needs to be smaller */
|
||||||
Rect *inset = &(con->window_rect);
|
Rect *inset = &(con->window_rect);
|
||||||
|
*inset = (Rect){0, 0, con->rect.width, con->rect.height};
|
||||||
if (con->border_style == BS_NORMAL)
|
*inset = rect_add(*inset, con_border_style_rect(con));
|
||||||
*inset = (Rect){2, 0, con->rect.width - (2 * 2), con->rect.height - 2};
|
|
||||||
else if (con->border_style == BS_1PIXEL)
|
|
||||||
*inset = (Rect){1, 1, con->rect.width - 2, con->rect.height - 1};
|
|
||||||
else *inset = (Rect){0, 0, con->rect.width, con->rect.height};
|
|
||||||
|
|
||||||
/* Obey the aspect ratio, if any */
|
/* Obey the aspect ratio, if any */
|
||||||
if (con->proportional_height != 0 &&
|
if (con->proportional_height != 0 &&
|
||||||
|
|
|
@ -38,6 +38,13 @@ bool rect_contains(Rect rect, uint32_t x, uint32_t y) {
|
||||||
y <= (rect.y + rect.height));
|
y <= (rect.y + rect.height));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Rect rect_add(Rect a, Rect b) {
|
||||||
|
return (Rect){a.x + b.x,
|
||||||
|
a.y + b.y,
|
||||||
|
a.width + b.width,
|
||||||
|
a.height + b.height};
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Updates *destination with new_value and returns true if it was changed or false
|
* Updates *destination with new_value and returns true if it was changed or false
|
||||||
* if it was the same
|
* if it was the same
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
test:
|
test:
|
||||||
PERL_DL_NONLAZY=1 /usr/bin/perl "-MExtUtils::Command::MM" "-e" "test_harness(1)" -It/lib t/34*.t
|
PERL_DL_NONLAZY=1 /usr/bin/perl "-MExtUtils::Command::MM" "-e" "test_harness(1)" -It/lib t/12*.t
|
||||||
|
|
||||||
all: test
|
all: test
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!perl
|
#!perl
|
||||||
# vim:ts=4:sw=4:expandtab
|
# vim:ts=4:sw=4:expandtab
|
||||||
|
|
||||||
use i3test tests => 10;
|
use i3test tests => 11;
|
||||||
use X11::XCB qw(:all);
|
use X11::XCB qw(:all);
|
||||||
use Time::HiRes qw(sleep);
|
use Time::HiRes qw(sleep);
|
||||||
|
|
||||||
|
@ -29,8 +29,8 @@ sleep(0.25);
|
||||||
my ($absolute, $top) = $window->rect;
|
my ($absolute, $top) = $window->rect;
|
||||||
|
|
||||||
ok($window->mapped, 'Window is mapped');
|
ok($window->mapped, 'Window is mapped');
|
||||||
ok($absolute->{width} >= 75, 'i3 raised the width to 75');
|
cmp_ok($absolute->{width}, '>=', 75, 'i3 raised the width to 75');
|
||||||
ok($absolute->{height} >= 50, 'i3 raised the height to 50');
|
cmp_ok($absolute->{height}, '>=', 50, 'i3 raised the height to 50');
|
||||||
|
|
||||||
ok($absolute->{x} != 0 && $absolute->{y} != 0, 'i3 did not map it to (0x0)');
|
ok($absolute->{x} != 0 && $absolute->{y} != 0, 'i3 did not map it to (0x0)');
|
||||||
|
|
||||||
|
@ -51,10 +51,11 @@ sleep(0.25);
|
||||||
|
|
||||||
($absolute, $top) = $window->rect;
|
($absolute, $top) = $window->rect;
|
||||||
|
|
||||||
ok($absolute->{width} == 80, "i3 let the width at 80");
|
cmp_ok($absolute->{width}, '==', 80, "i3 let the width at 80");
|
||||||
ok($absolute->{height} == 90, "i3 let the height at 90");
|
cmp_ok($absolute->{height}, '==', 90, "i3 let the height at 90");
|
||||||
|
|
||||||
ok($top->{x} == 1 && $top->{y} == 1, "i3 mapped it to (1,1)");
|
cmp_ok($top->{x}, '==', 1, 'i3 mapped it to x=1');
|
||||||
|
cmp_ok($top->{y}, '==', 1, 'i3 mapped it to y=1');
|
||||||
|
|
||||||
$window->unmap;
|
$window->unmap;
|
||||||
|
|
||||||
|
|
|
@ -12,9 +12,6 @@ BEGIN {
|
||||||
use_ok('X11::XCB::Connection') or BAIL_OUT('Cannot load X11::XCB::Connection');
|
use_ok('X11::XCB::Connection') or BAIL_OUT('Cannot load X11::XCB::Connection');
|
||||||
}
|
}
|
||||||
|
|
||||||
SKIP: {
|
|
||||||
skip "border styles not yet implemented", 14;
|
|
||||||
|
|
||||||
my $x = X11::XCB::Connection->new;
|
my $x = X11::XCB::Connection->new;
|
||||||
|
|
||||||
my $i3 = i3("/tmp/nestedcons");
|
my $i3 = i3("/tmp/nestedcons");
|
||||||
|
@ -31,7 +28,7 @@ my $window = $x->root->create_child(
|
||||||
rect => [ 0, 0, 30, 30],
|
rect => [ 0, 0, 30, 30],
|
||||||
background_color => '#C0C0C0',
|
background_color => '#C0C0C0',
|
||||||
# replace the type with 'utility' as soon as the coercion works again in X11::XCB
|
# replace the type with 'utility' as soon as the coercion works again in X11::XCB
|
||||||
type => $x->atom(name => '_NET_WM_WINDOW_TYPE_UTILITY'),
|
window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_UTILITY'),
|
||||||
);
|
);
|
||||||
|
|
||||||
isa_ok($window, 'X11::XCB::Window');
|
isa_ok($window, 'X11::XCB::Window');
|
||||||
|
@ -70,13 +67,11 @@ sub test_resize {
|
||||||
test_resize;
|
test_resize;
|
||||||
|
|
||||||
# Test borderless
|
# Test borderless
|
||||||
$i3->command('bb')->recv;
|
$i3->command('border none')->recv;
|
||||||
|
|
||||||
test_resize;
|
test_resize;
|
||||||
|
|
||||||
# Test with 1-px-border
|
# Test with 1-px-border
|
||||||
$i3->command('bp')->recv;
|
$i3->command('border 1pixel')->recv;
|
||||||
|
|
||||||
test_resize;
|
test_resize;
|
||||||
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue