self->wmstate = WithdrawnState; /* make sure it gets updated first time */
self->layer = -1;
self->desktop = screen_num_desktops; /* always an invalid value */
- self->user_time = ~0; /* maximum value, always newer than the real time */
+ self->user_time = client_last_user_time;
client_get_all(self);
client_restore_session_state(self);
/* this has to happen before we try focus the window, but we want it to
happen after the client's stacking has been determined or it looks bad
*/
- client_showhide(self);
+ client_show(self);
/* use client_focus instead of client_activate cuz client_activate does
stuff like switch desktops etc and I'm not interested in all that when
self->group = NULL;
}
- /* give the client its border back */
- client_toggle_border(self, TRUE);
+ /* restore the window's original geometry so it is not lost */
+ {
+ Rect a = self->area;
+
+ if (self->fullscreen)
+ a = self->pre_fullscreen_area;
+ else if (self->max_horz || self->max_vert) {
+ if (self->max_horz) {
+ a.x = self->pre_max_area.x;
+ a.width = self->pre_max_area.width;
+ }
+ if (self->max_vert) {
+ a.y = self->pre_max_area.y;
+ a.height = self->pre_max_area.height;
+ }
+ }
+
+ /* give the client its border back */
+ client_toggle_border(self, TRUE);
+
+ self->fullscreen = self->max_horz = self->max_vert = FALSE;
+ self->decorations = 0; /* unmanaged windows have no decor */
+
+ client_move_resize(self, a.x, a.y, a.width, a.height);
+ }
/* reparent the window out of the frame, and free the frame */
frame_release_client(self->frame, self);
self->frame = NULL;
- /* restore the window's original geometry so it is not lost */
- if (self->fullscreen)
- XMoveResizeWindow(ob_display, self->window,
- self->pre_fullscreen_area.x,
- self->pre_fullscreen_area.y,
- self->pre_fullscreen_area.width,
- self->pre_fullscreen_area.height);
- else if (self->max_horz || self->max_vert) {
- Rect a = self->area;
- if (self->max_horz) {
- a.x = self->pre_max_area.x;
- a.width = self->pre_max_area.width;
- }
- if (self->max_vert) {
- a.y = self->pre_max_area.y;
- a.height = self->pre_max_area.height;
- }
- XMoveResizeWindow(ob_display, self->window,
- a.x, a.y, a.width, a.height);
- }
-
if (ob_state() != OB_STATE_EXITING) {
/* these values should not be persisted across a window
unmapping/mapping */
XMapWindow(ob_display, self->window);
}
-
ob_debug("Unmanaged window 0x%lx\n", self->window);
/* free all data allocated in the client struct */
if (show) {
XSetWindowBorderWidth(ob_display, self->window, self->border_width);
- /* move the client so it is back it the right spot _with_ its
- border! */
- if (x != oldx || y != oldy)
- XMoveWindow(ob_display, self->window, x, y);
+ /* set border_width to 0 because there is no border to add into
+ calculations anymore */
+ self->border_width = 0;
} else
XSetWindowBorderWidth(ob_display, self->window, 0);
}
g_assert(ret != BadWindow);
RECT_SET(self->area, wattrib.x, wattrib.y, wattrib.width, wattrib.height);
+ POINT_SET(self->root_pos, wattrib.x, wattrib.y);
self->border_width = wattrib.border_width;
ob_debug("client area: %d %d %d %d\n", wattrib.x, wattrib.y,
return FALSE;
}
+void client_show(ObClient *self)
+{
+
+ if (client_should_show(self)) {
+ frame_show(self->frame);
+ }
+
+ /* According to the ICCCM (sec 4.1.3.1) when a window is not visible, it
+ needs to be in IconicState. This includes when it is on another
+ desktop!
+ */
+ client_change_wm_state(self);
+}
+
+void client_hide(ObClient *self)
+{
+ if (!client_should_show(self)) {
+ frame_hide(self->frame);
+ }
+
+ /* According to the ICCCM (sec 4.1.3.1) when a window is not visible, it
+ needs to be in IconicState. This includes when it is on another
+ desktop!
+ */
+ client_change_wm_state(self);
+}
+
void client_showhide(ObClient *self)
{
}
else {
frame_hide(self->frame);
-
- /* Fall back focus since we're disappearing */
- if (focus_client == self)
- client_unfocus(self);
}
/* According to the ICCCM (sec 4.1.3.1) when a window is not visible, it
pos = TRUE;
}
- /* if the client didn't get positioned yet, then do so now */
- if (!pos && (ox != x || oy != y)) {
+ /* if the client didn't get positioned yet, then do so now
+ call client_move even if the window is not being moved anywhere, because
+ when we reparent it and decorate it, it is getting moved and we need to
+ be telling it so with a ConfigureNotify event.
+ */
+ if (!pos) {
/* use the saved position */
self->area.x = ox;
self->area.y = oy;
the updated frame dimensions. */
frame_adjust_area(self->frame, TRUE, TRUE, TRUE);
- /* gets the frame's position */
- frame_client_gravity(self->frame, x, y);
-
- /* these positions are frame positions, not client positions */
-
- /* set the size and position if fullscreen */
- if (self->fullscreen) {
- Rect *a;
- guint i;
-
- i = screen_find_monitor(&desired_area);
- a = screen_physical_area_monitor(i);
-
- *x = a->x;
- *y = a->y;
- *w = a->width;
- *h = a->height;
-
- user = FALSE; /* ignore that increment etc shit when in fullscreen */
- } else {
- 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;
- }
- }
-
- /* gets the client's position */
- frame_frame_gravity(self->frame, x, y);
-
- /* 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;
- }
- }
-
+ /* work within the prefered sizes given by the window */
if (!(*w == self->area.width && *h == self->area.height)) {
gint basew, baseh, minw, minh;
*h += self->base_size.height;
}
+ /* gets the frame's position */
+ frame_client_gravity(self->frame, x, y);
+
+ /* these positions are frame positions, not client positions */
+
+ /* set the size and position if fullscreen */
+ if (self->fullscreen) {
+ Rect *a;
+ guint i;
+
+ i = screen_find_monitor(&desired_area);
+ a = screen_physical_area_monitor(i);
+
+ *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);
+
+ /* 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);
gboolean user, gboolean final,
gboolean force_reply)
{
- gint oldw, oldh;
+ gint oldw, oldh, oldrx, oldry;
gboolean send_resize_client;
- gboolean moved = FALSE, resized = FALSE;
+ gboolean moved = FALSE, resized = FALSE, rootmoved = FALSE;
guint fdecor = self->frame->decorations;
gboolean fhorz = self->frame->max_horz;
gint logicalw, logicalh;
if (send_resize_client && user && (w > oldw || h > oldh))
XResizeWindow(ob_display, self->window, MAX(w, oldw), MAX(h, oldh));
- /* move/resize the frame to match the request */
- if (self->frame) {
- if (self->decorations != fdecor || self->max_horz != fhorz)
- moved = resized = TRUE;
-
- if (moved || resized)
- frame_adjust_area(self->frame, moved, resized, FALSE);
-
- if (!resized && (force_reply || ((!user && moved) || (user && final))))
- {
- XEvent event;
- event.type = ConfigureNotify;
- event.xconfigure.display = ob_display;
- event.xconfigure.event = self->window;
- event.xconfigure.window = self->window;
-
- /* root window real coords */
- event.xconfigure.x = self->frame->area.x + self->frame->size.left -
- self->border_width;
- event.xconfigure.y = self->frame->area.y + self->frame->size.top -
- self->border_width;
- 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);
- }
+ /* find the frame's dimensions and move/resize it */
+ if (self->decorations != fdecor || self->max_horz != fhorz)
+ moved = resized = TRUE;
+ if (moved || resized)
+ frame_adjust_area(self->frame, moved, resized, FALSE);
+
+ /* find the client's position relative to the root window */
+ oldrx = self->root_pos.x;
+ oldry = self->root_pos.y;
+ rootmoved = (oldrx != (self->frame->area.x + self->frame->size.left -
+ self->border_width) ||
+ oldry != (self->frame->area.y + self->frame->size.top -
+ self->border_width));
+
+ if (force_reply || ((!user || (user && final)) && rootmoved))
+ {
+ 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;
+
+ /* 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 */
/* choose the correct target */
self = client_focus_target(self);
-#if 0
- if (!client_validate(self))
- return FALSE;
-#endif
-
if (!client_can_focus(self)) {
if (!self->frame->visible) {
/* update the focus lists */