diff --git a/src/floating.c b/src/floating.c index 349056a7..4a2e904f 100644 --- a/src/floating.c +++ b/src/floating.c @@ -98,7 +98,10 @@ void floating_enable(Con *con, bool automatic) { int deco_height = font->height + 5; DLOG("Original rect: (%d, %d) with %d x %d\n", con->rect.x, con->rect.y, con->rect.width, con->rect.height); - nc->rect = con->rect; + nc->rect = con->geometry; + /* Raise the width/height to at least 75x50 (minimum size for windows) */ + nc->rect.width = max(nc->rect.width, 75); + nc->rect.height = max(nc->rect.height, 50); /* add pixels for the decoration */ /* TODO: don’t add them when the user automatically puts new windows into * 1pixel/borderless mode */ diff --git a/src/manage.c b/src/manage.c index c602ee41..cd82d020 100644 --- a/src/manage.c +++ b/src/manage.c @@ -254,16 +254,15 @@ void manage_window(xcb_window_t window, xcb_get_window_attributes_cookie_t cooki if (cwindow->dock) want_floating = false; + /* Store the requested geometry. The width/height gets raised to at least + * 75x50 when entering floating mode, which is the minimum size for a + * window to be useful (smaller windows are usually overlays/toolbars/… + * which are not managed by the wm anyways). We store the original geometry + * here because it’s used for dock clients. */ nc->geometry = (Rect){ geom->x, geom->y, geom->width, geom->height }; if (want_floating) { - nc->rect.x = geom->x; - nc->rect.y = geom->y; - /* We respect the geometry wishes of floating windows, as long as they - * are bigger than our minimal useful size (75x50). */ - nc->rect.width = max(geom->width, 75); - nc->rect.height = max(geom->height, 50); - DLOG("geometry = %d x %d\n", nc->rect.width, nc->rect.height); + DLOG("geometry = %d x %d\n", nc->geometry.width, nc->geometry.height); floating_enable(nc, false); } diff --git a/testcases/t/53-floating-originalsize.t b/testcases/t/53-floating-originalsize.t new file mode 100644 index 00000000..65462e5f --- /dev/null +++ b/testcases/t/53-floating-originalsize.t @@ -0,0 +1,52 @@ +#!perl +# vim:ts=4:sw=4:expandtab +# +# Test if the requested width/height is set after making the window floating. +# +use Time::HiRes qw(sleep); +use X11::XCB qw(:all); +use i3test; + +my $tmp = get_unused_workspace; +cmd "workspace $tmp"; + +my $x = X11::XCB::Connection->new; + +# Create a floating window which is smaller than the minimum enforced size of i3 +my $window = $x->root->create_child( + class => WINDOW_CLASS_INPUT_OUTPUT, + rect => [ 0, 0, 400, 150], + background_color => '#C0C0C0', +); + +isa_ok($window, 'X11::XCB::Window'); + +$window->map; + +sleep 0.25; + +my ($absolute, $top) = $window->rect; + +ok($window->mapped, 'Window is mapped'); +cmp_ok($absolute->{width}, '>', 400, 'i3 raised the width'); +cmp_ok($absolute->{height}, '>', 150, 'i3 raised the height'); + +cmd 'mode toggle'; +sleep 0.25; + +($absolute, $top) = $window->rect; + +diag('new width: ' . $absolute->{width}); +diag('new height: ' . $absolute->{height}); + +# we compare with a tolerance of ± 20 pixels for borders in each direction +# (overkill, but hey) +cmp_ok($absolute->{width}, '>', 400-20, 'width now > 380'); +cmp_ok($absolute->{width}, '<', 400+20, 'width now < 420'); +cmp_ok($absolute->{height}, '>', 150-20, 'height now > 130'); +cmp_ok($absolute->{height}, '<', 150+20, 'height now < 170'); + +#cmp_ok($absolute->{width}, '>=', 75, 'i3 raised the width to 75'); +#cmp_ok($absolute->{height}, '>=', 50, 'i3 raised the height to 50'); + +done_testing;