}
}
+void client_remove_destroy_notify_data(ObClientCallback func, gpointer data)
+{
+ GSList *it;
+
+ for (it = client_destroy_notifies; it; it = g_slist_next(it)) {
+ ClientCallback *d = it->data;
+ if (d->func == func && d->data == data) {
+ g_slice_free(ClientCallback, d);
+ client_destroy_notifies =
+ g_slist_delete_link(client_destroy_notifies, it);
+ break;
+ }
+ }
+}
+
void client_set_list(void)
{
Window *windows, *win_it;
Time launch_time;
guint32 user_time;
gboolean obplaced;
- gulong ignore_start;
+ gulong ignore_start = FALSE;
ob_debug("Managing window: 0x%lx", window);
ob_debug("Window group: 0x%x", self->group?self->group->leader:0);
ob_debug("Window name: %s class: %s role: %s title: %s",
self->name, self->class, self->role, self->title);
+ ob_debug("Window group name: %s group class: %s",
+ self->group_name, self->group_class);
/* per-app settings override stuff from client_get_all, and return the
settings for other uses too. the returned settings is a shallow copy,
"program + user specified" :
"BADNESS !?")))), place.width, place.height);
- obplaced = place_client(self, do_activate, &place.x, &place.y,
- settings);
+ obplaced = place_client(self, do_activate, &place, settings);
/* watch for buggy apps that ask to be placed at (0,0) when there is
a strut there */
g_free(self->name);
g_free(self->class);
g_free(self->role);
+ g_free(self->group_name);
+ g_free(self->group_class);
g_free(self->client_machine);
g_free(self->sm_client_id);
g_slice_free(ObClient, self);
g_assert(app->name != NULL || app->class != NULL ||
app->role != NULL || app->title != NULL ||
+ app->group_name != NULL || app->group_class != NULL ||
(signed)app->type >= 0);
if (app->name &&
!g_pattern_match(app->name, strlen(self->name), self->name, NULL))
match = FALSE;
+ else if (app->group_name &&
+ !g_pattern_match(app->group_name,
+ strlen(self->group_name), self->group_name, NULL))
+ match = FALSE;
else if (app->class &&
!g_pattern_match(app->class,
strlen(self->class), self->class, NULL))
match = FALSE;
+ else if (app->group_class &&
+ !g_pattern_match(app->group_class,
+ strlen(self->group_class), self->group_class,
+ NULL))
+ match = FALSE;
else if (app->role &&
!g_pattern_match(app->role,
strlen(self->role), self->role, NULL))
self->desktop = settings->desktop - 1;
}
+ if (settings->opacity != -1)
+ self->opacity = settings->opacity;
+
if (settings->layer == -1) {
self->below = TRUE;
self->above = FALSE;
self->max_horz = self->session->max_horz;
self->max_vert = self->session->max_vert;
self->undecorated = self->session->undecorated;
+
+ self->opacity = self->session->opacity;
}
static gboolean client_restore_session_stacking(ObClient *self)
from per-app settings */
client_get_session_ids(self);
- /* now we got everything that can affect the decorations */
+ /* get this early so we have it for debugging, also this can be used
+ by app rule matching */
+ client_update_title(self);
+
+ /* now we got everything that can affect the decorations or app rule
+ matching */
if (!real)
return;
- /* get this early so we have it for debugging */
- client_update_title(self);
-
/* save the values of the variables used for app rule matching */
client_save_app_rule_values(self);
if (self->name == NULL) self->name = g_strdup("");
if (self->class == NULL) self->class = g_strdup("");
+ /* get the WM_CLASS (name and class) from the group leader. make them "" if
+ they are not provided */
+ if (leader)
+ got = OBT_PROP_GETSS_TYPE(leader, WM_CLASS, STRING_NO_CC, &ss);
+ else
+ got = FALSE;
+
+ if (got) {
+ if (ss[0]) {
+ self->group_name = g_strdup(ss[0]);
+ if (ss[1])
+ self->group_class = g_strdup(ss[1]);
+ }
+ g_strfreev(ss);
+ }
+
+ if (self->group_name == NULL) self->group_name = g_strdup("");
+ if (self->group_class == NULL) self->group_class = g_strdup("");
+
/* get the WM_WINDOW_ROLE. make it "" if it is not provided */
got = OBT_PROP_GETS_XPCS(self->window, WM_WINDOW_ROLE, &s);
}
}
-/*! Save the properties used for app matching rules, as seen by Openbox when
- the window mapped, so that users can still access them later if the app
- changes them */
-static void client_save_app_rule_values(ObClient *self)
+const gchar *client_type_to_string(ObClient *self)
{
const gchar *type;
- OBT_PROP_SETS(self->window, OB_APP_ROLE, self->role);
- OBT_PROP_SETS(self->window, OB_APP_NAME, self->name);
- OBT_PROP_SETS(self->window, OB_APP_CLASS, self->class);
- OBT_PROP_SETS(self->window, OB_APP_TITLE, self->original_title);
-
switch (self->type) {
case OB_CLIENT_TYPE_NORMAL:
type = "normal"; break;
case OB_CLIENT_TYPE_DOCK:
type = "dock"; break;
}
- OBT_PROP_SETS(self->window, OB_APP_TYPE, type);
+
+ return type;
+}
+
+/*! Save the properties used for app matching rules, as seen by Openbox when
+ the window mapped, so that users can still access them later if the app
+ changes them */
+static void client_save_app_rule_values(ObClient *self)
+{
+ OBT_PROP_SETS(self->window, OB_APP_ROLE, self->role);
+ OBT_PROP_SETS(self->window, OB_APP_NAME, self->name);
+ OBT_PROP_SETS(self->window, OB_APP_CLASS, self->class);
+ OBT_PROP_SETS(self->window, OB_APP_GROUP_NAME, self->group_name);
+ OBT_PROP_SETS(self->window, OB_APP_GROUP_CLASS, self->group_class);
+ OBT_PROP_SETS(self->window, OB_APP_TITLE, self->original_title);
+
+ OBT_PROP_SETS(self->window, OB_APP_TYPE, client_type_to_string(self));
}
static void client_change_wm_state(ObClient *self)
self->type == OB_CLIENT_TYPE_TOOLBAR);
}
+gboolean client_occupies_space(ObClient *self)
+{
+ return !(self->type == OB_CLIENT_TYPE_DESKTOP ||
+ self->type == OB_CLIENT_TYPE_SPLASH);
+}
+
gboolean client_mouse_focusable(ObClient *self)
{
return !(self->type == OB_CLIENT_TYPE_MENU ||
gboolean demands_attention = self->demands_attention;
gboolean max_horz = self->max_horz;
gboolean max_vert = self->max_vert;
+ guint8 opacity = self->opacity;
Rect oldarea;
gint l;
/* make sure client_setup_decor_and_functions() is called at least once */
client_setup_decor_and_functions(self, FALSE);
+ /* make the client semi-transparent */
+ client_set_opacity(self, opacity);
+
/* if the window hasn't been configured yet, then do so now, in fact the
x,y,w,h may _not_ be the same as the area rect, which can end up
meaning that the client isn't properly moved/resized by the fullscreen
focus_cycle_addremove(NULL, TRUE);
}
+void client_set_opacity(ObClient *self, guint8 opacity)
+{
+ OBT_PROP_SET32(self->window, NET_WM_WINDOW_OPACITY, CARDINAL,
+ opacity * 16777216);
+}
+
gboolean client_is_direct_child(ObClient *parent, ObClient *child)
{
while (child != parent && (child = client_direct_parent(child)));