X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Fclient.c;h=f8c3c457843b63027ce033dd36323c7212cca1d4;hb=d179d6428ae585a3b8a13479bfe4586e41de2ff9;hp=f91a783db0cf0d9b22117959456f1080241812e0;hpb=6cf3357036561134383198cc8b853abb3fe5a982;p=chaz%2Fopenbox diff --git a/openbox/client.c b/openbox/client.c index f91a783d..f8c3c457 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -150,7 +150,7 @@ static void client_call_notifies(ObClient *self, GSList *list) void client_add_destroy_notify(ObClientCallback func, gpointer data) { - ClientCallback *d = g_new(ClientCallback, 1); + ClientCallback *d = g_slice_new(ClientCallback); d->func = func; d->data = data; client_destroy_notifies = g_slist_prepend(client_destroy_notifies, d); @@ -163,7 +163,7 @@ void client_remove_destroy_notify(ObClientCallback func) for (it = client_destroy_notifies; it; it = g_slist_next(it)) { ClientCallback *d = it->data; if (d->func == func) { - g_free(d); + g_slice_free(ClientCallback, d); client_destroy_notifies = g_slist_delete_link(client_destroy_notifies, it); break; @@ -202,9 +202,11 @@ void client_manage(Window window, ObPrompt *prompt) gboolean activate = FALSE; ObAppSettings *settings; gboolean transient = FALSE; - Rect place, *monitor; + Rect place; + Rect const *monitor, *allmonitors; Time launch_time, map_time; guint32 user_time; + gboolean obplaced; ob_debug("Managing window: 0x%lx", window); @@ -220,7 +222,7 @@ void client_manage(Window window, ObPrompt *prompt) /* create the ObClient struct, and populate it from the hints on the window */ - self = g_new0(ObClient, 1); + self = g_slice_new0(ObClient); self->obwin.type = OB_WINDOW_CLASS_CLIENT; self->window = window; self->prompt = prompt; @@ -311,6 +313,7 @@ void client_manage(Window window, ObPrompt *prompt) /* where the frame was placed is where the window was originally */ place = self->area; monitor = screen_physical_area_monitor(screen_find_monitor(&place)); + allmonitors = screen_physical_area_all_monitors(); /* figure out placement for the window if the window is new */ if (ob_state() == OB_STATE_RUNNING) { @@ -330,7 +333,23 @@ void client_manage(Window window, ObPrompt *prompt) "program + user specified" : "BADNESS !?")))), place.width, place.height); - place_client(self, &place.x, &place.y, settings); + obplaced = place_client(self, &place.x, &place.y, settings); + + /* watch for buggy apps that ask to be placed at (0,0) when there is + a strut there */ + if (!obplaced && place.x == 0 && place.y == 0 && + /* oldschool fullscreen windows are allowed */ + !(self->decorations == 0 && (RECT_EQUAL(place, *monitor) || + RECT_EQUAL(place, *allmonitors)))) + { + Rect *r; + + r = screen_area(self->desktop, SCREEN_AREA_ALL_MONITORS, NULL); + place.x = r->x; + place.y = r->y; + ob_debug("Moving buggy app from (0,0) to (%d,%d)", r->x, r->y); + g_slice_free(Rect, r); + } /* make sure the window is visible. */ client_find_onscreen(self, &place.x, &place.y, @@ -362,7 +381,8 @@ void client_manage(Window window, ObPrompt *prompt) makes its fullscreen window fit the screen but it is not USSize'd or USPosition'd) */ !(self->decorations == 0 && - RECT_EQUAL(place, *monitor))))); + (RECT_EQUAL(place, *monitor) || + RECT_EQUAL(place, *allmonitors)))))); } /* if the window isn't user-sized, then make it fit inside @@ -382,7 +402,8 @@ void client_manage(Window window, ObPrompt *prompt) /* don't shrink oldschool fullscreen windows to fit inside the struts (fixes Acroread, which makes its fullscreen window fit the screen but it is not USSize'd or USPosition'd) */ - !(self->decorations == 0 && RECT_EQUAL(place, *monitor))))) + !(self->decorations == 0 && (RECT_EQUAL(place, *monitor) || + RECT_EQUAL(place, *allmonitors)))))) { Rect *a = screen_area(self->desktop, SCREEN_AREA_ONE_MONITOR, &place); @@ -400,7 +421,7 @@ void client_manage(Window window, ObPrompt *prompt) place.width -= self->frame->size.left + self->frame->size.right; place.height -= self->frame->size.top + self->frame->size.bottom; - g_free(a); + g_slice_free(Rect, a); } ob_debug("placing window 0x%x at %d, %d with size %d x %d. " @@ -420,8 +441,8 @@ void client_manage(Window window, ObPrompt *prompt) client_apply_startup_state(self, place.x, place.y, place.width, place.height); - g_free(monitor); monitor = NULL; + allmonitors = NULL; ob_debug_type(OB_DEBUG_FOCUS, "Going to try activate new window? %s", activate ? "yes" : "no"); @@ -496,7 +517,7 @@ ObClient *client_fake_manage(Window window) /* do this minimal stuff to figure out the client's decorations */ - self = g_new0(ObClient, 1); + self = g_slice_new0(ObClient); self->window = window; client_get_all(self, FALSE); @@ -673,7 +694,7 @@ void client_unmanage(ObClient *self) g_free(self->role); g_free(self->client_machine); g_free(self->sm_client_id); - g_free(self); + g_slice_free(ObClient, self); } void client_fake_unmanage(ObClient *self) @@ -681,7 +702,7 @@ void client_fake_unmanage(ObClient *self) /* this is all that got allocated to get the decorations */ frame_free(self->frame); - g_free(self); + g_slice_free(ObClient, self); } static gboolean client_can_steal_focus(ObClient *self, Time steal_time, @@ -701,7 +722,7 @@ static gboolean client_can_steal_focus(ObClient *self, Time steal_time, /* This is focus stealing prevention */ ob_debug_type(OB_DEBUG_FOCUS, - "Want to focus new window 0x%x at time %u " + "Want to focus window 0x%x at time %u " "launched at %u (last user interaction time %u)", self->window, steal_time, launch_time, event_last_user_time); @@ -1063,7 +1084,7 @@ gboolean client_find_onscreen(ObClient *self, gint *x, gint *y, gint w, gint h, if (rudeb && !self->strut.bottom && *y + fh > a->y + a->height) *y = a->y + MAX(0, a->height - fh); - g_free(a); + g_slice_free(Rect, a); } /* get where the client should be */ @@ -2027,7 +2048,7 @@ void client_update_strut(ObClient *self) if (!got && OBT_PROP_GETA32(self->window, NET_WM_STRUT, CARDINAL, &data, &num)) { if (num == 4) { - Rect *a; + Rect const *a; got = TRUE; @@ -2040,7 +2061,6 @@ void client_update_strut(ObClient *self) a->x, a->x + a->width - 1, a->y, a->y + a->height - 1, a->x, a->x + a->width - 1); - g_free(a); } g_free(data); } @@ -2456,9 +2476,10 @@ gboolean client_has_parent(ObClient *self) static ObStackingLayer calc_layer(ObClient *self) { ObStackingLayer l; - Rect *monitor; + Rect const *monitor, *allmonitors; monitor = screen_physical_area_monitor(client_monitor(self)); + allmonitors = screen_physical_area_all_monitors(); if (self->type == OB_CLIENT_TYPE_DESKTOP) l = OB_STACKING_LAYER_DESKTOP; @@ -2472,7 +2493,8 @@ static ObStackingLayer calc_layer(ObClient *self) */ (self->decorations == 0 && !(self->max_horz && self->max_vert) && - RECT_EQUAL(self->area, *monitor))) && + (RECT_EQUAL(self->area, *monitor) || + RECT_EQUAL(self->area, *allmonitors)))) && /* you are fullscreen while you or your children are focused.. */ (client_focused(self) || client_search_focus_tree(self) || /* you can be fullscreen if you're on another desktop */ @@ -2487,8 +2509,6 @@ static ObStackingLayer calc_layer(ObClient *self) else if (self->below) l = OB_STACKING_LAYER_BELOW; else l = OB_STACKING_LAYER_NORMAL; - g_free(monitor); - return l; } @@ -2815,7 +2835,7 @@ void client_try_configure(ObClient *self, gint *x, gint *y, gint *w, gint *h, /* set the size and position if fullscreen */ if (self->fullscreen) { - Rect *a; + Rect const *a; guint i; i = screen_find_monitor(&desired); @@ -2828,8 +2848,6 @@ void client_try_configure(ObClient *self, gint *x, gint *y, gint *w, gint *h, user = FALSE; /* ignore if the client can't be moved/resized when it is fullscreening */ - - g_free(a); } else if (self->max_horz || self->max_vert) { Rect *a; guint i; @@ -2852,7 +2870,7 @@ void client_try_configure(ObClient *self, gint *x, gint *y, gint *w, gint *h, user = FALSE; /* ignore if the client can't be moved/resized when it is maximizing */ - g_free(a); + g_slice_free(Rect, a); } /* gets the client's position */ @@ -3124,6 +3142,9 @@ void client_fullscreen(ObClient *self, gboolean fs) if (fs) { self->pre_fullscreen_area = self->area; + self->pre_fullscreen_max_horz = self->max_horz; + self->pre_fullscreen_max_vert = self->max_vert; + /* if the window is maximized, its area isn't all that meaningful. save its premax area instead. */ if (self->max_horz) { @@ -3145,6 +3166,17 @@ void client_fullscreen(ObClient *self, gboolean fs) g_assert(self->pre_fullscreen_area.width > 0 && self->pre_fullscreen_area.height > 0); + self->max_horz = self->pre_fullscreen_max_horz; + self->max_vert = self->pre_fullscreen_max_vert; + if (self->max_horz) { + self->pre_max_area.x = self->pre_fullscreen_area.x; + self->pre_max_area.width = self->pre_fullscreen_area.width; + } + if (self->max_vert) { + self->pre_max_area.y = self->pre_fullscreen_area.y; + self->pre_max_area.height = self->pre_fullscreen_area.height; + } + x = self->pre_fullscreen_area.x; y = self->pre_fullscreen_area.y; w = self->pre_fullscreen_area.width; @@ -4214,31 +4246,38 @@ void client_find_edge_directional(ObClient *self, ObDirection dir, Rect *area = screen_area(self->desktop, i, NULL); detect_edge(*area, dir, my_head, my_size, my_edge_start, my_edge_size, dest, near_edge); - g_free(area); + g_slice_free(Rect, area); } /* search for edges of clients */ - for (it = client_list; it; it = g_list_next(it)) { - ObClient *cur = it->data; + if (((dir == OB_DIRECTION_NORTH || dir == OB_DIRECTION_SOUTH) && + !self->max_vert) || + ((dir == OB_DIRECTION_EAST || dir == OB_DIRECTION_WEST) && + !self->max_horz)) + { + for (it = client_list; it; it = g_list_next(it)) { + ObClient *cur = it->data; - /* skip windows to not bump into */ - if (cur == self) - continue; - if (cur->iconic) - continue; - if (self->desktop != cur->desktop && cur->desktop != DESKTOP_ALL && - cur->desktop != screen_desktop) - continue; + /* skip windows to not bump into */ + if (cur == self) + continue; + if (cur->iconic) + continue; + if (self->desktop != cur->desktop && cur->desktop != DESKTOP_ALL && + cur->desktop != screen_desktop) + continue; - ob_debug("trying window %s", cur->title); + ob_debug("trying window %s", cur->title); - detect_edge(cur->frame->area, dir, my_head, my_size, my_edge_start, + detect_edge(cur->frame->area, dir, my_head, my_size, my_edge_start, + my_edge_size, dest, near_edge); + } + dock_get_area(&dock_area); + detect_edge(dock_area, dir, my_head, my_size, my_edge_start, my_edge_size, dest, near_edge); } - dock_get_area(&dock_area); - detect_edge(dock_area, dir, my_head, my_size, my_edge_start, - my_edge_size, dest, near_edge); - g_free(a); + + g_slice_free(Rect, a); } void client_find_move_directional(ObClient *self, ObDirection dir,