Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented 'stop_hidden' configuration option for applications. #34

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions data/rc.xml
Original file line number Diff line number Diff line change
Expand Up @@ -732,6 +732,13 @@
<fullscreen>yes</fullscreen>
# make the window in fullscreen mode when it appears

<stop_hidden>process</stop_hidden>
# stop the application when it hides in order to minimize CPU usage
# and power consumption
# 'no' - do not stop application when it hides (default value)
# 'process' - stop just the process the window belongs to
# 'group' - stop whole process group the application belongs to

<maximized>true</maximized>
# 'Horizontal', 'Vertical' or boolean (yes/no)
</application>
Expand Down
8 changes: 8 additions & 0 deletions data/rc.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@
<xsd:element minOccurs="0" name="skip_pager" type="ob:bool"/>
<xsd:element minOccurs="0" name="skip_taskbar" type="ob:bool"/>
<xsd:element minOccurs="0" name="fullscreen" type="ob:bool"/>
<xsd:element minOccurs="0" name="stop_hidden" type="ob:stop_mode"/>
<xsd:element minOccurs="0" name="maximized" type="ob:maximization"/>
</xsd:all>
<!-- at least one of these must be present -->
Expand Down Expand Up @@ -485,6 +486,13 @@
<xsd:enumeration value="Floating"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="stop_mode">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="no"/>
<xsd:enumeration value="process"/>
<xsd:enumeration value="group"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="keyname">
<xsd:restriction base="xsd:string">
<!-- FIXME: M, Mod2, Mod5 in addition to S, A, C -->
Expand Down
7 changes: 7 additions & 0 deletions doc/rc-mouse-focus.xml
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,13 @@
<fullscreen>yes</fullscreen>
# make the window in fullscreen mode when it appears

<stop_hidden>process</stop_hidden>
# stop the application when it hides in order to minimize CPU usage
# and power consumption
# 'no' - do not stop application when it hides (default value)
# 'process' - stop just the process the window belongs to
# 'group' - stop whole process group the application belongs to

<maximized>true</maximized>
# 'Horizontal', 'Vertical' or boolean (yes/no)
</application>
Expand Down
91 changes: 90 additions & 1 deletion openbox/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,9 @@ void client_unmanage(ObClient *self)
prompt_unref(self->kill_prompt);
self->kill_prompt = NULL;

/* if client was stopped, continue executing */
client_continue_hidden(self);

client_list = g_list_remove(client_list, self);
stacking_remove(self);
window_remove(self->window);
Expand Down Expand Up @@ -968,6 +971,8 @@ static ObAppSettings *client_get_settings_state(ObClient *self)
self->skip_pager = !!settings->skip_pager;
if (settings->skip_taskbar != -1)
self->skip_taskbar = !!settings->skip_taskbar;
if (settings->stop_hidden != OB_CLIENT_STOP_MODE_NONE)
self->stop_hidden = settings->stop_hidden;

if (settings->max_vert != -1)
self->max_vert = !!settings->max_vert;
Expand Down Expand Up @@ -1043,6 +1048,7 @@ static void client_restore_session_state(ObClient *self)
self->max_horz = self->session->max_horz;
self->max_vert = self->session->max_vert;
self->undecorated = self->session->undecorated;
self->stop_hidden = self->session->stop_hidden;
}

static gboolean client_restore_session_stacking(ObClient *self)
Expand Down Expand Up @@ -2510,8 +2516,11 @@ static void client_change_wm_state(ObClient *self)
(self->desktop != DESKTOP_ALL && self->desktop != screen_desktop))
{
self->wmstate = IconicState;
} else
client_stop_hidden(self);
} else {
self->wmstate = NormalState;
client_continue_hidden(self);
}

if (old != self->wmstate) {
OBT_PROP_MSG(ob_screen, self->window, KDE_WM_CHANGE_STATE,
Expand Down Expand Up @@ -2608,6 +2617,24 @@ ObClient *client_search_focus_group_full(ObClient *self)
return NULL;
}

gboolean client_is_hidden(ObClient *self)
{
return (self->wmstate == IconicState);
}

gboolean client_is_group_hidden(ObClient *self)
{
GSList *it;

if (self->group) {
for (it = self->group->members; it; it = g_slist_next(it)) {
ObClient *c = it->data;
if (!client_is_hidden(c)) return FALSE;
}
}
return TRUE;
}

gboolean client_has_parent(ObClient *self)
{
return self->parents != NULL;
Expand Down Expand Up @@ -3706,6 +3733,68 @@ void client_kill(ObClient *self)
}
}

void client_stop_hidden(ObClient *self)
{
if (self->stop_hidden == OB_CLIENT_STOP_MODE_NONE)
return;

if (client_on_localhost(self) && self->pid) {
/* running on the local host */

if (!client_is_group_hidden(self)) {
return;
}

if (self->stop_hidden == OB_CLIENT_STOP_MODE_PROCESS) {
ob_debug("client_stop_hidden is stopping process with pid %lu",
self->pid);
kill(self->pid, SIGSTOP);
} else if (self->stop_hidden == OB_CLIENT_STOP_MODE_GROUP) {
ob_debug("client_stop_hidden is stopping group with pid %lu",
self->pid);
pid_t pgid = getpgid(self->pid);
if (pgid != -1) {
killpg(self->pid, SIGSTOP);
}
} else {
ob_debug("client_stop_hidden: unknown value of stop_hidden");
return;
}
}
else {
/* do nothing, running on a remote host */
}
}

void client_continue_hidden(ObClient *self)
{
if (self->stop_hidden == OB_CLIENT_STOP_MODE_NONE)
return;

if (client_on_localhost(self) && self->pid) {
/* running on the local host */
if (self->stop_hidden == OB_CLIENT_STOP_MODE_PROCESS) {
ob_debug("client_continue_hidden is continuing process with pid %lu",
self->pid);
kill(self->pid, SIGCONT);
} else if (self->stop_hidden == OB_CLIENT_STOP_MODE_GROUP) {
ob_debug("client_continue_hidden is continuing group with pid %lu",
self->pid);
pid_t pgid = getpgid(self->pid);
if (pgid != -1) {
killpg(self->pid, SIGCONT);
}
} else {
ob_debug("client_continue_hidden: unknown value"
" of stop_hidden");
return;
}
}
else {
/* do nothing, running on a remote host */
}
}

void client_hilite(ObClient *self, gboolean hilite)
{
if (self->demands_attention == hilite)
Expand Down
16 changes: 16 additions & 0 deletions openbox/client.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,14 @@ typedef enum
OB_CLIENT_FUNC_UNDECORATE = 1 << 9 /*!< Allow to be undecorated */
} ObFunctions;

/*! The way to stop client when it hides */
typedef enum
{
OB_CLIENT_STOP_MODE_NONE, /*!< Do not stop client */
OB_CLIENT_STOP_MODE_PROCESS, /*!< Stop the client process only */
OB_CLIENT_STOP_MODE_GROUP, /*!< Stop process group the client belongs to */
} ObClientStopMode;

struct _ObClient
{
ObWindow obwin;
Expand Down Expand Up @@ -272,6 +280,8 @@ struct _ObClient
gboolean skip_pager;
/*! The window should not be displayed by taskbars */
gboolean skip_taskbar;
/*! How to stop the process when it hides or iconifies */
ObClientStopMode stop_hidden;
/*! The window is a 'fullscreen' window, and should be on top of all
others */
gboolean fullscreen;
Expand Down Expand Up @@ -548,6 +558,12 @@ void client_close(ObClient *self);
/*! Kill the client off violently */
void client_kill(ObClient *self);

/*! Stop the client process when all its windows are hidded */
void client_stop_hidden(ObClient *self);

/*! Continue executing the client process when one of its windows appears */
void client_continue_hidden(ObClient *self);

/*! Sends the window to the specified desktop
@param donthide If TRUE, the window will not be shown/hidden after its
desktop has been changed. Generally this should be FALSE.
Expand Down
14 changes: 14 additions & 0 deletions openbox/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ ObAppSettings* config_create_app_settings(void)
settings->fullscreen = -1;
settings->max_horz = -1;
settings->max_vert = -1;
settings->stop_hidden = OB_CLIENT_STOP_MODE_NONE;
return settings;
}

Expand All @@ -148,6 +149,7 @@ void config_app_settings_copy_non_defaults(const ObAppSettings *src,
copy_if(fullscreen, -1);
copy_if(max_horz, -1);
copy_if(max_vert, -1);
copy_if(stop_hidden, OB_CLIENT_STOP_MODE_NONE);

if (src->pos_given) {
dst->pos_given = TRUE;
Expand Down Expand Up @@ -328,6 +330,18 @@ static void parse_single_per_app_settings(xmlNodePtr app,
if (!obt_xml_node_contains(n, "default"))
settings->fullscreen = obt_xml_node_bool(n);

if ((n = obt_xml_find_node(app->children, "stop_hidden")))
if (!obt_xml_node_contains(n, "default")) {
gchar *s = obt_xml_node_string(n);
if (!g_ascii_strcasecmp(s, "no"))
settings->stop_hidden = OB_CLIENT_STOP_MODE_NONE;
else if (!g_ascii_strcasecmp(s, "process"))
settings->stop_hidden = OB_CLIENT_STOP_MODE_PROCESS;
else if (!g_ascii_strcasecmp(s, "group"))
settings->stop_hidden = OB_CLIENT_STOP_MODE_GROUP;
g_free(s);
}

if ((n = obt_xml_find_node(app->children, "maximized"))) {
if (!obt_xml_node_contains(n, "default")) {
gchar *s = obt_xml_node_string(n);
Expand Down
1 change: 1 addition & 0 deletions openbox/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ struct _ObAppSettings
GPatternSpec *group_name;
GPatternSpec *title;
ObClientType type;
ObClientStopMode stop_hidden;

GravityPoint position;
gboolean pos_given;
Expand Down
4 changes: 4 additions & 0 deletions openbox/session.c
Original file line number Diff line number Diff line change
Expand Up @@ -603,6 +603,8 @@ static gboolean session_save_to_file(const ObSMSaveData *savedata)
fprintf(f, "\t<max_vert />\n");
if (c->undecorated)
fprintf(f, "\t<undecorated />\n");
if (c->stop_hidden)
fprintf(f, "\t<stop_hidden />\n");
if (savedata->focus_client == c)
fprintf(f, "\t<focused />\n");
fprintf(f, "</window>\n\n");
Expand Down Expand Up @@ -784,6 +786,8 @@ static void session_load_file(const gchar *path)
obt_xml_find_node(node->children, "max_vert") != NULL;
state->undecorated =
obt_xml_find_node(node->children, "undecorated") != NULL;
state->stop_hidden =
obt_xml_find_node(node->children, "stop_hidden") != NULL;
state->focused =
obt_xml_find_node(node->children, "focused") != NULL;

Expand Down
2 changes: 1 addition & 1 deletion openbox/session.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ struct _ObSessionState {
gboolean shaded, iconic, skip_pager, skip_taskbar, fullscreen;
gboolean above, below, max_horz, max_vert, undecorated;
gboolean focused;

ObClientStopMode stop_hidden;
gboolean matched;
};

Expand Down