Skip to content

Commit

Permalink
Add Style CornerLength
Browse files Browse the repository at this point in the history
  Adds a style to set the length of the corners of a window. This style
  takes a single numerical argument and sets the length of the corner
  in number of pixels beyond the edge of the boundary. If the argument
  has a '%' suffix, the number will be treated as a percent of the window
  size instead of a pixel length.

  Note: Corner percent flag is stored as a negative value, due to
  not being able to get flag states to work correctly.
  • Loading branch information
somiaj committed Nov 5, 2023
1 parent 2bfde50 commit ec3e2e8
Show file tree
Hide file tree
Showing 8 changed files with 111 additions and 19 deletions.
20 changes: 14 additions & 6 deletions doc/fvwm3_manpage_source.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -4990,10 +4990,11 @@ style.
_options_ is a comma separated list containing one or more of the
following keywords. Each group of style names is separated by slashes
('/'). The last style in these groups is the default. _BorderWidth_,
_HandleWidth_, _!Icon_ / _Icon_, _MiniIcon_, _IconBox_, _IconGrid_,
_IconFill_, _IconSize_, _!Title_ / _Title_, _TitleAtBottom_ /
_TitleAtLeft_ / _TitleAtRight_ / _TitleAtTop_, _LeftTitleRotatedCW_ /
_LeftTitleRotatedCCW_, _RightTitleRotatedCCW_ / _RightTitleRotatedCW_,
_HandleWidth_, _CornerLength_, _!Icon_ / _Icon_, _MiniIcon_,
_IconBox_, _IconGrid_, _IconFill_, _IconSize_, _!Title_ / _Title_,
_TitleAtBottom_ / _TitleAtLeft_ / _TitleAtRight_ /
_TitleAtTop_, _LeftTitleRotatedCW_ / _LeftTitleRotatedCCW_,
_RightTitleRotatedCCW_ / _RightTitleRotatedCW_,
_TopTitleRotated_ / _TopTitleNotRotated_, _BottomTitleRotated_ /
_BottomTitleNotRotated_, _!UseTitleDecorRotation_ /
_UseTitleDecorRotation_, _StippledTitle_ / _!StippledTitle_,
Expand Down Expand Up @@ -5474,12 +5475,19 @@ but is deprecated.
+
_HandleWidth_ takes a numeric argument which is the width of the
border to place the window if it does have resize-handles. Using
HandleWidth without an argument restores the default.
_HandleWidth_ without an argument restores the default.
+
_CornerLength_ takes a numeric argument which is the length the
corners extend beyond the edge of the border. If the numeric argument
has a suffix of '%', the length will be treated as a percent of the
window size. If the _CornerLength_ exceeds a third of the window length,
it will be reduced to be one third the window length. Using _CornerLength_
without an argument restores the default.
+
_BorderWidth_ takes a numeric argument which is the width of the
border to place the window if it does not have resize-handles. It is
used only if the _!Handles_ style is specified too. Using
BorderWidth without an argument restores the default.
_BorderWidth_ without an argument restores the default.
+
_DepressableBorder_ makes the border parts of the window decoration
look sunken in when a button is pressed over them. This can be
Expand Down
11 changes: 10 additions & 1 deletion fvwm/add_window.c
Original file line number Diff line number Diff line change
Expand Up @@ -1659,6 +1659,7 @@ void setup_title_geometry(
{
int width;
int offset;
style_flags *sflags = &(pstyle->flags);

get_title_font_size_and_offset(
fw, S_TITLE_DIR(SCF(*pstyle)),
Expand All @@ -1669,7 +1670,15 @@ void setup_title_geometry(
&width, &offset);
fw->title_thickness = width;
fw->title_text_offset = offset;
fw->corner_width = fw->title_thickness + fw->boundary_width;
fw->corner_length = fw->title_thickness + fw->boundary_width;
if (SHAS_CORNER_LENGTH(sflags))
{
fw->corner_length = SGET_CORNER_LENGTH(*pstyle);
if (fw->corner_length > 0)
{
fw->corner_length += fw->boundary_width;
}
}
if (!HAS_TITLE(fw))
{
fw->title_thickness = 0;
Expand Down
11 changes: 7 additions & 4 deletions fvwm/borders.c
Original file line number Diff line number Diff line change
Expand Up @@ -1765,6 +1765,7 @@ static void border_draw_one_border_part(
Pixmap p;
Window w;
Bool free_bg_pixmap = False;
int corner_w, corner_h;

/* make a pixmap */
border_get_part_geometry(fw, part, sidebar_g, &part_g, &w);
Expand All @@ -1780,6 +1781,8 @@ static void border_draw_one_border_part(
relative_g.y = part_g.y;
border_get_border_background(
&bg, cd, &part_g, &relative_g, &free_bg_pixmap, w, part);
frame_set_corner_length(
fw, &corner_w, &corner_h, frame_g->width, frame_g->height);
if (cd->texture_pixmap)
{
switch (part)
Expand All @@ -1789,11 +1792,11 @@ static void border_draw_one_border_part(
break;
case PART_BORDER_NE:
case PART_BORDER_SE:
bg.pixmap.g.x = frame_g->width - fw->corner_width;
bg.pixmap.g.x = frame_g->width - corner_w;
break;
case PART_BORDER_N:
case PART_BORDER_S:
bg.pixmap.g.x = fw->corner_width;
bg.pixmap.g.x = corner_w;
break;
default:
bg.pixmap.g.x = 0;
Expand All @@ -1806,11 +1809,11 @@ static void border_draw_one_border_part(
break;
case PART_BORDER_SW:
case PART_BORDER_SE:
bg.pixmap.g.y = frame_g->height - fw->corner_width;
bg.pixmap.g.y = frame_g->height - corner_h;
break;
case PART_BORDER_W:
case PART_BORDER_E:
bg.pixmap.g.y = fw->corner_width;
bg.pixmap.g.y = corner_h;
break;
default:
bg.pixmap.g.y = 0;
Expand Down
42 changes: 36 additions & 6 deletions fvwm/frame.c
Original file line number Diff line number Diff line change
Expand Up @@ -1531,11 +1531,40 @@ void frame_get_titlebar_dimensions(
return;
}

#define MIN_SIZE 4
void frame_set_corner_length(
FvwmWindow *fw, int *width, int *height, int frame_w, int frame_h)
{
*width = fw->corner_length;
*height = fw->corner_length;

/* Negative values mean treat as a percent length. */
if (*width < 0) {
*width *= -frame_w / 100;
*height *= -frame_h / 100;
}

/* Ensure a minimum/maximize size. */
int min_l = fw->title_thickness + fw->boundary_width;
if (frame_w > MIN_SIZE && *width > frame_w / 2 - MIN_SIZE) {
*width = frame_w / 2 - MIN_SIZE;
}
if (*width < min_l) {
*width = min_l;
}
if (frame_h > MIN_SIZE && *height > frame_h / 2 - MIN_SIZE) {
*height = frame_h / 2 - MIN_SIZE;
}
if (*height < min_l) {
*height = min_l;
}
}

void frame_get_sidebar_geometry(
FvwmWindow *fw, DecorFaceStyle *borderstyle, rectangle *frame_g,
rectangle *ret_g, Bool *ret_has_x_marks, Bool *ret_has_y_marks)
{
int min_w;
int min_l;
size_borders b;

ret_g->x = 0;
Expand Down Expand Up @@ -1570,16 +1599,16 @@ void frame_get_sidebar_geometry(
*ret_has_x_marks = True;
*ret_has_y_marks = True;
}
ret_g->x = fw->corner_width;
ret_g->y = fw->corner_width;
min_w = 2 * fw->corner_width + 4;
frame_set_corner_length(
fw, &ret_g->x, &ret_g->y, frame_g->width, frame_g->height);
/* limit by available space, remove handle marks if necessary */
if (frame_g->width < min_w)
min_l = 2*(fw->title_thickness + fw->boundary_width) + MIN_SIZE;
if (frame_g->width < min_l)
{
ret_g->x = frame_g->width / 3;
*ret_has_y_marks = False;
}
if (frame_g->height < min_w)
if (frame_g->height < min_l)
{
ret_g->y = frame_g->height / 3;
*ret_has_x_marks = False;
Expand All @@ -1599,6 +1628,7 @@ void frame_get_sidebar_geometry(

return;
}
#undef MIN_SIZE

int frame_window_id_to_context(
FvwmWindow *fw, Window w, int *ret_num)
Expand Down
2 changes: 2 additions & 0 deletions fvwm/frame.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ void frame_free_move_resize_args(
void frame_get_titlebar_dimensions(
FvwmWindow *fw, rectangle *frame_g, rectangle *diff_g,
frame_title_layout_t *title_layout);
void frame_set_corner_length(
FvwmWindow *fw, int *width, int *height, int frame_w, int frame_h);
void frame_get_sidebar_geometry(
FvwmWindow *fw, DecorFaceStyle *borderstyle, rectangle *frame_g,
rectangle *ret_g, Bool *ret_has_x_marks, Bool *ret_has_y_marks);
Expand Down
5 changes: 3 additions & 2 deletions fvwm/fvwm.h
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,7 @@ typedef struct style_flags
unsigned has_edge_resistance_move : 1;
unsigned has_edge_resistance_screen_move : 1;
unsigned has_handle_width : 1;
unsigned has_corner_length : 1;
unsigned has_icon : 1;
unsigned has_icon_boxes : 1;
unsigned has_icon_size_limits : 1;
Expand Down Expand Up @@ -637,6 +638,7 @@ typedef struct window_style
short border_width;
/* resize handle width */
short handle_width;
short corner_length;
int layer;
int start_desk;
int start_page_x;
Expand Down Expand Up @@ -764,8 +766,7 @@ typedef struct FvwmWindow
* CONFIGARGSNEW macro in module_interface.c, libs/vpacket.h too! */
short boundary_width;
short unshaped_boundary_width;
short corner_width;
short visual_corner_width;
short corner_length;

/* title font */
FlocaleFont *title_font;
Expand Down
33 changes: 33 additions & 0 deletions fvwm/style.c
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,11 @@ static void merge_styles(
SSET_HANDLE_WIDTH(
*merged_style, SGET_HANDLE_WIDTH(*add_style));
}
if (add_style->flags.has_corner_length)
{
SSET_CORNER_LENGTH(
*merged_style, SGET_CORNER_LENGTH(*add_style));
}
if (add_style->flags.has_icon_size_limits)
{
SSET_MIN_ICON_WIDTH(
Expand Down Expand Up @@ -2349,6 +2354,28 @@ static Bool style_parse_one_style_option(
S_SET_IS_UNCLOSABLE(SCM(*ps), 1);
S_SET_IS_UNCLOSABLE(SCC(*ps), 1);
}
else if (StrEquals(token, "CornerLength"))
{
int num;
num = GetSuffixedIntegerArguments(
rest, &rest, val, 1, "%", tmpno);

if (num > 0 && *val >= 0)
{
SSET_CORNER_LENGTH(*ps, (short)*val);
ps->flags.has_corner_length = 1;
/* Percent lengths are stored as negative values. */
if (*tmpno == 1) {
SSET_CORNER_LENGTH(*ps, -(short)*val);
}
}
else
{
ps->flags.has_corner_length = 0;
}
ps->flag_mask.has_corner_length = 1;
ps->change_mask.has_corner_length = 1;
}
else
{
found = False;
Expand Down Expand Up @@ -4988,6 +5015,12 @@ void check_window_style_change(
flags->do_update_modules_flags = 1;
}

/* has_corner_length */
if (ret_style->change_mask.has_corner_length)
{
flags->do_redecorate = 1;
}

if (ret_style->change_mask.do_save_under ||
ret_style->change_mask.use_backing_store ||
ret_style->change_mask.use_parent_relative)
Expand Down
6 changes: 6 additions & 0 deletions fvwm/style.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
((sf)->has_border_width)
#define SHAS_HANDLE_WIDTH(sf) \
((sf)->has_handle_width)
#define SHAS_CORNER_LENGTH(sf) \
((sf)->has_corner_length)
#define SHAS_ICON(sf) \
((sf)->has_icon)
#define SHAS_ICON_BOXES(sf) \
Expand Down Expand Up @@ -468,6 +470,10 @@
((s).handle_width)
#define SSET_HANDLE_WIDTH(s,x) \
((s).handle_width = (x))
#define SGET_CORNER_LENGTH(s) \
((s).corner_length)
#define SSET_CORNER_LENGTH(s,x) \
((s).corner_length = (x))
#define SGET_LAYER(s) \
((s).layer)
#define SSET_LAYER(s,x) \
Expand Down

0 comments on commit ec3e2e8

Please sign in to comment.