Confusing feedback from xfwm4 when resizing a window with an increment hint for one axis, but a fixed size for the other axis
Submitted by Sam Varshavchik
Description
When resizing a window whose WM_NORMAL_HINTS specify an explicit size increment, xfwm4 tries to provide a visual feedback on the window's size in rows and columns, computed based on the window's base size, the indicated horizontal and vertical increments, and the current pixel size.
For example, when a window's size is 200x100 pixels, and the window specifies a horizontal increment of 10 and a vertical increment of 10, and a base size of 0x0, xfwm4 computes the window's size as 20 columns by 10 rows and shows a small "20x10" label in the middle of the window. This label gets updated, each time the window's size gets dragged (in increments of 10 pixels in each direction).
However, a window can be resizable only in one dimension. For example, a window may specify both a minimum and a maximum height of 100 pixels, but some horizontal range, ranging from a minimum to a maximum value. This sets a fixed height that cannot be adjusted, but an adjustable width.
In this case, xfwm4 shows a rather confusing label, claiming that this window's size is "20x0", "21x0", "22x0", etc...
Here's a small test program that creates a window of a fixed height, but which can be resized horizontally, across a modest range. Using the window's right border the window's width is adjustable, but with xfwm4 showing this confusing label.
Compile and link with -lxcb -lxcb-icccm
:
#include <xcb/xproto.h>
#include <xcb/xcb_icccm.h>
#include <stdio.h>
#include <string.h>
int main ()
{
xcb_connection_t *connection = xcb_connect (NULL, NULL);
const xcb_setup_t *setup = xcb_get_setup (connection);
xcb_screen_iterator_t iter = xcb_setup_roots_iterator (setup);
xcb_screen_t *screen = iter.data;
xcb_size_hints_t hints;
xcb_window_t window = xcb_generate_id (connection);
xcb_create_window (connection,
XCB_COPY_FROM_PARENT,
window,
screen->root,
0, 0,
150, 150,
10,
XCB_WINDOW_CLASS_INPUT_OUTPUT,
screen->root_visual,
0, NULL );
static const char wm_normal_hints[]="WM_NORMAL_HINTS";
xcb_map_window (connection, window);
memset(&hints, 0, sizeof(hints));
/*
** Minimum size 20x150, maximum size 250x150.
**
** The window's height is fixed at 150 pixels.
*/
xcb_icccm_size_hints_set_min_size(&hints, 20, 150);
xcb_icccm_size_hints_set_max_size(&hints, 250, 150);
/* Base size is same as minimum size */
xcb_icccm_size_hints_set_base_size(&hints, 20, 150);
/*
** We can scroll by 10 pixels horizontally
**
** Tried setting vertical scrolling increment to either 0 or 1,
** makes no difference.
*/
xcb_icccm_size_hints_set_resize_inc(&hints, 10, 1);
xcb_icccm_set_wm_size_hints
(connection,
window,
xcb_intern_atom_reply(connection,
xcb_intern_atom(connection, 0,
strlen(wm_normal_hints),
wm_normal_hints),
0)->atom,
&hints);
xcb_flush (connection);
fgetc(stdin);
xcb_disconnect (connection);
return 0;
}