Skip to content

Commit

Permalink
Allow Min/Max WindowSize style to use client size
Browse files Browse the repository at this point in the history
Adds the option to the MinWindowSize and MaxWindowSize style to state the
size in terms of the clients size increment hints by using the suffix 'c'.
For example to give xterm minimum size to be 80x24 use.

Style xterm MinWindowSize 80c 24c

Fixes #145
  • Loading branch information
somiaj committed Jun 25, 2021
1 parent 1fe936a commit 1307d72
Show file tree
Hide file tree
Showing 6 changed files with 170 additions and 76 deletions.
37 changes: 21 additions & 16 deletions doc/fvwm3/fvwm3.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -6140,22 +6140,27 @@ character size in many applications). This can be handy for broken
applications that refuse to be resized. Do not use it if you do not
need it. The default (opposite) style is _NoResizeOverride_.
+
_MinWindowSize [ width [ p ] height [ p ] ]_ Tells fvwm the minimum
width and height of a window. The values are the percentage of the
total screen area. If the letter '_p_' is appended to either of the
values, the numbers are interpreted as pixels. This command is useful
for certain versions of xemacs which freak out if their windows become
too small. If you omit he parameters or their values are invalid, both
limits are set to 0 pixels (which is the default value).
+
_MaxWindowSize [ width [ p ] height [ p ] ]_ Tells fvwm the maximum
width and height of a window. The values are the percentage of the
total screen area. If the letter '_p_' is appended to either of the
values, the numbers are interpreted as pixels. This command is useful
to force large application windows to be fully visible. Neither
_height_ nor _width_ may be less than 100 pixels. If you omit the
parameters or their values are invalid, both limits are set to 32767
pixels (which is the default).
_MinWindowSize [ width [ p | c ] height [ p | c ] ]_ Tells fvwm the
minimum width and height of a window. The values are the percentage of
the total screen area. If the letter '_p_' is appended to either of the
values, the numbers are interpreted as pixels. If the letter '_c_' is
appended to either of the values, the numbers are in terms of the client
window's size hints, which can be useful for windows such as terminals to
specify the number of rows or columns. This command is useful to deal with
windows that freak out if their window becomes too small. If you omit the
parameters or their values are invalid, both limits are set to 0 pixels
(which is the default value).
+
_MaxWindowSize [ width [ p | c ] height [ p | c ] ]_ Tells fvwm the
maximum width and height of a window. The values are the percentage of
the total screen area. If the letter '_p_' is appended to either of the
values, the numbers are interpreted as pixels. If the letter '_c_' is
appended to either of the values, the numbers are in terms of the client
window's size hints, which can be useful for windows such as terminals to
specify the number of rows or columns. This command is useful to force
large application windows to be fully visible. Neither _height_ nor _width_
may be less than 100 pixels. If you omit the parameters or their values
are invalid, both limits are set to 32767 pixels (which is the default).
+
With _IconifyWindowGroups_ all windows in the same window group are
iconified and deiconified at once when any window in the group is
Expand Down
22 changes: 22 additions & 0 deletions fvwm/add_window.c
Original file line number Diff line number Diff line change
Expand Up @@ -2095,7 +2095,13 @@ void setup_frame_size_limits(FvwmWindow *fw, window_style *pstyle)
if (SHAS_MIN_WINDOW_SIZE(&pstyle->flags))
{
fw->min_window_width = SGET_MIN_WINDOW_WIDTH(*pstyle);
if (SGET_MIN_WINDOW_WIDTH_IS_C(*pstyle))
fw->min_window_width = fw->min_window_width *
fw->hints.width_inc + fw->hints.base_width;
fw->min_window_height = SGET_MIN_WINDOW_HEIGHT(*pstyle);
if (SGET_MIN_WINDOW_HEIGHT_IS_C(*pstyle))
fw->min_window_height = fw->min_window_width *
fw->hints.height_inc + fw->hints.base_height;
}
else
{
Expand All @@ -2105,7 +2111,23 @@ void setup_frame_size_limits(FvwmWindow *fw, window_style *pstyle)
if (SHAS_MAX_WINDOW_SIZE(&pstyle->flags))
{
fw->max_window_width = SGET_MAX_WINDOW_WIDTH(*pstyle);
if (SGET_MAX_WINDOW_WIDTH_IS_C(*pstyle))
fw->max_window_width = fw->max_window_width *
fw->hints.width_inc + fw->hints.base_width;
fw->max_window_height = SGET_MAX_WINDOW_HEIGHT(*pstyle);
if (SGET_MAX_WINDOW_HEIGHT_IS_C(*pstyle))
fw->max_window_height = fw->max_window_height *
fw->hints.height_inc + fw->hints.base_height;

/* Checking size now that the client window is known. */
if (fw->max_window_width < DEFAULT_MIN_MAX_WINDOW_WIDTH)
fw->max_window_width = DEFAULT_MIN_MAX_WINDOW_WIDTH;
if (fw->max_window_width > DEFAULT_MAX_MAX_WINDOW_WIDTH)
fw->max_window_width = DEFAULT_MAX_MAX_WINDOW_WIDTH;
if (fw->max_window_height < DEFAULT_MIN_MAX_WINDOW_HEIGHT)
fw->max_window_height = DEFAULT_MIN_MAX_WINDOW_HEIGHT;
if (fw->max_window_width > DEFAULT_MAX_MAX_WINDOW_HEIGHT)
fw->max_window_height = DEFAULT_MAX_MAX_WINDOW_HEIGHT;
}
else
{
Expand Down
5 changes: 5 additions & 0 deletions fvwm/fvwm.h
Original file line number Diff line number Diff line change
Expand Up @@ -680,6 +680,11 @@ typedef struct window_style
int min_window_height;
int max_window_width;
int max_window_height;
/* sizes are in terms of client window size hints */
bool min_window_width_is_c;
bool min_window_height_is_c;
bool max_window_width_is_c;
bool max_window_height_is_c;
int shade_anim_steps;
#if 1 /*!!!*/
snap_attraction_t snap_attraction;
Expand Down
29 changes: 19 additions & 10 deletions fvwm/geometry.c
Original file line number Diff line number Diff line change
Expand Up @@ -827,6 +827,8 @@ void constrain_size(
FvwmWindow *fw, const XEvent *e, int *widthp, int *heightp,
int xmotion, int ymotion, int flags)
{
int tmp;
window_style style;
size_rect min;
size_rect max;
size_rect inc;
Expand Down Expand Up @@ -863,28 +865,35 @@ void constrain_size(
d.width -= b.total_size.width;
d.height -= b.total_size.height;

/* Need to know if using client size for Min/Max WindowSize
* styles to decided if border width is included in the size.
*/
lookup_style(fw, &style);

min.width = fw->hints.min_width;
min.height = fw->hints.min_height;
if (min.width < fw->min_window_width - b.total_size.width)
tmp = SGET_MIN_WINDOW_WIDTH_IS_C(style) ? 0 : b.total_size.width;
if (min.width < fw->min_window_width - tmp)
{
min.width = fw->min_window_width - b.total_size.width;
min.width = fw->min_window_width - tmp;
}
if (min.height < fw->min_window_height - b.total_size.height)
tmp = SGET_MIN_WINDOW_HEIGHT_IS_C(style) ? 0 : b.total_size.height;
if (min.height < fw->min_window_height - tmp)
{
min.height =
fw->min_window_height - b.total_size.height;
min.height = fw->min_window_height - tmp;
}

max.width = fw->hints.max_width;
max.height = fw->hints.max_height;
if (max.width > fw->max_window_width - b.total_size.width)
tmp = SGET_MAX_WINDOW_WIDTH_IS_C(style) ? 0 : b.total_size.width;
if (max.width > fw->max_window_width - tmp)
{
max.width = fw->max_window_width - b.total_size.width;
max.width = fw->max_window_width - tmp;
}
if (max.height > fw->max_window_height - b.total_size.height)
tmp = SGET_MAX_WINDOW_HEIGHT_IS_C(style) ? 0 : b.total_size.height;
if (max.height > fw->max_window_height - tmp)
{
max.height =
fw->max_window_height - b.total_size.height;
max.height = fw->max_window_height - tmp;
}

if (min.width > max.width)
Expand Down
137 changes: 87 additions & 50 deletions fvwm/style.c
Original file line number Diff line number Diff line change
Expand Up @@ -551,15 +551,23 @@ static void merge_styles(
{
SSET_MIN_WINDOW_WIDTH(
*merged_style, SGET_MIN_WINDOW_WIDTH(*add_style));
SSET_MIN_WINDOW_WIDTH_IS_C(
*merged_style, SGET_MIN_WINDOW_WIDTH_IS_C(*add_style));
SSET_MIN_WINDOW_HEIGHT(
*merged_style, SGET_MIN_WINDOW_HEIGHT(*add_style));
SSET_MIN_WINDOW_HEIGHT_IS_C(
*merged_style, SGET_MIN_WINDOW_HEIGHT_IS_C(*add_style));
}
if (add_style->flags.has_max_window_size)
{
SSET_MAX_WINDOW_WIDTH(
*merged_style, SGET_MAX_WINDOW_WIDTH(*add_style));
SSET_MAX_WINDOW_WIDTH_IS_C(
*merged_style, SGET_MAX_WINDOW_WIDTH_IS_C(*add_style));
SSET_MAX_WINDOW_HEIGHT(
*merged_style, SGET_MAX_WINDOW_HEIGHT(*add_style));
SSET_MAX_WINDOW_HEIGHT_IS_C(
*merged_style, SGET_MAX_WINDOW_HEIGHT_IS_C(*add_style));
}
if (add_style->flags.has_icon_background_relief)
{
Expand Down Expand Up @@ -3426,76 +3434,105 @@ static Bool style_parse_one_style_option(
}
else if (StrEquals(token, "MinWindowSize"))
{
int val1;
int val2;
int val1_unit;
int val2_unit;
int units[2] = {100, 100};
int mondim[2];
bool use_client[2] = {false, false};

num = GetTwoArguments(
rest, &val1, &val2, &val1_unit, &val2_unit);
rest = SkipNTokens(rest, num);
mondim[0] = monitor_get_all_widths();
mondim[1] = monitor_get_all_heights();

num = GetSuffixedIntegerArguments(
rest, &rest, val, 2, "pc", tmpno);
if (num != 2)
{
val1 = 0;
val2 = 0;
val[0] = 0;
val[1] = 0;
}
else
{
val1 = val1 * val1_unit / 100;
val2 = val2 * val2_unit / 100;
}
if (val1 < 0)
{
val1 = 0;
}
if (val2 < 0)
{
val2 = 0;
for (i = 0; i < 2; i++)
{
switch (tmpno[i])
{
case 0: /* no suffix */
units[i] = mondim[i];
break;
case 1: /* p suffix */
break;
case 2: /* c suffix */
use_client[i] = true;
break;
default: /* shouldn't happen */
val[i] = 0;
break;
}
val[i] = val[i] * units[i] / 100;
if (val[i] < 0)
{
val[i] = 0;
use_client[i] = false;
}
}
}
SSET_MIN_WINDOW_WIDTH(*ps, val1);
SSET_MIN_WINDOW_HEIGHT(*ps, val2);
SSET_MIN_WINDOW_WIDTH(*ps, val[0]);
SSET_MIN_WINDOW_WIDTH_IS_C(*ps, use_client[0]);
SSET_MIN_WINDOW_HEIGHT(*ps, val[1]);
SSET_MIN_WINDOW_HEIGHT_IS_C(*ps, use_client[1]);
ps->flags.has_min_window_size = 1;
ps->flag_mask.has_min_window_size = 1;
ps->change_mask.has_min_window_size = 1;
}
else if (StrEquals(token, "MaxWindowSize"))
{
int val1;
int val2;
int val1_unit;
int val2_unit;
int units[2] = {100, 100};
int mondim[2];
bool use_client[2] = {false, false};
int maxsize[2] = {DEFAULT_MAX_MAX_WINDOW_WIDTH,
DEFAULT_MAX_MAX_WINDOW_HEIGHT};

mondim[0] = monitor_get_all_widths();
mondim[1] = monitor_get_all_heights();

num = GetTwoArguments(
rest, &val1, &val2, &val1_unit, &val2_unit);
rest = SkipNTokens(rest, num);
num = GetSuffixedIntegerArguments(
rest, &rest, val, 2, "pc", tmpno);
if (num != 2)
{
val1 = DEFAULT_MAX_MAX_WINDOW_WIDTH;
val2 = DEFAULT_MAX_MAX_WINDOW_HEIGHT;
val[0] = DEFAULT_MAX_MAX_WINDOW_WIDTH;
val[1] = DEFAULT_MAX_MAX_WINDOW_HEIGHT;
}
else
{
val1 = val1 * val1_unit / 100;
val2 = val2 * val2_unit / 100;
}
if (val1 < DEFAULT_MIN_MAX_WINDOW_WIDTH)
{
val1 = DEFAULT_MIN_MAX_WINDOW_WIDTH;
}
if (val1 > DEFAULT_MAX_MAX_WINDOW_WIDTH || val1 <= 0)
{
val1 = DEFAULT_MAX_MAX_WINDOW_WIDTH;
}
if (val2 < DEFAULT_MIN_MAX_WINDOW_HEIGHT)
{
val2 = DEFAULT_MIN_MAX_WINDOW_HEIGHT;
}
if (val2 > DEFAULT_MAX_MAX_WINDOW_HEIGHT || val2 <= 0)
{
val2 = DEFAULT_MAX_MAX_WINDOW_HEIGHT;
for (i = 0; i < 2; i++)
{
switch (tmpno[i])
{
case 0: /* no suffix */
units[i] = mondim[i];
break;
case 1: /* p suffix */
break;
case 2: /* c suffix */
use_client[i] = true;
break;
default: /* shouldn't happen */
val[i] = 0;
break;
}
val[i] = val[i] * units[i] / 100;
/* Actual check is done later once the
* size of the client window is known.
*/
if (val[i] < 1 || val[i] > maxsize[i])
{
val[i] = maxsize[i];
use_client[i] = false;
}
}
}
SSET_MAX_WINDOW_WIDTH(*ps, val1);
SSET_MAX_WINDOW_HEIGHT(*ps, val2);
SSET_MAX_WINDOW_WIDTH(*ps, val[0]);
SSET_MAX_WINDOW_WIDTH_IS_C(*ps, use_client[0]);
SSET_MAX_WINDOW_HEIGHT(*ps, val[1]);
SSET_MAX_WINDOW_HEIGHT_IS_C(*ps, use_client[1]);
ps->flags.has_max_window_size = 1;
ps->flag_mask.has_max_window_size = 1;
ps->change_mask.has_max_window_size = 1;
Expand Down
16 changes: 16 additions & 0 deletions fvwm/style.h
Original file line number Diff line number Diff line change
Expand Up @@ -546,20 +546,36 @@
((s).icon_title_relief = (x))
#define SGET_MIN_WINDOW_WIDTH(s) \
((s).min_window_width)
#define SGET_MIN_WINDOW_WIDTH_IS_C(s) \
((s).min_window_width_is_c)
#define SSET_MIN_WINDOW_WIDTH(s,x) \
((s).min_window_width = (x))
#define SSET_MIN_WINDOW_WIDTH_IS_C(s,x) \
((s).min_window_width_is_c = (x))
#define SGET_MAX_WINDOW_WIDTH(s) \
((s).max_window_width)
#define SGET_MAX_WINDOW_WIDTH_IS_C(s) \
((s).max_window_width_is_c)
#define SSET_MAX_WINDOW_WIDTH(s,x) \
((s).max_window_width = (x))
#define SSET_MAX_WINDOW_WIDTH_IS_C(s,x) \
((s).max_window_width_is_c = (x))
#define SGET_MIN_WINDOW_HEIGHT(s) \
((s).min_window_height)
#define SGET_MIN_WINDOW_HEIGHT_IS_C(s) \
((s).min_window_height_is_c)
#define SSET_MIN_WINDOW_HEIGHT(s,x) \
((s).min_window_height = (x))
#define SSET_MIN_WINDOW_HEIGHT_IS_C(s,x) \
((s).min_window_height_is_c = (x))
#define SGET_MAX_WINDOW_HEIGHT(s) \
((s).max_window_height)
#define SGET_MAX_WINDOW_HEIGHT_IS_C(s) \
((s).max_window_height_is_c)
#define SSET_MAX_WINDOW_HEIGHT(s,x) \
((s).max_window_height = (x))
#define SSET_MAX_WINDOW_HEIGHT_IS_C(s,x) \
((s).max_window_height_is_c = (x))
#define SGET_WINDOW_SHADE_STEPS(s) \
((s).shade_anim_steps)
#define SSET_WINDOW_SHADE_STEPS(s,x) \
Expand Down

0 comments on commit 1307d72

Please sign in to comment.