all repos — openbox @ 5e06be6abb68a95aa9cafc5a6f0c5e295ebe9bee

openbox fork - make it a bit more like ryudo

add window placement routines to the kernel
Dana Jansens danakj@orodu.net
commit

5e06be6abb68a95aa9cafc5a6f0c5e295ebe9bee

parent

db4b0e6270a7f943b1e1a3238283673a78ffd469

3 files changed, 148 insertions(+), 18 deletions(-)

jump to
M Makefile.amMakefile.am

@@ -26,7 +26,6 @@ kernel/openbox \

tools/kdetrayproxy/kdetrayproxy plugin_LTLIBRARIES = \ - plugins/placement/placement.la \ plugins/menu/client_menu.la \ plugins/menu/client_list_menu.la # plugins/menu/timed_menu.la \

@@ -168,6 +167,8 @@ kernel/moveresize.h \

kernel/mwm.h \ kernel/openbox.c \ kernel/openbox.h \ + kernel/place.c \ + kernel/place.h \ kernel/plugin.c \ kernel/plugin.h \ kernel/popup.c \

@@ -193,23 +194,6 @@ kernel/window.h \

kernel/xerror.c \ kernel/xerror.h \ plugins/interface.h - -## plugins/placement ## - -plugins_placement_placement_la_CPPFLAGS = \ - $(XFT_CFLAGS) \ - $(GLIB_CFLAGS) \ - $(LIBSN_CFLAGS) \ - $(XML_CFLAGS) \ - -DPLUGINDIR=\"$(plugindir)\" \ - -DG_LOG_DOMAIN=\"Plugin-Placement\" -plugins_placement_placement_la_LDFLAGS = \ - -module \ - -avoid-version -plugins_placement_placement_la_SOURCES = \ - plugins/placement/placement.c \ - plugins/placement/history.c \ - plugins/placement/history.h ## plugins/menu ##
A openbox/place.c

@@ -0,0 +1,136 @@

+#include "client.h" +#include "group.h" +#include "screen.h" +#include "frame.h" + +static Rect* pick_head(ObClient *c) +{ + /* try direct parent first */ + if (c->transient_for && c->transient_for != OB_TRAN_GROUP) { + return screen_area_monitor(c->desktop, + client_monitor(c->transient_for)); + } + + /* more than one guy in his group (more than just him) */ + if (c->group && c->group->members->next) { + GSList *it; + + /* try on the client's desktop */ + for (it = c->group->members; it; it = g_slist_next(it)) { + ObClient *itc = it->data; + if (itc != c && + (itc->desktop == c->desktop || + itc->desktop == DESKTOP_ALL || c->desktop == DESKTOP_ALL)) + return screen_area_monitor(c->desktop, + client_monitor(it->data)); + } + + /* try on all desktops */ + for (it = c->group->members; it; it = g_slist_next(it)) { + ObClient *itc = it->data; + if (itc != c) + return screen_area_monitor(c->desktop, + client_monitor(it->data)); + } + } + + return NULL; +} + +static gboolean place_random(ObClient *client, gint *x, gint *y) +{ + int l, r, t, b; + Rect *area; + + area = pick_head(client); + if (!area) + area = screen_area_monitor(client->desktop, + g_random_int_range(0, screen_num_monitors)); + + l = area->x; + t = area->y; + r = area->x + area->width - client->frame->area.width; + b = area->y + area->height - client->frame->area.height; + + if (r > l) *x = g_random_int_range(l, r + 1); + else *x = 0; + if (b > t) *y = g_random_int_range(t, b + 1); + else *y = 0; + + /* get where the client should be */ + frame_frame_gravity(client->frame, x, y); + + return TRUE; +} + +static gboolean place_transient(ObClient *client, gint *x, gint *y) +{ + if (client->transient_for) { + if (client->transient_for != OB_TRAN_GROUP) { + ObClient *c = client; + ObClient *p = client->transient_for; + *x = (p->frame->area.width - c->frame->area.width) / 2 + + p->frame->area.x; + *y = (p->frame->area.height - c->frame->area.height) / 2 + + p->frame->area.y; + return TRUE; + } else { + GSList *it; + gboolean first = TRUE; + int l, r, t, b; + for (it = client->group->members; it; it = it->next) { + ObClient *m = it->data; + if (!(m == client || m->transient_for)) { + if (first) { + l = m->frame->area.x; + t = m->frame->area.y; + r = m->frame->area.x + m->frame->area.width - 1; + b = m->frame->area.y + m->frame->area.height - 1; + first = FALSE; + } else { + l = MIN(l, m->frame->area.x); + t = MIN(t, m->frame->area.y); + r = MAX(r, m->frame->area.x +m->frame->area.width - 1); + b = MAX(b, m->frame->area.y +m->frame->area.height -1); + } + } + } + if (!first) { + *x = ((r + 1 - l) - client->frame->area.width) / 2 + l; + *y = ((b + 1 - t) - client->frame->area.height) / 2 + t; + return TRUE; + } + } + } + return FALSE; +} + +static gboolean place_dialog(ObClient *client, gint *x, gint *y) +{ + /* center parentless dialogs on the screen */ + if (client->type == OB_CLIENT_TYPE_DIALOG) { + Rect *area; + + area = pick_head(client); + if (!area) + area = screen_area_monitor(client->desktop, 0); + + *x = (area->width - client->frame->area.width) / 2 + area->x; + *y = (area->height - client->frame->area.height) / 2 + area->y; + return TRUE; + } + return FALSE; +} + +void place_client(ObClient *client, gint *x, gint *y) +{ + if (client->positioned) + return; + if (place_transient(client, x, y)) + return; + if (place_dialog(client, x, y)) + return; + if (place_random(client, x, y)) + return; + g_assert_not_reached(); /* the last one better succeed */ +}
A openbox/place.h

@@ -0,0 +1,10 @@

+#ifndef ob__place_h +#define ob__place_h + +#include <glib.h> + +struct _ObClient; + +void place_client(ObClient *client, gint *x, gint *y); + +#endif