diff --git a/docs/labwc-actions.5.scd b/docs/labwc-actions.5.scd
index 3353fcfa..095a9112 100644
--- a/docs/labwc-actions.5.scd
+++ b/docs/labwc-actions.5.scd
@@ -117,6 +117,17 @@ Actions are used in menus and keyboard/mouse bindings.
upper-left corner of the window associated with the action. Default is
yes.
+**
+ Set decorations of focused window.
+
+ *decorations* [full|border|none] *full* enables the whole server side
+ decorations. With *border*. only the borders and invisible resize area
+ are enabled. *none* disables everything.
+
+ *forceSSD* [yes|no] If this is no, this action will be ignored for
+ windows that have client side decorations if it would increase the
+ amount of decoration. Default is no.
+
**
Toggle decorations of focused window.
diff --git a/include/ssd.h b/include/ssd.h
index 6853a9e5..d91f1122 100644
--- a/include/ssd.h
+++ b/include/ssd.h
@@ -91,6 +91,7 @@ enum ssd_part_type ssd_get_part_type(const struct ssd *ssd,
uint32_t ssd_resize_edges(enum ssd_part_type type);
bool ssd_is_button(enum ssd_part_type type);
bool ssd_part_contains(enum ssd_part_type whole, enum ssd_part_type candidate);
+enum ssd_mode ssd_mode_parse(const char *mode);
/* TODO: clean up / update */
struct border ssd_thickness(struct view *view);
diff --git a/include/view.h b/include/view.h
index f2d1adad..ba675a7c 100644
--- a/include/view.h
+++ b/include/view.h
@@ -478,6 +478,7 @@ bool view_is_floating(struct view *view);
void view_move_to_workspace(struct view *view, struct workspace *workspace);
enum ssd_mode view_get_ssd_mode(struct view *view);
void view_set_ssd_mode(struct view *view, enum ssd_mode mode);
+void view_set_decorations(struct view *view, enum ssd_mode mode, bool force_ssd);
void view_toggle_fullscreen(struct view *view);
void view_invalidate_last_layout_geometry(struct view *view);
void view_adjust_for_layout_change(struct view *view);
diff --git a/src/action.c b/src/action.c
index 7cc4bc56..1a543186 100644
--- a/src/action.c
+++ b/src/action.c
@@ -78,6 +78,7 @@ enum action_type {
ACTION_TYPE_TOGGLE_MAXIMIZE,
ACTION_TYPE_MAXIMIZE,
ACTION_TYPE_TOGGLE_FULLSCREEN,
+ ACTION_TYPE_SET_DECORATIONS,
ACTION_TYPE_TOGGLE_DECORATIONS,
ACTION_TYPE_TOGGLE_ALWAYS_ON_TOP,
ACTION_TYPE_TOGGLE_ALWAYS_ON_BOTTOM,
@@ -131,6 +132,7 @@ const char *action_names[] = {
"ToggleMaximize",
"Maximize",
"ToggleFullscreen",
+ "SetDecorations",
"ToggleDecorations",
"ToggleAlwaysOnTop",
"ToggleAlwaysOnBottom",
@@ -340,6 +342,17 @@ action_arg_from_xml_node(struct action *action, const char *nodename, const char
goto cleanup;
}
break;
+ case ACTION_TYPE_SET_DECORATIONS:
+ if (!strcmp(argument, "decorations")) {
+ enum ssd_mode mode = ssd_mode_parse(content);
+ action_arg_add_int(action, argument, mode);
+ goto cleanup;
+ }
+ if (!strcasecmp(argument, "forceSSD")) {
+ action_arg_add_bool(action, argument, parse_bool(content, false));
+ goto cleanup;
+ }
+ break;
case ACTION_TYPE_RESIZE_RELATIVE:
if (!strcmp(argument, "left") || !strcmp(argument, "right") ||
!strcmp(argument, "top") || !strcmp(argument, "bottom")) {
@@ -785,6 +798,15 @@ actions_run(struct view *activator, struct server *server,
view_toggle_fullscreen(view);
}
break;
+ case ACTION_TYPE_SET_DECORATIONS:
+ if (view) {
+ enum ssd_mode mode = action_get_int(action,
+ "decorations", LAB_SSD_MODE_FULL);
+ bool force_ssd = action_get_bool(action,
+ "forceSSD", false);
+ view_set_decorations(view, mode, force_ssd);
+ }
+ break;
case ACTION_TYPE_TOGGLE_DECORATIONS:
if (view) {
view_toggle_decorations(view);
diff --git a/src/ssd/ssd.c b/src/ssd/ssd.c
index b910ae74..8e382a6a 100644
--- a/src/ssd/ssd.c
+++ b/src/ssd/ssd.c
@@ -7,6 +7,7 @@
*/
#include
+#include
#include "common/mem.h"
#include "common/scene-helpers.h"
#include "labwc.h"
@@ -329,6 +330,21 @@ ssd_part_contains(enum ssd_part_type whole, enum ssd_part_type candidate)
return false;
}
+enum ssd_mode
+ssd_mode_parse(const char *mode)
+{
+ if (!mode) {
+ return LAB_SSD_MODE_FULL;
+ }
+ if (!strcasecmp(mode, "none")) {
+ return LAB_SSD_MODE_NONE;
+ } else if (!strcasecmp(mode, "border")) {
+ return LAB_SSD_MODE_BORDER;
+ } else {
+ return LAB_SSD_MODE_FULL;
+ }
+}
+
void
ssd_set_active(struct ssd *ssd, bool active)
{
diff --git a/src/view.c b/src/view.c
index 54993708..4bed2466 100644
--- a/src/view.c
+++ b/src/view.c
@@ -1234,6 +1234,17 @@ view_wants_decorations(struct view *view)
}
}
+void
+view_set_decorations(struct view *view, enum ssd_mode mode, bool force_ssd)
+{
+ assert(view);
+
+ if (force_ssd || !view_wants_decorations(view)
+ || mode < view_get_ssd_mode(view)) {
+ view_set_ssd_mode(view, mode);
+ }
+}
+
void
view_toggle_decorations(struct view *view)
{