<xsd:element minOccurs="0" name="here" type="ob:bool"/>
<xsd:element minOccurs="0" name="linear" type="ob:bool"/>
<xsd:element minOccurs="0" name="group" type="ob:bool"/>
+ <xsd:element minOccurs="0" name="strict" type="ob:bool"/>
</xsd:all>
<xsd:attribute name="name" type="ob:actionname" use="required"/>
</xsd:complexType>
#include "openbox/actions.h"
#include "openbox/screen.h"
+typedef struct {
+ /* If true, windows are unable to be shown while in the showing-desktop
+ state. */
+ gboolean strict;
+} Options;
+
+static gpointer setup_func(xmlNodePtr node);
+static void free_func(gpointer o);
static gboolean run_func(ObActionsData *data, gpointer options);
void action_showdesktop_startup(void)
{
- actions_register("ToggleShowDesktop", NULL, NULL, run_func);
+ actions_register("ToggleShowDesktop", setup_func, free_func, run_func);
+}
+
+static gpointer setup_func(xmlNodePtr node)
+{
+ xmlNodePtr n;
+ Options *o = g_slice_new0(Options);
+ o->strict = FALSE;
+
+ if ((n = obt_xml_find_node(node, "strict")))
+ o->strict = obt_xml_node_bool(n);
+
+ return o;
+}
+
+static void free_func(gpointer o)
+{
+ g_slice_free(Options, o);
}
/* Always return FALSE because its not interactive */
static gboolean run_func(ObActionsData *data, gpointer options)
{
- screen_show_desktop(!screen_showing_desktop, NULL);
+ Options *o = options;
+
+ ObScreenShowDestopMode show_mode;
+ if (screen_showing_desktop())
+ show_mode = SCREEN_SHOW_DESKTOP_NO;
+ else if (!o->strict)
+ show_mode = SCREEN_SHOW_DESKTOP_UNTIL_WINDOW;
+ else
+ show_mode = SCREEN_SHOW_DESKTOP_UNTIL_TOGGLE;
+
+ screen_show_desktop(show_mode, NULL);
return FALSE;
}
{
if (self->iconic)
return FALSE;
- if (client_normal(self) && screen_showing_desktop)
+ if (client_normal(self) && screen_showing_desktop())
return FALSE;
if (self->desktop == screen_desktop || self->desktop == DESKTOP_ALL)
return TRUE;
static void client_present(ObClient *self, gboolean here, gboolean raise,
gboolean unshade)
{
- if (client_normal(self) && screen_showing_desktop)
+ if (client_normal(self) && screen_showing_desktop())
screen_show_desktop(FALSE, self);
if (self->iconic)
client_iconify(self, FALSE, here, FALSE);
if (d > 0 && d <= 1000)
screen_set_num_desktops(d);
} else if (msgtype == OBT_PROP_ATOM(NET_SHOWING_DESKTOP)) {
- screen_show_desktop(e->xclient.data.l[0] != 0, NULL);
+ ObScreenShowDestopMode show_mode;
+ if (e->xclient.data.l[0] != 0)
+ show_mode = SCREEN_SHOW_DESKTOP_UNTIL_WINDOW;
+ else
+ show_mode = SCREEN_SHOW_DESKTOP_NO;
+ screen_show_desktop(show_mode, NULL);
} else if (msgtype == OBT_PROP_ATOM(OB_CONTROL)) {
ob_debug("OB_CONTROL: %d", e->xclient.data.l[0]);
if (e->xclient.data.l[0] == 1)
GSList* potential_overlap_clients = NULL;
gint n_client_rects = config_dock_hide ? 0 : 1;
- /* if we're "showing desktop", ignore all existing windows */
- if (!screen_showing_desktop) {
+ /* If we're "showing desktop", and going to allow this window to
+ be shown now, then ignore all existing windows */
+ gboolean ignore_windows = FALSE;
+ switch (screen_show_desktop_mode) {
+ case SCREEN_SHOW_DESKTOP_NO:
+ case SCREEN_SHOW_DESKTOP_UNTIL_WINDOW:
+ break;
+ case SCREEN_SHOW_DESKTOP_UNTIL_TOGGLE:
+ ignore_windows = TRUE;
+ break;
+ }
+
+ if (!ignore_windows) {
GList* it;
for (it = client_list; it != NULL; it = g_list_next(it)) {
ObClient* maybe_client = (ObClient*)it->data;
static void screen_tell_ksplash(void);
static void screen_fallback_focus(void);
-guint screen_num_desktops;
-guint screen_num_monitors;
-guint screen_desktop;
-guint screen_last_desktop;
-gboolean screen_showing_desktop;
-ObDesktopLayout screen_desktop_layout;
-gchar **screen_desktop_names;
-Window screen_support_win;
-Time screen_desktop_user_time = CurrentTime;
+guint screen_num_desktops;
+guint screen_num_monitors;
+guint screen_desktop;
+guint screen_last_desktop;
+ObScreenShowDestopMode screen_show_desktop_mode;
+ObDesktopLayout screen_desktop_layout;
+gchar **screen_desktop_names;
+Window screen_support_win;
+Time screen_desktop_user_time = CurrentTime;
static Size screen_physical_size;
static guint screen_old_desktop;
screen_last_desktop = screen_desktop;
/* don't start in showing-desktop mode */
- screen_showing_desktop = FALSE;
+ screen_show_desktop_mode = SCREEN_SHOW_DESKTOP_NO;
OBT_PROP_SET32(obt_root(ob_screen),
- NET_SHOWING_DESKTOP, CARDINAL, screen_showing_desktop);
+ NET_SHOWING_DESKTOP, CARDINAL, screen_showing_desktop());
if (session_desktop_layout_present &&
screen_validate_layout(&session_desktop_layout))
screen_num_desktops);
}
-void screen_show_desktop(gboolean show, ObClient *show_only)
+void screen_show_desktop(ObScreenShowDestopMode show_mode, ObClient *show_only)
{
GList *it;
- if (show == screen_showing_desktop) return; /* no change */
+ ObScreenShowDestopMode before_mode = screen_show_desktop_mode;
- screen_showing_desktop = show;
+ gboolean showing_before = screen_showing_desktop();
+ screen_show_desktop_mode = show_mode;
+ gboolean showing_after = screen_showing_desktop();
- if (show) {
+ if (showing_before == showing_after) {
+ /* No change. */
+ screen_show_desktop_mode = before_mode;
+ return;
+ }
+
+ if (screen_show_desktop_mode == SCREEN_SHOW_DESKTOP_UNTIL_TOGGLE &&
+ show_only != NULL)
+ {
+ /* If we're showing the desktop until the show-mode is toggled, we
+ don't allow breaking out of showing-desktop mode unless we're
+ showing all the windows again. */
+ screen_show_desktop_mode = before_mode;
+ return;
+ }
+
+ if (showing_after) {
/* hide windows bottom to top */
for (it = g_list_last(stacking_list); it; it = g_list_previous(it)) {
if (WINDOW_IS_CLIENT(it->data)) {
}
}
- if (show) {
+ if (showing_after) {
/* focus the desktop */
for (it = focus_order; it; it = g_list_next(it)) {
ObClient *c = it->data;
}
}
- show = !!show; /* make it boolean */
- OBT_PROP_SET32(obt_root(ob_screen), NET_SHOWING_DESKTOP, CARDINAL, show);
+ OBT_PROP_SET32(obt_root(ob_screen),
+ NET_SHOWING_DESKTOP,
+ CARDINAL,
+ !!showing_after);
+}
+
+gboolean screen_showing_desktop()
+{
+ switch (screen_show_desktop_mode) {
+ case SCREEN_SHOW_DESKTOP_NO:
+ return FALSE;
+ case SCREEN_SHOW_DESKTOP_UNTIL_WINDOW:
+ case SCREEN_SHOW_DESKTOP_UNTIL_TOGGLE:
+ return TRUE;
+ }
+ g_assert_not_reached();
+ return FALSE;
}
void screen_install_colormap(ObClient *client, gboolean install)
#define DESKTOP_ALL (0xffffffff)
+typedef enum {
+ SCREEN_SHOW_DESKTOP_NO,
+ SCREEN_SHOW_DESKTOP_UNTIL_WINDOW,
+ SCREEN_SHOW_DESKTOP_UNTIL_TOGGLE
+} ObScreenShowDestopMode;
+
/*! The number of available desktops */
extern guint screen_num_desktops;
/*! The number of virtual "xinerama" screens/heads */
/*! The desktop which was last visible */
extern guint screen_last_desktop;
/*! Are we in showing-desktop mode? */
-extern gboolean screen_showing_desktop;
+extern ObScreenShowDestopMode screen_show_desktop_mode;
/*! The support window also used for focus and stacking */
extern Window screen_support_win;
/*! The last time at which the user changed desktops */
show is FALSE (restoring from show-desktop mode), and the rest are
iconified.
*/
-void screen_show_desktop(gboolean show, struct _ObClient *show_only);
+void screen_show_desktop(ObScreenShowDestopMode show_mode,
+ struct _ObClient *show_only);
+
+/*! Returns true if showing desktop mode is enabled. */
+gboolean screen_showing_desktop();
/*! Updates the desktop layout from the root property if available */
void screen_update_layout(void);