gboolean oldgtran, gboolean newgtran,
ObClient* oldparent,
ObClient *newparent);
-static void client_present(ObClient *self, gboolean here, gboolean raise);
+static void client_present(ObClient *self, gboolean here, gboolean raise,
+ gboolean unshade);
static GSList *client_search_all_top_parents_internal(ObClient *self,
gboolean bylayer,
ObStackingLayer layer);
*/
if (ob_state() == OB_STATE_RUNNING &&
(transient ||
- (!(self->sized & USSize) &&
+ (!(self->sized & USSize || self->positioned & USPosition) &&
client_normal(self) &&
!self->session)))
{
if (activate) {
gboolean stacked = client_restore_session_stacking(self);
- client_present(self, FALSE, !stacked);
+ client_present(self, FALSE, !stacked, TRUE);
}
/* add to client list/map */
frame_rect_to_frame(self->frame, &desired);
/* get where the frame would be */
- frame_client_gravity(self->frame, x, y, w, h);
+ frame_client_gravity(self->frame, x, y);
/* get the requested size of the window with decorations */
fw = self->frame->size.left + w + self->frame->size.right;
}
/* get where the client should be */
- frame_frame_gravity(self->frame, x, y, w, h);
+ frame_frame_gravity(self->frame, x, y);
return ox != *x || oy != *y;
}
}
}
-void client_reconfigure(ObClient *self, gboolean force)
-{
- gint x, y, w, h, lw, lh;
-
- RECT_TO_DIMS(self->area, x, y, w, h);
- if (!force)
- client_try_configure(self, &x, &y, &w, &h, &lw, &lh, FALSE);
- if (force || !RECT_EQUAL_DIMS(self->area, x, y, w, h)) {
- gulong ignore_start;
-
- ob_debug("Reconfiguring client x %d y %d w %d h %d\n",
- x, y, w, h);
- ignore_start = event_start_ignore_all_enters();
- client_configure(self, x, y, w, h, FALSE, TRUE);
- event_end_ignore_all_enters(ignore_start);
- }
-}
-
void client_update_wmhints(ObClient *self)
{
XWMHints *hints;
/* set the default icon onto the window
in theory, this could be a race, but if a window doesn't set an icon
or removes it entirely, it's not very likely it is going to set one
- right away afterwards */
- if (self->nicons == 0) {
+ right away afterwards
+
+ if it has parents, then one of them will have an icon already
+ */
+ if (self->nicons == 0 && !self->parents) {
RrPixel32 *icon = ob_rr_theme->def_win_icon;
gulong *data;
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);
- }
+ /* 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
+ function
+ pho can cause this because it maps at size of the screen but not 0,0
+ so openbox moves it on screen to 0,0 (thus x,y=0,0 and area.x,y don't).
+ then fullscreen'ing makes it go to 0,0 which it thinks it already is at
+ cuz thats where the pre-fullscreen will be. however the actual area is
+ not, so this needs to be called even if we have fullscreened/maxed
+ */
+ self->area = oldarea;
+ client_configure(self, x, y, w, h, FALSE, TRUE, FALSE);
/* set the desktop hint, to make sure that it always exists */
PROP_SET32(self->window, net_wm_desktop, cardinal, self->desktop);
frame_adjust_area(self->frame, FALSE, TRUE, TRUE);
/* gets the frame's position */
- frame_client_gravity(self->frame, x, y, *w, *h);
+ frame_client_gravity(self->frame, x, y);
/* these positions are frame positions, not client positions */
}
/* gets the client's position */
- frame_frame_gravity(self->frame, x, y, *w, *h);
+ frame_frame_gravity(self->frame, x, y);
/* work within the prefered sizes given by the window */
if (!(*w == self->area.width && *h == self->area.height)) {
void client_configure(ObClient *self, gint x, gint y, gint w, gint h,
- gboolean user, gboolean final)
+ gboolean user, gboolean final, gboolean force_reply)
{
gint oldw, oldh;
gboolean send_resize_client;
- gboolean moved = FALSE, resized = FALSE;
+ gboolean moved = FALSE, resized = FALSE, rootmoved = FALSE;
gboolean fmoved, fresized;
guint fdecor = self->frame->decorations;
gboolean fhorz = self->frame->max_horz;
}
/* adjust the frame */
- if (fmoved || fresized)
+ if (fmoved || fresized) {
+ gulong ignore_start;
+ if (!user)
+ ignore_start = event_start_ignore_all_enters();
+
frame_adjust_area(self->frame, fmoved, fresized, FALSE);
+ if (!user)
+ event_end_ignore_all_enters(ignore_start);
+ }
+
+ if (!user || final) {
+ gint oldrx = self->root_pos.x;
+ gint oldry = self->root_pos.y;
+ /* we have reset the client to 0 border width, so don't include
+ it in these coords */
+ 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);
+ if (self->root_pos.x != oldrx || self->root_pos.y != oldry)
+ rootmoved = TRUE;
+ }
+
/* 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.
+ in this case (if force_reply is true)
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
+ maximize a window or something. 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))
+ if ((!user && !resized && (rootmoved || force_reply)) ||
+ (user && final && rootmoved))
{
XEvent event;
- /* we have reset the client to 0 border width, so don't include
- it in these coords */
- 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;
RECT_SET(self->pre_fullscreen_area, 0, 0, 0, 0);
}
+ ob_debug("Window %s going fullscreen (%d)\n",
+ self->title, self->fullscreen);
+
client_setup_decor_and_functions(self, FALSE);
client_move_resize(self, x, y, w, h);
if (curdesk && self->desktop != screen_desktop &&
self->desktop != DESKTOP_ALL)
- client_set_desktop(self, screen_desktop, FALSE);
+ client_set_desktop(self, screen_desktop, FALSE, FALSE);
/* this puts it after the current focused window */
focus_order_remove(self);
void client_set_desktop_recursive(ObClient *self,
guint target,
- gboolean donthide)
+ gboolean donthide,
+ gboolean dontraise)
{
guint old;
GSList *it;
frame_adjust_state(self->frame);
/* 'move' the window to the new desktop */
if (!donthide)
- client_showhide(self);
+ client_hide(self);
+ client_show(self);
/* raise if it was not already on the desktop */
- if (old != DESKTOP_ALL)
+ if (old != DESKTOP_ALL && !dontraise)
stacking_raise(CLIENT_AS_WINDOW(self));
if (STRUT_EXISTS(self->strut))
screen_update_areas();
for (it = self->transients; it; it = g_slist_next(it))
if (it->data != self)
if (client_is_direct_child(self, it->data))
- client_set_desktop_recursive(it->data, target, donthide);
+ client_set_desktop_recursive(it->data, target,
+ donthide, dontraise);
}
-void client_set_desktop(ObClient *self, guint target, gboolean donthide)
+void client_set_desktop(ObClient *self, guint target,
+ gboolean donthide, gboolean dontraise)
{
self = client_search_top_direct_parent(self);
- client_set_desktop_recursive(self, target, donthide);
+ client_set_desktop_recursive(self, target, donthide, dontraise);
}
gboolean client_is_direct_child(ObClient *parent, ObClient *child)
"Focusing client \"%s\" (0x%x) at time %u\n",
self->title, self->window, event_curtime);
+ /* if using focus_delay, stop the timer now so that focus doesn't
+ go moving on us */
+ event_halt_focus_delay();
+
/* if there is a grab going on, then we need to cancel it. if we move
focus during the grab, applications will get NotifyWhileGrabbed events
and ignore them !
return !xerror_occured;
}
-/*! Present the client to the user.
- @param raise If the client should be raised or not. You should only set
- raise to false if you don't care if the window is completely
- hidden.
-*/
-static void client_present(ObClient *self, gboolean here, gboolean raise)
+static void client_present(ObClient *self, gboolean here, gboolean raise,
+ gboolean unshade)
{
- /* if using focus_delay, stop the timer now so that focus doesn't
- go moving on us */
- event_halt_focus_delay();
-
if (client_normal(self) && screen_showing_desktop)
screen_show_desktop(FALSE, self);
if (self->iconic)
self->desktop != screen_desktop)
{
if (here)
- client_set_desktop(self, screen_desktop, FALSE);
+ client_set_desktop(self, screen_desktop, FALSE, TRUE);
else
screen_set_desktop(self->desktop, FALSE);
} else if (!self->frame->visible)
/* if its not visible for other reasons, then don't mess
with it */
return;
- if (self->shaded)
+ if (self->shaded && unshade)
client_shade(self, FALSE);
if (raise)
stacking_raise(CLIENT_AS_WINDOW(self));
client_focus(self);
}
-void client_activate(ObClient *self, gboolean here, gboolean user)
+void client_activate(ObClient *self, gboolean here, gboolean raise,
+ gboolean unshade, gboolean user)
{
guint32 last_time = focus_client ? focus_client->user_time : CurrentTime;
gboolean allow = FALSE;
(user ? "user" : "application"), allow);
if (allow)
- client_present(self, here, TRUE);
+ client_present(self, here, raise, unshade);
else
/* don't focus it but tell the user it wants attention */
client_hilite(self, TRUE);
if (iconic && self->iconic)
client_iconify(self, FALSE, TRUE, FALSE);
else
- client_set_desktop(self, desktop, FALSE);
+ client_set_desktop(self, desktop, FALSE, FALSE);
}
}
{
return self->group && self->group->members->next;
}
+
+ObClientIcon *client_thumbnail(ObClient *self, gint wantw, gint wanth)
+{
+ ObClientIcon *ret;
+ RrPixel32 *data;
+ gint w, h;
+
+ if (!self->frame->pixmap) return NULL;
+ if (!RrPixmapToRGBA(ob_rr_inst, self->frame->pixmap, None, &w, &h, &data))
+ return NULL;
+
+ /* resize the thumbnail (within aspect ratio) to the given sizes */
+
+ ret = g_new(ObClientIcon, 1);
+ ret->data = data;
+ ret->width = w;
+ ret->height = h;
+ return ret;
+}
+
+void clienticon_free(ObClientIcon *ci)
+{
+ if (ci) {
+ g_free(ci->data);
+ g_free(ci);
+ }
+}