static void client_get_shaped(ObClient *self)
{
self->shaped = FALSE;
+ self->shaped_input = FALSE;
#ifdef SHAPE
if (obt_display_extension_shape) {
gint foo;
&foo, &ufoo, &ufoo, &foo, &foo, &foo, &ufoo,
&ufoo);
self->shaped = !!s;
+#ifdef ShapeInput
+ { /* when some smart people added ShapeInput they forgot to update XShapeQueryExtents or
+ add a new one for input shapes, so we get to do this instead, yay! */
+ int nrects, ordering;
+ XRectangle *input_rect = XShapeGetRectangles(obt_display, self->window,
+ ShapeInput, &nrects, &ordering);
+ if (nrects == 1 && input_rect->width == self->area.width &&
+ input_rect->height == self->area.height &&
+ /* openbox sets the border width of client windows to 0 */
+ input_rect->x == 0 && input_rect->y == 0) {
+ self->shaped_input = FALSE;
+ } else {
+ self->shaped_input = TRUE;
+ }
+ XFree(input_rect);
+ }
+#endif
}
#endif
}
OBT_PROP_ERASE(self->frame->window, NET_WM_WINDOW_OPACITY);
}
-void client_update_normal_hints(ObClient *self)
+void client_update_normal_hints(ObClient *realself)
{
- XSizeHints size;
+ XSizeHints size = {0};
glong ret;
+ ObClient *self = g_new(ObClient, 1);
/* defaults */
- self->min_ratio = 0.0f;
- self->max_ratio = 0.0f;
- SIZE_SET(self->size_inc, 1, 1);
- SIZE_SET(self->base_size, -1, -1);
- SIZE_SET(self->min_size, 0, 0);
- SIZE_SET(self->max_size, G_MAXINT, G_MAXINT);
+ realself->min_ratio = 0.0f;
+ realself->max_ratio = 0.0f;
+ SIZE_SET(realself->size_inc, 1, 1);
+ SIZE_SET(realself->base_size, -1, -1);
+ SIZE_SET(realself->min_size, 0, 0);
+ SIZE_SET(realself->max_size, G_MAXINT, G_MAXINT);
+
+ memcpy(self, realself, sizeof(ObClient));
/* get the hints from the window */
if (XGetWMNormalHints(obt_display, self->window, &size, &ret)) {
self->gravity = size.win_gravity;
if (size.flags & PAspect) {
+ if ((unsigned int)size.min_aspect.x > 4096 ||
+ (unsigned int)size.min_aspect.y > 4096)
+ goto invalid_hints;
if (size.min_aspect.y)
self->min_ratio =
(gfloat) size.min_aspect.x / size.min_aspect.y;
(gfloat) size.max_aspect.x / size.max_aspect.y;
}
- if (size.flags & PMinSize)
+ if (size.flags & PMinSize) {
+ if ((unsigned int)size.min_width > 4096 ||
+ (unsigned int)size.min_height > 4096)
+ goto invalid_hints;
SIZE_SET(self->min_size, size.min_width, size.min_height);
+ }
- if (size.flags & PMaxSize)
+ if (size.flags & PMaxSize) {
+ if ((unsigned int)size.max_width > 4096 ||
+ (unsigned int)size.max_height > 4096)
+ goto invalid_hints;
SIZE_SET(self->max_size, size.max_width, size.max_height);
+ }
- if (size.flags & PBaseSize)
+ if (size.flags & PBaseSize) {
+ if ((unsigned int)size.base_width > 4096 ||
+ (unsigned int)size.base_height > 4096)
+ goto invalid_hints;
SIZE_SET(self->base_size, size.base_width, size.base_height);
+ }
- if (size.flags & PResizeInc && size.width_inc && size.height_inc)
+ if (size.flags & PResizeInc && size.width_inc && size.height_inc) {
+ if ((unsigned int)size.width_inc > 4096 ||
+ (unsigned int)size.width_inc > 4096)
+ goto invalid_hints;
SIZE_SET(self->size_inc, size.width_inc, size.height_inc);
+ }
ob_debug("Normal hints: min size (%d %d) max size (%d %d)",
self->min_size.width, self->min_size.height,
}
else
ob_debug("Normal hints: not set");
+ memcpy(realself, self, sizeof(ObClient));
+ g_free(self);
+ return;
+invalid_hints:
+ ob_debug("Normal hints: corruption detected, not setting anything");
}
static void client_setup_default_decor_and_functions(ObClient *self)
/* now we need to check against rules for the client's current state */
if (self->fullscreen) {
self->functions &= (OB_CLIENT_FUNC_CLOSE |
+ OB_CLIENT_FUNC_MOVE |
OB_CLIENT_FUNC_FULLSCREEN |
OB_CLIENT_FUNC_ICONIFY);
self->decorations = 0;