+ *x = a->x;
+ *y = a->y;
+ *w = a->width;
+ *h = a->height;
+
+ user = FALSE; /* ignore if the client can't be moved/resized when it
+ is entering fullscreen */
+ } else if (self->max_horz || self->max_vert) {
+ Rect *a;
+ guint i;
+
+ i = screen_find_monitor(&desired_area);
+ a = screen_area_monitor(self->desktop, i);
+
+ /* set the size and position if maximized */
+ if (self->max_horz) {
+ *x = a->x;
+ *w = a->width - self->frame->size.left - self->frame->size.right;
+ }
+ if (self->max_vert) {
+ *y = a->y;
+ *h = a->height - self->frame->size.top - self->frame->size.bottom;
+ }
+
+ /* maximizing is not allowed if the user can't move+resize the window
+ */
+ }
+
+ /* gets the client's position */
+ frame_frame_gravity(self->frame, x, y, *w, *h);
+
+ /* these override the above states! if you cant move you can't move! */
+ if (user) {
+ if (!(self->functions & OB_CLIENT_FUNC_MOVE)) {
+ *x = self->area.x;
+ *y = self->area.y;
+ }
+ if (!(self->functions & OB_CLIENT_FUNC_RESIZE)) {
+ *w = self->area.width;
+ *h = self->area.height;
+ }
+ }
+
+ g_assert(*w > 0);
+ g_assert(*h > 0);
+}
+
+
+void client_configure(ObClient *self, gint x, gint y, gint w, gint h,
+ gboolean user, gboolean final)
+{
+ gint oldw, oldh;
+ gboolean send_resize_client;
+ gboolean moved = FALSE, resized = FALSE;
+ gboolean fmoved, fresized;
+ guint fdecor = self->frame->decorations;
+ gboolean fhorz = self->frame->max_horz;
+ gboolean fvert = self->frame->max_vert;
+ gint logicalw, logicalh;
+
+ /* find the new x, y, width, and height (and logical size) */
+ client_try_configure(self, &x, &y, &w, &h, &logicalw, &logicalh, user);
+
+ /* set the logical size if things changed */
+ if (!(w == self->area.width && h == self->area.height))
+ SIZE_SET(self->logical_size, logicalw, logicalh);
+
+ /* figure out if we moved or resized or what */
+ moved = x != self->area.x || y != self->area.y;
+ resized = w != self->area.width || h != self->area.height;
+
+ oldw = self->area.width;
+ oldh = self->area.height;
+ RECT_SET(self->area, x, y, w, h);
+
+ /* for app-requested resizes, always resize if 'resized' is true.
+ for user-requested ones, only resize if final is true, or when
+ resizing in redraw mode */
+ send_resize_client = ((!user && resized) ||
+ (user && (final ||
+ (resized && config_resize_redraw))));
+
+ /* if the client is enlarging, then resize the client before the frame */
+ if (send_resize_client && (w > oldw || h > oldh)) {
+ XResizeWindow(ob_display, self->window,
+ MAX(w, oldw), MAX(h, oldh));
+ /* resize the plate to show the client padding color underneath */
+ frame_adjust_client_area(self->frame);
+ }
+
+ /* find the frame's dimensions and move/resize it */
+ fmoved = moved;
+ fresized = resized;
+ if (self->decorations != fdecor ||
+ self->max_horz != fhorz || self->max_vert != fvert)
+ {
+ fmoved = fresized = TRUE;
+ }
+ if (fmoved || fresized)
+ frame_adjust_area(self->frame, fmoved, fresized, FALSE);
+
+ if ((!user || (user && final)) && !resized)
+ {
+ XEvent event;
+
+ POINT_SET(self->root_pos,
+ self->frame->area.x + self->frame->size.left -
+ self->border_width,
+ self->frame->area.y + self->frame->size.top -
+ self->border_width);
+
+ event.type = ConfigureNotify;
+ event.xconfigure.display = ob_display;
+ event.xconfigure.event = self->window;
+ event.xconfigure.window = self->window;
+
+ ob_debug("Sending ConfigureNotify to %s for %d,%d %dx%d\n",
+ self->title, self->root_pos.x, self->root_pos.y, w, h);
+
+ /* root window real coords */
+ event.xconfigure.x = self->root_pos.x;
+ event.xconfigure.y = self->root_pos.y;
+ event.xconfigure.width = w;
+ event.xconfigure.height = h;
+ event.xconfigure.border_width = 0;
+ event.xconfigure.above = self->frame->plate;
+ event.xconfigure.override_redirect = FALSE;
+ XSendEvent(event.xconfigure.display, event.xconfigure.window,
+ FALSE, StructureNotifyMask, &event);
+ }
+
+ /* if the client is shrinking, then resize the frame before the client */
+ if (send_resize_client && (w <= oldw || h <= oldh)) {
+ /* resize the plate to show the client padding color underneath */
+ frame_adjust_client_area(self->frame);
+
+ if (send_resize_client)
+ XResizeWindow(ob_display, self->window, w, h);
+ }
+
+ XFlush(ob_display);
+}
+
+void client_fullscreen(ObClient *self, gboolean fs)
+{
+ gint x, y, w, h;
+
+ if (!(self->functions & OB_CLIENT_FUNC_FULLSCREEN) || /* can't */
+ self->fullscreen == fs) return; /* already done */
+
+ self->fullscreen = fs;
+ client_change_state(self); /* change the state hints on the client */
+
+ if (fs) {
+ self->pre_fullscreen_area = self->area;
+ /* if the window is maximized, its area isn't all that meaningful.
+ save it's premax area instead. */
+ if (self->max_horz) {
+ self->pre_fullscreen_area.x = self->pre_max_area.x;
+ self->pre_fullscreen_area.width = self->pre_max_area.width;
+ }
+ if (self->max_vert) {
+ self->pre_fullscreen_area.y = self->pre_max_area.y;
+ self->pre_fullscreen_area.height = self->pre_max_area.height;
+ }
+
+ /* these will help configure_full figure out where to fullscreen
+ the window */
+ x = self->area.x;
+ y = self->area.y;
+ w = self->area.width;
+ h = self->area.height;