settings for other uses too. the returned settings is a shallow copy,
that needs to be freed with g_free(). */
settings = client_get_settings_state(self);
- /* the session should get the last say thought */
+ /* the session should get the last say though */
client_restore_session_state(self);
/* now we have all of the window's information so we can set this up */
client_search_focus_tree_full(self)) &&
/* this checks for focus=false for the window */
(!settings || settings->focus != 0) &&
- /* note the check against Type_Normal/Dialog, not client_normal(self),
- which would also include other types. in this case we want more
- strict rules for focus */
+ /* note the check against type Normal/Dialog/Utility,
+ not client_normal(self), which would also include other types.
+ in this case we want more strict rules for focus */
(self->type == OB_CLIENT_TYPE_NORMAL ||
+ self->type == OB_CLIENT_TYPE_UTILITY ||
self->type == OB_CLIENT_TYPE_DIALOG))
{
activate = TRUE;
splash screens get "transient" set to TRUE by
the place_client call
*/
- transient ||
- (!(self->positioned & USPosition) &&
- client_normal(self) &&
- !self->session));
+ ob_state() == OB_STATE_RUNNING &&
+ (transient ||
+ (!(self->positioned & USPosition) &&
+ client_normal(self) &&
+ !self->session)));
}
/* if the window isn't user-sized, then make it fit inside
splash screens get "transient" set to TRUE by
the place_client call
*/
- if (transient ||
- (!(self->sized & USSize) &&
- client_normal(self) &&
- !self->session))
+ if (ob_state() == OB_STATE_RUNNING &&
+ (transient ||
+ (!(self->sized & USSize) &&
+ client_normal(self) &&
+ !self->session)))
{
/* make a copy to modify */
Rect a = *screen_area_monitor(self->desktop, client_monitor(self));
{
guint j;
GSList *it;
+ gulong ignore_start;
ob_debug("Unmanaging window: 0x%x plate 0x%x (%s) (%s)\n",
self->window, self->frame->window,
don't generate more events */
XSelectInput(ob_display, self->window, NoEventMask);
+ /* ignore enter events from the unmap so it doesnt mess with the focus */
+ if (!client_focused(self) || !config_focus_under_mouse)
+ ignore_start = event_start_ignore_all_enters();
+
frame_hide(self->frame);
/* flush to send the hide to the server quickly */
XFlush(ob_display);
- /* ignore enter events from the unmap so it doesnt mess with the
- focus */
- event_ignore_all_queued_enters();
+ if (!client_focused(self) || !config_focus_under_mouse)
+ event_end_ignore_all_enters(ignore_start);
mouse_grab_for_client(self, FALSE);
for (it = self->group->members; it; it = g_slist_next(it)) {
ObClient *c = it->data;
+
+ if (c->desktop == DESKTOP_ALL) continue;
+
if (c != self) {
if (first) {
all = c->desktop;
static void client_change_state(ObClient *self)
{
- gulong netstate[11];
+ gulong netstate[12];
guint num;
num = 0;
gboolean demands_attention = self->demands_attention;
gboolean max_horz = self->max_horz;
gboolean max_vert = self->max_vert;
+ Rect oldarea;
+ gint l;
/* turn them all off in the client, so they won't affect the window
being placed */
do this before applying the states so they have the correct
pre-max/pre-fullscreen values
*/
- client_configure(self, x, y, w, h, FALSE, TRUE);
+ client_try_configure(self, &x, &y, &w, &h, &l, &l, FALSE);
ob_debug("placed window 0x%x at %d, %d with size %d x %d\n",
self->window, self->area.x, self->area.y,
self->area.width, self->area.height);
+ oldarea = self->area; /* save the area */
+ RECT_SET(self->area, x, y, w, h); /* put where it should be for the premax stuff */
/* apply the states. these are in a carefully crafted order.. */
else if (max_horz)
client_maximize(self, TRUE, 1);
+ /* if the window hasn't been configured yet, then do so now */
+ if (!fullscreen && !max_vert && !max_horz) {
+ self->area = oldarea;
+ client_configure(self, x, y, w, h, FALSE, TRUE);
+ }
+
/* set the desktop hint, to make sure that it always exists */
PROP_SET32(self->window, net_wm_desktop, cardinal, self->desktop);
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;
+ 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;
/* 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));
+ XMoveResizeWindow(ob_display, self->window,
+ self->frame->size.left, self->frame->size.top,
+ MAX(w, oldw), MAX(h, oldh));
frame_adjust_client_area(self->frame);
}
if (fmoved || fresized)
frame_adjust_area(self->frame, fmoved, fresized, FALSE);
- if ((!user || (user && final)) && !resized)
+ /* This is kinda tricky and should not be changed.. let me explain!
+
+ When user = FALSE, then the request is coming from the application
+ itself, and we are more strict about when to send a synthetic
+ ConfigureNotify. We strictly follow the rules of the ICCCM sec 4.1.5
+ in this case.
+
+ When user = TRUE, then the request is coming from "us", like when we
+ maximize a window or sometihng. In this case we are more lenient. We
+ used to follow the same rules as above, but _Java_ Swing can't handle
+ this. So just to appease Swing, when user = TRUE, we always send
+ a synthetic ConfigureNotify to give the window its root coordinates.
+ */
+ if ((!user && !resized) || (user && final))
{
XEvent event;
FALSE, StructureNotifyMask, &event);
}
- /* if the client is shrinking, then resize the frame before the client */
- if (send_resize_client && (w <= oldw && h <= oldh)) {
+ /* if the client is shrinking, then resize the frame before the client.
+
+ both of these resize sections may run, because the top one only resizes
+ in the direction that is growing
+ */
+ if (send_resize_client && (w <= oldw || h <= oldh)) {
frame_adjust_client_area(self->frame);
- XResizeWindow(ob_display, self->window, w, h);
+ XMoveResizeWindow(ob_display, self->window,
+ self->frame->size.left, self->frame->size.top, w, h);
}
XFlush(ob_display);
client_set_desktop_recursive(it->data, target, donthide);
}
-void client_set_desktop(ObClient *self, guint target,
- gboolean donthide)
+void client_set_desktop(ObClient *self, guint target, gboolean donthide)
{
self = client_search_top_normal_parent(self);
client_set_desktop_recursive(self, target, donthide);
self = client_focus_target(self);
if (!client_can_focus(self)) {
- if (!self->frame->visible) {
- /* update the focus lists */
- focus_order_to_top(self);
- }
ob_debug_type(OB_DEBUG_FOCUS,
"Client %s can't be focused\n", self->title);
return FALSE;
static void client_bring_windows_recursive(ObClient *self,
guint desktop,
gboolean helpers,
- gboolean modals)
+ gboolean modals,
+ gboolean iconic)
{
GSList *it;
for (it = self->transients; it; it = g_slist_next(it))
- client_bring_windows_recursive(it->data, desktop, helpers, modals);
+ client_bring_windows_recursive(it->data, desktop,
+ helpers, modals, iconic);
if (((helpers && client_helper(self)) ||
- (modals && self->modal))&&
- self->desktop != desktop && self->desktop != DESKTOP_ALL)
+ (modals && self->modal)) &&
+ ((self->desktop != desktop && self->desktop != DESKTOP_ALL) ||
+ (iconic && self->iconic)))
{
- client_set_desktop(self, desktop, FALSE);
+ if (iconic && self->iconic)
+ client_iconify(self, FALSE, TRUE, FALSE);
+ else
+ client_set_desktop(self, desktop, FALSE);
}
}
void client_bring_helper_windows(ObClient *self)
{
- client_bring_windows_recursive(self, self->desktop, TRUE, FALSE);
+ client_bring_windows_recursive(self, self->desktop, TRUE, FALSE, FALSE);
}
void client_bring_modal_windows(ObClient *self)
{
- client_bring_windows_recursive(self, self->desktop, FALSE, TRUE);
+ client_bring_windows_recursive(self, self->desktop, FALSE, TRUE, TRUE);
}
gboolean client_focused(ObClient *self)
}
#define WANT_EDGE(cur, c) \
- if(cur == c) \
- continue; \
- if(!client_normal(cur)) \
+ if (cur == c) \
continue; \
- if(screen_desktop != cur->desktop && cur->desktop != DESKTOP_ALL) \
+ if (c->desktop != cur->desktop && cur->desktop != DESKTOP_ALL && \
+ cur->desktop != screen_desktop) \
continue; \
- if(cur->iconic) \
+ if (cur->iconic) \
continue;
#define HIT_EDGE(my_edge_start, my_edge_end, his_edge_start, his_edge_end) \