diff options
| author | Dana Jansens <danakj@orodu.net> | 2003-05-24 21:47:06 +0000 |
|---|---|---|
| committer | Dana Jansens <danakj@orodu.net> | 2003-05-24 21:47:06 +0000 |
| commit | d1e355de2c6aae38cea3cdc0e0b902ea2b194e86 (patch) | |
| tree | dcb99d7232895e2b54ed58fbaa7d3a775da9ccfc /plugins/resistance | |
| parent | 927f99e4125743bbecf41b1aa7dbce9587fb6156 (diff) | |
this is a big one! im putting stats in here just cuz!
59 files changed, 1691 insertions(+), 607 deletions(-)
Adding the beginings of ObConf. Adding a resistance-config plugin for ObConf.
Creating an obparser library that obrender can use, the kernel can use, plugins can use, and ObConf and its plugins can use. (its just code for using libXml2)
Diffstat (limited to 'plugins/resistance')
| -rw-r--r-- | plugins/resistance/.cvsignore | 8 | ||||
| -rw-r--r-- | plugins/resistance/Makefile.am | 32 | ||||
| -rw-r--r-- | plugins/resistance/resistance.c | 275 | ||||
| -rw-r--r-- | plugins/resistance/resistance.glade | 109 | ||||
| -rw-r--r-- | plugins/resistance/resistance.gladep | 8 | ||||
| -rw-r--r-- | plugins/resistance/resistance.h | 2 | ||||
| -rw-r--r-- | plugins/resistance/resistance_config.c | 64 |
7 files changed, 498 insertions, 0 deletions
diff --git a/plugins/resistance/.cvsignore b/plugins/resistance/.cvsignore new file mode 100644 index 00000000..fe97c5fa --- /dev/null +++ b/plugins/resistance/.cvsignore @@ -0,0 +1,8 @@ +.deps +.libs +Makefile +Makefile.in +resistance-config.la +resistance.la +resistance_config_la-resistance_config.lo +resistance_la-resistance.lo diff --git a/plugins/resistance/Makefile.am b/plugins/resistance/Makefile.am new file mode 100644 index 00000000..9f95f947 --- /dev/null +++ b/plugins/resistance/Makefile.am @@ -0,0 +1,32 @@ +plugindir=$(libdir)/openbox/plugins + +CPPFLAGS=$(XFT_CFLAGS) $(GLIB_CFLAGS) $(LIBSN_CFLAGS) $(GL_CFLAGS) \ + $(XML_CFLAGS) @CPPFLAGS@ \ + -DPLUGINDIR=\"$(plugindir)\" + +INCLUDES=-I../.. -I../../tools + +plugin_LTLIBRARIES=resistance.la +if OBCONF +plugin_LTLIBRARIES+=resistance-config.la +endif + +resistance_la_CPPFLAGS=-DG_LOG_DOMAIN=\"Plugin-Resistance\" +resistance_la_LDFLAGS=-module -avoid-version +resistance_la_SOURCES=resistance.c + +if OBCONF +resistance_config_la_CPPFLAGS=-DG_LOG_DOMAIN=\"Plugin-Resistance\" \ + $(GTK_CFLAGS) $(GLADE_CFLAGS) +resistance_config_la_LDFLAGS=-module -avoid-version +resistance_config_la_SOURCES=resistance_config.c +endif + +noinst_HEADERS=resistance.h + +noinst_DATA=resistance.glade resistance.gladep + +MAINTAINERCLEANFILES= Makefile.in + +distclean-local: + $(RM) *\~ *.orig *.rej .\#* diff --git a/plugins/resistance/resistance.c b/plugins/resistance/resistance.c new file mode 100644 index 00000000..91c10c0e --- /dev/null +++ b/plugins/resistance/resistance.c @@ -0,0 +1,275 @@ +#include "kernel/dispatch.h" +#include "kernel/client.h" +#include "kernel/frame.h" +#include "kernel/stacking.h" +#include "kernel/screen.h" +#include "parser/parse.h" +#include "resistance.h" +#include <glib.h> + +static int resistance; +static gboolean resist_windows; + +static void parse_xml(xmlDocPtr doc, xmlNodePtr node, void *d) +{ + xmlNodePtr n; + + if ((n = parse_find_node("strength", node))) + resistance = parse_int(doc, n); + if ((n = parse_find_node("windows", node))) + resist_windows = parse_bool(doc, n); +} + +void plugin_setup_config() +{ + resistance = DEFAULT_RESISTANCE; + resist_windows = DEFAULT_RESIST_WINDOWS; + + parse_register("resistance", parse_xml, NULL); +} + +static void resist_move(Client *c, int *x, int *y) +{ + GList *it; + Rect *area; + int l, t, r, b; /* requested edges */ + int al, at, ar, ab; /* screen area edges */ + int cl, ct, cr, cb; /* current edges */ + int w, h; /* current size */ + Client *snapx = NULL, *snapy = NULL; + + w = c->frame->area.width; + h = c->frame->area.height; + + l = *x; + t = *y; + r = l + w - 1; + b = t + h - 1; + + cl = c->frame->area.x; + ct = c->frame->area.y; + cr = cl + c->frame->area.width - 1; + cb = ct + c->frame->area.height - 1; + + /* snap to other clients */ + if (resist_windows) + for (it = stacking_list; it != NULL; it = it->next) { + Client *target; + int tl, tt, tr, tb; /* 1 past the target's edges on each side */ + + if (!WINDOW_IS_CLIENT(it->data)) + continue; + target = it->data; + /* don't snap to self or non-visibles */ + if (!target->frame->visible || target == c) continue; + + tl = target->frame->area.x - 1; + tt = target->frame->area.y - 1; + tr = tl + target->frame->area.width + 1; + tb = tt + target->frame->area.height + 1; + + /* snapx and snapy ensure that the window snaps to the top-most + window edge available, without going all the way from + bottom-to-top in the stacking list + */ + if (snapx == NULL) { + if (ct < tb && cb > tt) { + if (cl >= tr && l < tr && l >= tr - resistance) + *x = tr, snapx = target; + else if (cr <= tl && r > tl && r <= tl + resistance) + *x = tl - w + 1, snapx = target; + if (snapx != NULL) { + /* try to corner snap to the window */ + if (ct > tt && t <= tt && t > tt - resistance) + *y = tt + 1, snapy = target; + else if (cb < tb && b >= tb && b < tb + resistance) + *y = tb - h, snapy = target; + } + } + } + if (snapy == NULL) { + if (cl < tr && cr > tl) { + if (ct >= tb && t < tb && t >= tb - resistance) + *y = tb, snapy = target; + else if (cb <= tt && b > tt && b <= tt + resistance) + *y = tt - h + 1, snapy = target; + if (snapy != NULL) { + /* try to corner snap to the window */ + if (cl > tl && l <= tl && l > tl - resistance) + *x = tl + 1, snapx = target; + else if (cr < tr && r >= tr && r < tr + resistance) + *x = tr - w, snapx = target; + } + } + } + + if (snapx && snapy) break; + } + + /* get the screen boundaries */ + area = screen_area(c->desktop); + al = area->x; + at = area->y; + ar = al + area->width - 1; + ab = at + area->height - 1; + + /* snap to screen edges */ + if (cl >= al && l < al && l >= al - resistance) + *x = al; + else if (cr <= ar && r > ar && r <= ar + resistance) + *x = ar - w + 1; + if (ct >= at && t < at && t >= at - resistance) + *y = at; + else if (cb <= ab && b > ab && b < ab + resistance) + *y = ab - h + 1; +} + +static void resist_size(Client *c, int *w, int *h, Corner corn) +{ + GList *it; + Client *target; /* target */ + int l, t, r, b; /* my left, top, right and bottom sides */ + int dlt, drb; /* my destination left/top and right/bottom sides */ + int tl, tt, tr, tb; /* target's left, top, right and bottom bottom sides */ + Rect *area; + int al, at, ar, ab; /* screen boundaries */ + Client *snapx = NULL, *snapy = NULL; + + /* don't snap windows with size increments */ + if (c->size_inc.width > 1 || c->size_inc.height > 1) + return; + + l = c->frame->area.x; + r = l + c->frame->area.width - 1; + t = c->frame->area.y; + b = t + c->frame->area.height - 1; + + /* get the screen boundaries */ + area = screen_area(c->desktop); + al = area->x; + at = area->y; + ar = al + area->width - 1; + ab = at + area->height - 1; + + /* snap to other windows */ + if (resist_windows) { + for (it = stacking_list; it != NULL; it = it->next) { + if (!WINDOW_IS_CLIENT(it->data)) + continue; + target = it->data; + + /* don't snap to invisibles or ourself */ + if (!target->frame->visible || target == c) continue; + + tl = target->frame->area.x; + tr = target->frame->area.x + target->frame->area.width - 1; + tt = target->frame->area.y; + tb = target->frame->area.y + target->frame->area.height - 1; + + if (snapx == NULL) { + /* horizontal snapping */ + if (t < tb && b > tt) { + switch (corn) { + case Corner_TopLeft: + case Corner_BottomLeft: + dlt = l; + drb = r + *w - c->frame->area.width; + if (r < tl && drb >= tl && drb < tl + resistance) + *w = tl - l, snapx = target; + break; + case Corner_TopRight: + case Corner_BottomRight: + dlt = l - *w + c->frame->area.width; + drb = r; + if (l > tr && dlt <= tr && dlt > tr - resistance) + *w = r - tr, snapx = target; + break; + } + } + } + + if (snapy == NULL) { + /* vertical snapping */ + if (l < tr && r > tl) { + switch (corn) { + case Corner_TopLeft: + case Corner_TopRight: + dlt = t; + drb = b + *h - c->frame->area.height; + if (b < tt && drb >= tt && drb < tt + resistance) + *h = tt - t, snapy = target; + break; + case Corner_BottomLeft: + case Corner_BottomRight: + dlt = t - *h + c->frame->area.height; + drb = b; + if (t > tb && dlt <= tb && dlt > tb - resistance) + *h = b - tb, snapy = target; + break; + } + } + } + + /* snapped both ways */ + if (snapx && snapy) break; + } + } + + /* snap to screen edges */ + + /* horizontal snapping */ + switch (corn) { + case Corner_TopLeft: + case Corner_BottomLeft: + dlt = l; + drb = r + *w - c->frame->area.width; + if (r <= ar && drb > ar && drb <= ar + resistance) + *w = ar - l + 1; + break; + case Corner_TopRight: + case Corner_BottomRight: + dlt = l - *w + c->frame->area.width; + drb = r; + if (l >= al && dlt < al && dlt >= al - resistance) + *w = r - al + 1; + break; + } + + /* vertical snapping */ + switch (corn) { + case Corner_TopLeft: + case Corner_TopRight: + dlt = t; + drb = b + *h - c->frame->area.height; + if (b <= ab && drb > ab && drb <= ab + resistance) + *h = ab - t + 1; + break; + case Corner_BottomLeft: + case Corner_BottomRight: + dlt = t - *h + c->frame->area.height; + drb = b; + if (t >= at && dlt < at && dlt >= at - resistance) + *h = b - at + 1; + break; + } +} + +static void event(ObEvent *e, void *foo) +{ + if (e->type == Event_Client_Moving) + resist_move(e->data.c.client, &e->data.c.num[0], &e->data.c.num[1]); + else if (e->type == Event_Client_Resizing) + resist_size(e->data.c.client, &e->data.c.num[0], &e->data.c.num[1], + e->data.c.num[2]); +} + +void plugin_startup() +{ + dispatch_register(Event_Client_Moving | Event_Client_Resizing, + (EventHandler)event, NULL); +} + +void plugin_shutdown() +{ + dispatch_register(0, (EventHandler)event, NULL); +} diff --git a/plugins/resistance/resistance.glade b/plugins/resistance/resistance.glade new file mode 100644 index 00000000..ecb52b0e --- /dev/null +++ b/plugins/resistance/resistance.glade @@ -0,0 +1,109 @@ +<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*--> +<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd"> + +<glade-interface> + +<widget class="GtkWindow" id="resistwindow"> + <property name="title" translatable="yes"></property> + <property name="type">GTK_WINDOW_POPUP</property> + <property name="window_position">GTK_WIN_POS_NONE</property> + <property name="modal">False</property> + <property name="resizable">True</property> + <property name="destroy_with_parent">False</property> + + <child> + <widget class="GtkVBox" id="vbox1"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">0</property> + + <child> + <widget class="GtkHBox" id="hbox2"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">6</property> + + <child> + <widget class="GtkLabel" id="label1"> + <property name="visible">True</property> + <property name="label" translatable="yes">_Strength</property> + <property name="use_underline">True</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.49</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="mnemonic_widget">resist_strength</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkSpinButton" id="resist_strength"> + <property name="visible">True</property> + <property name="tooltip" translatable="yes">Set to the amount of resistance to provide when moving or resizing a window past a screen or window edge. A value of 0 disables resistance.</property> + <property name="can_focus">True</property> + <property name="climb_rate">1</property> + <property name="digits">0</property> + <property name="numeric">True</property> + <property name="update_policy">GTK_UPDATE_ALWAYS</property> + <property name="snap_to_ticks">False</property> + <property name="wrap">False</property> + <property name="adjustment">1 0 30 1 10 10</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkHBox" id="hbox1"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">6</property> + + <child> + <widget class="GtkCheckButton" id="resist_windows"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="label" translatable="yes">Resist other _Windows</property> + <property name="use_underline">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="active">False</property> + <property name="inconsistent">False</property> + <property name="draw_indicator">True</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + </child> +</widget> + +</glade-interface> diff --git a/plugins/resistance/resistance.gladep b/plugins/resistance/resistance.gladep new file mode 100644 index 00000000..1951d46b --- /dev/null +++ b/plugins/resistance/resistance.gladep @@ -0,0 +1,8 @@ +<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*--> +<!DOCTYPE glade-project SYSTEM "http://glade.gnome.org/glade-project-2.0.dtd"> + +<glade-project> + <name>resistance</name> + <program_name>resistance</program_name> + <gnome_support>FALSE</gnome_support> +</glade-project> diff --git a/plugins/resistance/resistance.h b/plugins/resistance/resistance.h new file mode 100644 index 00000000..5bec224b --- /dev/null +++ b/plugins/resistance/resistance.h @@ -0,0 +1,2 @@ +#define DEFAULT_RESISTANCE 10 +#define DEFAULT_RESIST_WINDOWS TRUE diff --git a/plugins/resistance/resistance_config.c b/plugins/resistance/resistance_config.c new file mode 100644 index 00000000..1384fe3f --- /dev/null +++ b/plugins/resistance/resistance_config.c @@ -0,0 +1,64 @@ +#include "plugins/obconf_interface.h" +#include "parser/parse.h" +#include "resistance.h" +#include <gtk/gtk.h> +#include <glade/glade.h> + +static GtkWidget *conf_widget; +static GtkCheckButton *conf_resist_windows; +static GtkSpinButton *conf_resist_strength; +static gboolean conf_edited = FALSE; + +int plugin_interface_version() { return OBCONF_INTERFACE_VERSION; } + +char *plugin_name() { return "Resistance"; } +char *plugin_plugin_name() { return "resistance"; } +void plugin_icon() {} + +GtkWidget *plugin_toplevel_widget() { return conf_widget; } + +gboolean plugin_edited() { return conf_edited; } + +void plugin_load(xmlDocPtr doc, xmlNodePtr root) +{ + xmlNodePtr node, n; + + gtk_spin_button_set_value(conf_resist_strength, DEFAULT_RESISTANCE); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(conf_resist_windows), + DEFAULT_RESIST_WINDOWS); + + node = parse_find_node("resistance", root); + while (node) { + if ((n = parse_find_node("strength", node))) + gtk_spin_button_set_value(conf_resist_strength, + parse_int(doc, n)); + if ((n = parse_find_node("windows", node))) + gtk_toggle_button_set_active + (GTK_TOGGLE_BUTTON(conf_resist_windows), + parse_bool(doc, n)); + + node = parse_find_node("resistance", node->next); + } +} + +void plugin_save(xmlDocPtr doc, xmlNodePtr root) +{ +} + +void plugin_startup() +{ + GladeXML *xml; + + xml = glade_xml_new("obconf.glade", NULL, NULL); + glade_xml_signal_autoconnect(xml); + + conf_widget = glade_xml_get_widget(xml, "resistwindow"); + conf_resist_strength = + GTK_SPIN_BUTTON(glade_xml_get_widget(xml, "resist_strength")); + conf_resist_windows = + GTK_CHECK_BUTTON(glade_xml_get_widget(xml, "resist_windows")); +} + +void plugin_shutdown() +{ +} |
