Add a strict option to the ToggleShowDesktop action

When the strict option is used, normal windows are not able to show themselves
while showing the desktop.
This commit is contained in:
Dana Jansens 2013-09-08 13:39:59 -04:00
parent adcb7a78d9
commit 7b408bc3b8
7 changed files with 122 additions and 27 deletions

View file

@ -176,6 +176,7 @@
<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>

View file

@ -1,17 +1,52 @@
#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;
}

View file

@ -2734,7 +2734,7 @@ gboolean client_should_show(ObClient *self)
{
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;
@ -4080,7 +4080,7 @@ gboolean client_focus(ObClient *self)
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);

View file

@ -772,7 +772,12 @@ static void event_handle_root(XEvent *e)
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)

View file

@ -406,8 +406,19 @@ static gboolean place_least_overlap(ObClient *c, Rect *head, int *x, int *y,
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;

View file

@ -61,7 +61,7 @@ guint screen_num_desktops;
guint screen_num_monitors;
guint screen_desktop;
guint screen_last_desktop;
gboolean screen_showing_desktop;
ObScreenShowDestopMode screen_show_desktop_mode;
ObDesktopLayout screen_desktop_layout;
gchar **screen_desktop_names;
Window screen_support_win;
@ -445,9 +445,9 @@ void screen_startup(gboolean reconfig)
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))
@ -1218,15 +1218,33 @@ void screen_update_desktop_names(void)
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)) {
@ -1250,7 +1268,7 @@ void screen_show_desktop(gboolean show, ObClient *show_only)
}
}
if (show) {
if (showing_after) {
/* focus the desktop */
for (it = focus_order; it; it = g_list_next(it)) {
ObClient *c = it->data;
@ -1275,8 +1293,23 @@ void screen_show_desktop(gboolean show, ObClient *show_only)
}
}
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)

View file

@ -26,6 +26,12 @@ struct _ObClient;
#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 */
@ -35,7 +41,7 @@ extern guint screen_desktop;
/*! 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 */
@ -90,7 +96,11 @@ void screen_hide_desktop_popup(void);
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);