From: Dana Jansens Date: Fri, 29 Aug 2003 06:40:35 +0000 (+0000) Subject: add window placement routines to the kernel X-Git-Url: https://git.brokenzipper.com/gitweb?a=commitdiff_plain;h=5e06be6abb68a95aa9cafc5a6f0c5e295ebe9bee;p=chaz%2Fopenbox add window placement routines to the kernel --- diff --git a/Makefile.am b/Makefile.am index 4b162ed4..6407ee8c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -26,7 +26,6 @@ bin_PROGRAMS = \ 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_openbox_SOURCES = \ kernel/mwm.h \ kernel/openbox.c \ kernel/openbox.h \ + kernel/place.c \ + kernel/place.h \ kernel/plugin.c \ kernel/plugin.h \ kernel/popup.c \ @@ -194,23 +195,6 @@ kernel_openbox_SOURCES = \ 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 ## plugins_menu_timed_menu_la_CPPFLAGS = \ diff --git a/openbox/place.c b/openbox/place.c new file mode 100644 index 00000000..91beea4b --- /dev/null +++ b/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 */ +} diff --git a/openbox/place.h b/openbox/place.h new file mode 100644 index 00000000..3ff1524c --- /dev/null +++ b/openbox/place.h @@ -0,0 +1,10 @@ +#ifndef ob__place_h +#define ob__place_h + +#include + +struct _ObClient; + +void place_client(ObClient *client, gint *x, gint *y); + +#endif