+++ /dev/null
-ob3
-Makefile.in
-.libs
-.deps
-Makefile
+++ /dev/null
-localedir=$(datadir)/locale
-scriptdir = $(libdir)/openbox/python
-
-CPPFLAGS=$(PYTHON_CFLAGS) $(GLIB_CFLAGS) @CPPFLAGS@ \
--DLOCALEDIR=\"$(localedir)\" \
--DSCRIPTDIR=\"$(scriptdir)\" \
--DG_LOG_DOMAIN=\"Openbox\"
-
-LIBS=$(PYTHON_LIBS) $(GLIB_LIBS) @LIBS@
-
-bin_PROGRAMS= ob3
-
-ob3_LDADD=@LIBINTL@
-ob3_LDFLAGS=-export-dynamic
-ob3_SOURCES=client.c event.c extensions.c focus.c frame.c openbox.c prop.c \
- python.c screen.c stacking.c xerror.c hooks.c eventdata.c obexport.c \
- clientwrap.c screenwrap.c kbind.c mbind.c
-
-noinst_HEADERS=client.h event.h extensions.h focus.h frame.h geom.h gettext.h \
- openbox.h prop.h python.h screen.h stacking.h xerror.h hooks.h \
- eventdata.h clientwrap.h obexport.h screenwrap.h kbind.h mbind.h
-
-MAINTAINERCLEANFILES= Makefile.in
-
-#if CVS
-#ob3.i: $(wildcard *.h)
-# @touch $@
-
-#ob3_wrap.c: ob3.i
-# $(SWIG) $(SWIG_PYTHON_OPT) $(filter -I%,$(CPPFLAGS)) -o $@ $<
-#endif
-
-distclean-local:
- $(RM) *\~ *.orig *.rej .\#*
+++ /dev/null
-#include "client.h"
-#include "screen.h"
-#include "prop.h"
-#include "extensions.h"
-#include "frame.h"
-#include "event.h"
-#include "focus.h"
-#include "clientwrap.h"
-#include "stacking.h"
-#include "hooks.h"
-#include "mbind.h"
-#include <X11/Xutil.h>
-
-/*! The event mask to grab on client windows */
-#define CLIENT_EVENTMASK (PropertyChangeMask | FocusChangeMask | \
- StructureNotifyMask)
-
-#define CLIENT_NOPROPAGATEMASK (ButtonPressMask | ButtonReleaseMask | \
- ButtonMotionMask)
-
-GSList *client_list = NULL;
-GHashTable *client_map = NULL;
-
-static void client_get_all(Client *self);
-static void client_toggle_border(Client *self, gboolean show);
-static void client_get_area(Client *self);
-static void client_get_desktop(Client *self);
-static void client_get_state(Client *self);
-static void client_get_shaped(Client *self);
-static void client_get_mwm_hints(Client *self);
-static void client_get_gravity(Client *self);
-static void client_change_allowed_actions(Client *self);
-static void client_change_state(Client *self);
-static Client *search_focus_tree(Client *node, Client *skip);
-static void client_apply_startup_state(Client *self);
-static Client *search_modal_tree(Client *node, Client *skip);
-
-static guint map_hash(Window w) { return w; }
-static gboolean map_key_comp(Window w1, Window w2) { return w1 == w2; }
-
-void client_startup()
-{
- client_map = g_hash_table_new((GHashFunc)map_hash,
- (GEqualFunc)map_key_comp);
- client_set_list();
-}
-
-void client_shutdown()
-{
- g_hash_table_destroy(client_map);
-}
-
-void client_set_list()
-{
- Window *windows, *win_it;
- GSList *it;
- guint size = g_slist_length(client_list);
-
- /* create an array of the window ids */
- if (size > 0) {
- windows = g_new(Window, size);
- win_it = windows;
- for (it = client_list; it != NULL; it = it->next, ++win_it)
- *win_it = ((Client*)it->data)->window;
- } else
- windows = NULL;
-
- PROP_SET32A(ob_root, net_client_list, window, windows, size);
-
- if (windows)
- g_free(windows);
-
- stacking_set_list();
-}
-
-void client_manage_all()
-{
- unsigned int i, j, nchild;
- Window w, *children;
- XWMHints *wmhints;
- XWindowAttributes attrib;
-
- XQueryTree(ob_display, ob_root, &w, &w, &children, &nchild);
-
- /* remove all icon windows from the list */
- for (i = 0; i < nchild; i++) {
- if (children[i] == None) continue;
- wmhints = XGetWMHints(ob_display, children[i]);
- if (wmhints) {
- if ((wmhints->flags & IconWindowHint) &&
- (wmhints->icon_window != children[i]))
- for (j = 0; j < nchild; j++)
- if (children[j] == wmhints->icon_window) {
- children[j] = None;
- break;
- }
- XFree(wmhints);
- }
- }
-
- for (i = 0; i < nchild; ++i) {
- if (children[i] == None)
- continue;
- if (XGetWindowAttributes(ob_display, children[i], &attrib)) {
- if (attrib.override_redirect) continue;
-
- if (attrib.map_state != IsUnmapped)
- client_manage(children[i]);
- }
- }
- XFree(children);
-}
-
-void client_manage(Window window)
-{
- Client *client;
- XEvent e;
- XWindowAttributes attrib;
- XSetWindowAttributes attrib_set;
- XWMHints *wmhint;
-
- XGrabServer(ob_display);
- XSync(ob_display, FALSE);
-
- /* check if it has already been unmapped by the time we started mapping
- the grab does a sync so we don't have to here */
- if (XCheckTypedWindowEvent(ob_display, window, DestroyNotify, &e) ||
- XCheckTypedWindowEvent(ob_display, window, UnmapNotify, &e)) {
- XPutBackEvent(ob_display, &e);
-
- XUngrabServer(ob_display);
- XFlush(ob_display);
- return; /* don't manage it */
- }
-
- /* make sure it isn't an override-redirect window */
- if (!XGetWindowAttributes(ob_display, window, &attrib) ||
- attrib.override_redirect) {
- XUngrabServer(ob_display);
- XFlush(ob_display);
- return; /* don't manage it */
- }
-
- /* is the window a docking app */
- if ((wmhint = XGetWMHints(ob_display, window))) {
- if ((wmhint->flags & StateHint) &&
- wmhint->initial_state == WithdrawnState) {
- /* XXX: make dock apps work! */
- XUngrabServer(ob_display);
- XFlush(ob_display);
- XFree(wmhint);
- return;
- }
- XFree(wmhint);
- }
-
- /* choose the events we want to receive on the CLIENT window */
- attrib_set.event_mask = CLIENT_EVENTMASK;
- attrib_set.do_not_propagate_mask = CLIENT_NOPROPAGATEMASK;
- XChangeWindowAttributes(ob_display, window,
- CWEventMask|CWDontPropagate, &attrib_set);
-
-
- /* create the Client struct, and populate it from the hints on the
- window */
- client = g_new(Client, 1);
- client->window = window;
- client_get_all(client);
-
- /* remove the client's border (and adjust re gravity) */
- client_toggle_border(client, FALSE);
-
- /* specify that if we exit, the window should not be destroyed and should
- be reparented back to root automatically */
- XChangeSaveSet(ob_display, window, SetModeInsert);
-
- /* create the decoration frame for the client window */
- client->frame = frame_new(client);
-
- frame_grab_client(client->frame);
-
- client_apply_startup_state(client);
-
- XUngrabServer(ob_display);
- XFlush(ob_display);
-
- client_list = g_slist_append(client_list, client);
- stacking_list = g_list_append(stacking_list, client);
- g_hash_table_insert(client_map, (gpointer)window, client);
-
- stacking_raise(client);
-
- screen_update_struts();
-
- LOGICALHOOK(NewWindow, g_quark_try_string("client"), client);
-
- client_showhide(client);
-
- /* grab all mouse bindings */
- mbind_grab_all(client, TRUE);
-
- /* update the list hints */
- client_set_list();
-
- g_message("Managed window 0x%lx frame 0x%lx", window,
- client->frame->window);
-}
-
-void client_unmanage_all()
-{
- while (client_list != NULL) {
- client_unmanage(client_list->data);
- }
-}
-
-void client_unmanage(Client *client)
-{
- int j;
- GSList *it;
-
- g_message("Unmanaging window: %lx", client->window);
-
- LOGICALHOOK(CloseWindow, g_quark_try_string("client"), client);
-
- /* remove the window from our save set */
- XChangeSaveSet(ob_display, client->window, SetModeDelete);
-
- /* we dont want events no more */
- XSelectInput(ob_display, client->window, NoEventMask);
-
- /* ungrab any mouse bindings */
- mbind_grab_all(client, FALSE);
-
- frame_hide(client->frame);
-
- /* give the client its border back */
- client_toggle_border(client, TRUE);
-
- /* reparent the window out of the frame */
- frame_release_client(client->frame);
-
- client_list = g_slist_remove(client_list, client);
- stacking_list = g_list_remove(stacking_list, client);
- g_hash_table_remove(client_map, (gpointer)client->window);
-
- /* once the client is out of the list, update the struts to remove it's
- influence */
- screen_update_struts();
-
- frame_free(client->frame);
-
- /* notify the wrapper that its useless now */
- if (client->wrap != NULL)
- client->wrap->client = NULL;
-
- /* tell our parent that we're gone */
- if (client->transient_for != NULL)
- client->transient_for->transients =
- g_slist_remove(client->transient_for->transients, client);
-
- /* tell our transients that we're gone */
- for (it = client->transients; it != NULL; it = it->next) {
- Client *t = ((Client*)it->data)->transient_for;
- ((Client*)it->data)->transient_for = NULL;
- if (t != NULL)
- client_calc_layer(it->data);
- }
-
- /* unfocus the client (calls the focus callbacks) (we're out of the
- transient lists already, so being modal doesn't matter) */
- if (client->focused)
- client_unfocus(client);
-
- if (ob_state != State_Exiting) {
- /* these values should not be persisted across a window
- unmapping/mapping */
- prop_erase(client->window, prop_atoms.net_wm_desktop);
- prop_erase(client->window, prop_atoms.net_wm_state);
- } else {
- /* if we're left in an iconic state, the client wont be mapped. this is
- bad, since we will no longer be managing the window on restart */
- if (client->iconic)
- XMapWindow(ob_display, client->window);
- }
-
- /* free all data allocated in the client struct */
- g_slist_free(client->transients);
- for (j = 0; j < client->nicons; ++j)
- g_free(client->icons[j].data);
- if (client->nicons > 0)
- g_free(client->icons);
- g_free(client->title);
- g_free(client->icon_title);
- g_free(client->res_name);
- g_free(client->res_class);
- g_free(client->role);
- g_free(client);
-
- /* update the list hints */
- client_set_list();
-}
-
-static void client_toggle_border(Client *self, gboolean show)
-{
- /* adjust our idea of where the client is, based on its border. When the
- border is removed, the client should now be considered to be in a
- different position.
- when re-adding the border to the client, the same operation needs to be
- reversed. */
- int oldx = self->area.x, oldy = self->area.y;
- int x = oldx, y = oldy;
- switch(self->gravity) {
- default:
- case NorthWestGravity:
- case WestGravity:
- case SouthWestGravity:
- break;
- case NorthEastGravity:
- case EastGravity:
- case SouthEastGravity:
- if (show) x -= self->border_width * 2;
- else x += self->border_width * 2;
- break;
- case NorthGravity:
- case SouthGravity:
- case CenterGravity:
- case ForgetGravity:
- case StaticGravity:
- if (show) x -= self->border_width;
- else x += self->border_width;
- break;
- }
- switch(self->gravity) {
- default:
- case NorthWestGravity:
- case NorthGravity:
- case NorthEastGravity:
- break;
- case SouthWestGravity:
- case SouthGravity:
- case SouthEastGravity:
- if (show) y -= self->border_width * 2;
- else y += self->border_width * 2;
- break;
- case WestGravity:
- case EastGravity:
- case CenterGravity:
- case ForgetGravity:
- case StaticGravity:
- if (show) y -= self->border_width;
- else y += self->border_width;
- break;
- }
- self->area.x = x;
- self->area.y = y;
-
- if (show) {
- XSetWindowBorderWidth(ob_display, self->window, self->border_width);
-
- /* move the client so it is back it the right spot _with_ its
- border! */
- if (x != oldx || y != oldy)
- XMoveWindow(ob_display, self->window, x, y);
- } else
- XSetWindowBorderWidth(ob_display, self->window, 0);
-}
-
-
-static void client_get_all(Client *self)
-{
- /* update EVERYTHING!! */
-
- self->ignore_unmaps = 0;
-
- /* defaults */
- self->frame = NULL;
- self->title = self->icon_title = NULL;
- self->res_name = self->res_class = self->role = NULL;
- self->wmstate = NormalState;
- self->focused = FALSE;
- self->transient = FALSE;
- self->transients = NULL;
- self->transient_for = NULL;
- self->layer = -1;
- self->urgent = FALSE;
- self->positioned = FALSE;
- self->disabled_decorations = 0;
- self->group = None;
- self->nicons = 0;
- self->wrap = NULL;
-
- client_get_area(self);
- client_get_desktop(self);
- client_get_state(self);
- client_get_shaped(self);
-
- client_update_transient_for(self);
- client_get_mwm_hints(self);
- client_get_type(self);/* this can change the mwmhints for special cases */
-
- client_update_protocols(self);
-
- client_get_gravity(self); /* get the attribute gravity */
- client_update_normal_hints(self); /* this may override the attribute
- gravity */
-
- /* got the type, the mwmhints, the protocols, and the normal hints
- (min/max sizes), so we're ready to set up the decorations/functions */
- client_setup_decor_and_functions(self);
-
- client_update_wmhints(self);
- client_update_title(self);
- client_update_icon_title(self);
- client_update_class(self);
- client_update_strut(self);
- client_update_icons(self);
- client_update_kwm_icon(self);
-
- /* this makes sure that these windows appear on all desktops */
- if (self->type == Type_Desktop)
- self->desktop = DESKTOP_ALL;
-
- /* set the desktop hint, to make sure that it always exists, and to
- reflect any changes we've made here */
- PROP_SET32(self->window, net_wm_desktop, cardinal, self->desktop);
-
- client_change_state(self);
-}
-
-static void client_get_area(Client *self)
-{
- XWindowAttributes wattrib;
- Status ret;
-
- ret = XGetWindowAttributes(ob_display, self->window, &wattrib);
- g_assert(ret != BadWindow);
-
- RECT_SET(self->area, wattrib.x, wattrib.y, wattrib.width, wattrib.height);
- self->border_width = wattrib.border_width;
-}
-
-static void client_get_desktop(Client *self)
-{
- unsigned int d;
-
- if (PROP_GET32(self->window, net_wm_desktop, cardinal, d)) {
- if (d >= screen_desktop && d != DESKTOP_ALL)
- d = screen_desktop - 1;
- self->desktop = d;
- } else {
- /* defaults to the current desktop */
- self->desktop = screen_desktop;
- }
-}
-
-static void client_get_state(Client *self)
-{
- gulong *state;
- gulong num;
-
- self->modal = self->shaded = self->max_horz = self->max_vert =
- self->fullscreen = self->above = self->below = self->iconic =
- self->skip_taskbar = self->skip_pager = FALSE;
-
- if (PROP_GET32U(self->window, net_wm_state, atom, state, num)) {
- gulong i;
- for (i = 0; i < num; ++i) {
- if (state[i] == prop_atoms.net_wm_state_modal)
- self->modal = TRUE;
- else if (state[i] == prop_atoms.net_wm_state_shaded)
- self->shaded = TRUE;
- else if (state[i] == prop_atoms.net_wm_state_hidden)
- self->iconic = TRUE;
- else if (state[i] == prop_atoms.net_wm_state_skip_taskbar)
- self->skip_taskbar = TRUE;
- else if (state[i] == prop_atoms.net_wm_state_skip_pager)
- self->skip_pager = TRUE;
- else if (state[i] == prop_atoms.net_wm_state_fullscreen)
- self->fullscreen = TRUE;
- else if (state[i] == prop_atoms.net_wm_state_maximized_vert)
- self->max_vert = TRUE;
- else if (state[i] == prop_atoms.net_wm_state_maximized_horz)
- self->max_horz = TRUE;
- else if (state[i] == prop_atoms.net_wm_state_above)
- self->above = TRUE;
- else if (state[i] == prop_atoms.net_wm_state_below)
- self->below = TRUE;
- }
-
- g_free(state);
- }
-}
-
-static void client_get_shaped(Client *self)
-{
- self->shaped = FALSE;
-#ifdef SHAPE
- if (extensions_shape) {
- int foo;
- guint ufoo;
- int s;
-
- XShapeSelectInput(ob_display, self->window, ShapeNotifyMask);
-
- XShapeQueryExtents(ob_display, self->window, &s, &foo,
- &foo, &ufoo, &ufoo, &foo, &foo, &foo, &ufoo,
- &ufoo);
- self->shaped = (s != 0);
- }
-#endif
-}
-
-void client_update_transient_for(Client *self)
-{
- Window t = None;
- Client *c = NULL;
-
- if (XGetTransientForHint(ob_display, self->window, &t) &&
- t != self->window) { /* cant be transient to itself! */
- self->transient = TRUE;
- c = g_hash_table_lookup(client_map, (gpointer)t);
- g_assert(c != self);/* if this happens then we need to check for it*/
-
- if (!c /*XXX: && _group*/) {
- /* not transient to a client, see if it is transient for a
- group */
- if (/*t == _group->leader() || */
- t == None ||
- t == ob_root) {
- /* window is a transient for its group! */
- /* XXX: for now this is treated as non-transient.
- this needs to be fixed! */
- }
- }
- } else
- self->transient = FALSE;
-
- /* if anything has changed... */
- if (c != self->transient_for) {
- if (self->transient_for)
- /* remove from old parent */
- g_slist_remove(self->transient_for->transients, self);
- self->transient_for = c;
- if (self->transient_for)
- /* add to new parent */
- g_slist_append(self->transient_for->transients, self);
- }
-}
-
-static void client_get_mwm_hints(Client *self)
-{
- unsigned long num;
- unsigned long *hints;
-
- self->mwmhints.flags = 0; /* default to none */
-
- if (PROP_GET32U(self->window, motif_wm_hints, motif_wm_hints, hints, num)) {
- if (num >= MWM_ELEMENTS) {
- self->mwmhints.flags = hints[0];
- self->mwmhints.functions = hints[1];
- self->mwmhints.decorations = hints[2];
- }
- g_free(hints);
- }
-}
-
-void client_get_type(Client *self)
-{
- gulong *val, num, i;
-
- self->type = -1;
-
- if (PROP_GET32U(self->window, net_wm_window_type, atom, val, num)) {
- /* use the first value that we know about in the array */
- for (i = 0; i < num; ++i) {
- if (val[i] == prop_atoms.net_wm_window_type_desktop)
- self->type = Type_Desktop;
- else if (val[i] == prop_atoms.net_wm_window_type_dock)
- self->type = Type_Dock;
- else if (val[i] == prop_atoms.net_wm_window_type_toolbar)
- self->type = Type_Toolbar;
- else if (val[i] == prop_atoms.net_wm_window_type_menu)
- self->type = Type_Menu;
- else if (val[i] == prop_atoms.net_wm_window_type_utility)
- self->type = Type_Utility;
- else if (val[i] == prop_atoms.net_wm_window_type_splash)
- self->type = Type_Splash;
- else if (val[i] == prop_atoms.net_wm_window_type_dialog)
- self->type = Type_Dialog;
- else if (val[i] == prop_atoms.net_wm_window_type_normal)
- self->type = Type_Normal;
- else if (val[i] == prop_atoms.kde_net_wm_window_type_override) {
- /* prevent this window from getting any decor or
- functionality */
- self->mwmhints.flags &= (MwmFlag_Functions |
- MwmFlag_Decorations);
- self->mwmhints.decorations = 0;
- self->mwmhints.functions = 0;
- }
- if (self->type != (WindowType) -1)
- break; /* grab the first legit type */
- }
- g_free(val);
- }
-
- if (self->type == (WindowType) -1) {
- /*the window type hint was not set, which means we either classify
- ourself as a normal window or a dialog, depending on if we are a
- transient. */
- if (self->transient)
- self->type = Type_Dialog;
- else
- self->type = Type_Normal;
- }
-}
-
-void client_update_protocols(Client *self)
-{
- Atom *proto;
- int num_return = 0, i;
-
- self->focus_notify = FALSE;
- self->delete_window = FALSE;
-
- if (XGetWMProtocols(ob_display, self->window, &proto, &num_return)) {
- for (i = 0; i < num_return; ++i) {
- if (proto[i] == prop_atoms.wm_delete_window) {
- /* this means we can request the window to close */
- self->delete_window = TRUE;
- } else if (proto[i] == prop_atoms.wm_take_focus)
- /* if this protocol is requested, then the window will be
- notified whenever we want it to receive focus */
- self->focus_notify = TRUE;
- }
- XFree(proto);
- }
-}
-
-static void client_get_gravity(Client *self)
-{
- XWindowAttributes wattrib;
- Status ret;
-
- ret = XGetWindowAttributes(ob_display, self->window, &wattrib);
- g_assert(ret != BadWindow);
- self->gravity = wattrib.win_gravity;
-}
-
-void client_update_normal_hints(Client *self)
-{
- XSizeHints size;
- long ret;
- int oldgravity = self->gravity;
-
- /* defaults */
- self->min_ratio = 0.0f;
- self->max_ratio = 0.0f;
- SIZE_SET(self->size_inc, 1, 1);
- SIZE_SET(self->base_size, 0, 0);
- SIZE_SET(self->min_size, 0, 0);
- SIZE_SET(self->max_size, G_MAXINT, G_MAXINT);
-
- /* get the hints from the window */
- if (XGetWMNormalHints(ob_display, self->window, &size, &ret)) {
- self->positioned = (size.flags & (PPosition|USPosition));
-
- if (size.flags & PWinGravity) {
- self->gravity = size.win_gravity;
-
- /* if the client has a frame, i.e. has already been mapped and
- is changing its gravity */
- if (self->frame && self->gravity != oldgravity) {
- /* move our idea of the client's position based on its new
- gravity */
- self->area.x = self->frame->area.x;
- self->area.y = self->frame->area.y;
- frame_frame_gravity(self->frame,
- &self->area.x, &self->area.y);
- }
- }
-
- if (size.flags & PAspect) {
- if (size.min_aspect.y)
- self->min_ratio = size.min_aspect.x / size.min_aspect.y;
- if (size.max_aspect.y)
- self->max_ratio = size.max_aspect.x / size.max_aspect.y;
- }
-
- if (size.flags & PMinSize)
- SIZE_SET(self->min_size, size.min_width, size.min_height);
-
- if (size.flags & PMaxSize)
- SIZE_SET(self->max_size, size.max_width, size.max_height);
-
- if (size.flags & PBaseSize)
- SIZE_SET(self->base_size, size.base_width, size.base_height);
-
- if (size.flags & PResizeInc)
- SIZE_SET(self->size_inc, size.width_inc, size.height_inc);
- }
-}
-
-void client_setup_decor_and_functions(Client *self)
-{
- /* start with everything (cept fullscreen) */
- self->decorations = Decor_Titlebar | Decor_Handle | Decor_Border |
- Decor_Icon | Decor_AllDesktops | Decor_Iconify | Decor_Maximize;
- self->functions = Func_Resize | Func_Move | Func_Iconify | Func_Maximize |
- Func_Shade;
- if (self->delete_window) {
- self->decorations |= Decor_Close;
- self->functions |= Func_Close;
- }
-
- if (!(self->min_size.width < self->max_size.width ||
- self->min_size.height < self->max_size.height)) {
- self->decorations &= ~(Decor_Maximize | Decor_Handle);
- self->functions &= ~(Func_Resize | Func_Maximize);
- }
-
- switch (self->type) {
- case Type_Normal:
- /* normal windows retain all of the possible decorations and
- functionality, and are the only windows that you can fullscreen */
- self->functions |= Func_Fullscreen;
- break;
-
- case Type_Dialog:
- /* dialogs cannot be maximized */
- self->decorations &= ~Decor_Maximize;
- self->functions &= ~Func_Maximize;
- break;
-
- case Type_Menu:
- case Type_Toolbar:
- case Type_Utility:
- /* these windows get less functionality */
- self->decorations &= ~(Decor_Iconify | Decor_Handle);
- self->functions &= ~(Func_Iconify | Func_Resize);
- break;
-
- case Type_Desktop:
- case Type_Dock:
- case Type_Splash:
- /* none of these windows are manipulated by the window manager */
- self->decorations = 0;
- self->functions = 0;
- break;
- }
-
- /* Mwm Hints are applied subtractively to what has already been chosen for
- decor and functionality */
- if (self->mwmhints.flags & MwmFlag_Decorations) {
- if (! (self->mwmhints.decorations & MwmDecor_All)) {
- if (! (self->mwmhints.decorations & MwmDecor_Border))
- self->decorations &= ~Decor_Border;
- if (! (self->mwmhints.decorations & MwmDecor_Handle))
- self->decorations &= ~Decor_Handle;
- if (! (self->mwmhints.decorations & MwmDecor_Title))
- self->decorations &= ~Decor_Titlebar;
- if (! (self->mwmhints.decorations & MwmDecor_Iconify))
- self->decorations &= ~Decor_Iconify;
- if (! (self->mwmhints.decorations & MwmDecor_Maximize))
- self->decorations &= ~Decor_Maximize;
- }
- }
-
- if (self->mwmhints.flags & MwmFlag_Functions) {
- if (! (self->mwmhints.functions & MwmFunc_All)) {
- if (! (self->mwmhints.functions & MwmFunc_Resize))
- self->functions &= ~Func_Resize;
- if (! (self->mwmhints.functions & MwmFunc_Move))
- self->functions &= ~Func_Move;
- if (! (self->mwmhints.functions & MwmFunc_Iconify))
- self->functions &= ~Func_Iconify;
- if (! (self->mwmhints.functions & MwmFunc_Maximize))
- self->functions &= ~Func_Maximize;
- /* dont let mwm hints kill the close button
- if (! (self->mwmhints.functions & MwmFunc_Close))
- self->functions &= ~Func_Close; */
- }
- }
-
- /* can't maximize without moving/resizing */
- if (!((self->functions & Func_Move) && (self->functions & Func_Resize)))
- self->functions &= ~Func_Maximize;
-
- /* finally, user specified disabled decorations are applied to subtract
- decorations */
- if (self->disabled_decorations & Decor_Titlebar)
- self->decorations &= ~Decor_Titlebar;
- if (self->disabled_decorations & Decor_Handle)
- self->decorations &= ~Decor_Handle;
- if (self->disabled_decorations & Decor_Border)
- self->decorations &= ~Decor_Border;
- if (self->disabled_decorations & Decor_Iconify)
- self->decorations &= ~Decor_Iconify;
- if (self->disabled_decorations & Decor_Maximize)
- self->decorations &= ~Decor_Maximize;
- if (self->disabled_decorations & Decor_AllDesktops)
- self->decorations &= ~Decor_AllDesktops;
- if (self->disabled_decorations & Decor_Close)
- self->decorations &= ~Decor_Close;
-
- /* if we don't have a titlebar, then we cannot shade! */
- if (!(self->decorations & Decor_Titlebar))
- self->functions &= ~Func_Shade;
-
- client_change_allowed_actions(self);
-
- if (self->frame) {
- /* change the decors on the frame */
- frame_adjust_size(self->frame);
- /* with more/less decorations, we may need to be repositioned */
- frame_adjust_position(self->frame);
- /* with new decor, the window's maximized size may change */
- client_remaximize(self);
- }
-}
-
-static void client_change_allowed_actions(Client *self)
-{
- Atom actions[9];
- int num = 0;
-
- actions[num++] = prop_atoms.net_wm_action_change_desktop;
-
- if (self->functions & Func_Shade)
- actions[num++] = prop_atoms.net_wm_action_shade;
- if (self->functions & Func_Close)
- actions[num++] = prop_atoms.net_wm_action_close;
- if (self->functions & Func_Move)
- actions[num++] = prop_atoms.net_wm_action_move;
- if (self->functions & Func_Iconify)
- actions[num++] = prop_atoms.net_wm_action_minimize;
- if (self->functions & Func_Resize)
- actions[num++] = prop_atoms.net_wm_action_resize;
- if (self->functions & Func_Fullscreen)
- actions[num++] = prop_atoms.net_wm_action_fullscreen;
- if (self->functions & Func_Maximize) {
- actions[num++] = prop_atoms.net_wm_action_maximize_horz;
- actions[num++] = prop_atoms.net_wm_action_maximize_vert;
- }
-
- PROP_SET32A(self->window, net_wm_allowed_actions, atom, actions, num);
-
- /* make sure the window isn't breaking any rules now */
-
- if (!(self->functions & Func_Shade) && self->shaded) {
- if (self->frame) client_shade(self, FALSE);
- else self->shaded = FALSE;
- }
- if (!(self->functions & Func_Iconify) && self->iconic) {
- if (self->frame) client_iconify(self, FALSE, TRUE);
- else self->iconic = FALSE;
- }
- if (!(self->functions & Func_Fullscreen) && self->fullscreen) {
- if (self->frame) client_fullscreen(self, FALSE, TRUE);
- else self->fullscreen = FALSE;
- }
- if (!(self->functions & Func_Maximize) && (self->max_horz ||
- self->max_vert)) {
- if (self->frame) client_maximize(self, FALSE, 0, TRUE);
- else self->max_vert = self->max_horz = FALSE;
- }
-}
-
-void client_remaximize(Client *self)
-{
- int dir;
- if (self->max_horz && self->max_vert)
- dir = 0;
- else if (self->max_horz)
- dir = 1;
- else if (self->max_vert)
- dir = 2;
- else
- return; /* not maximized */
- self->max_horz = self->max_vert = FALSE;
- client_maximize(self, TRUE, dir, FALSE);
-}
-
-void client_update_wmhints(Client *self)
-{
- XWMHints *hints;
- gboolean ur = FALSE;
-
- /* assume a window takes input if it doesnt specify */
- self->can_focus = TRUE;
-
- if ((hints = XGetWMHints(ob_display, self->window)) != NULL) {
- if (hints->flags & InputHint)
- self->can_focus = hints->input;
-
- /* only do this when starting! */
- if (ob_state == State_Starting && (hints->flags & StateHint))
- self->iconic = hints->initial_state == IconicState;
-
- if (hints->flags & XUrgencyHint)
- ur = TRUE;
-
- if (hints->flags & WindowGroupHint) {
- if (hints->window_group != self->group) {
- /* XXX: remove from the old group if there was one */
- self->group = hints->window_group;
- /* XXX: do stuff with the group */
- }
- } else /* no group! */
- self->group = None;
-
- if (hints->flags & IconPixmapHint) {
- client_update_kwm_icon(self);
- /* try get the kwm icon first, this is a fallback only */
- if (self->pixmap_icon == None) {
- self->pixmap_icon = hints->icon_pixmap;
- if (hints->flags & IconMaskHint)
- self->pixmap_icon_mask = hints->icon_mask;
- else
- self->pixmap_icon_mask = None;
-
- if (self->frame)
- frame_adjust_icon(self->frame);
- }
- }
-
- XFree(hints);
- }
-
- if (ur != self->urgent) {
- self->urgent = ur;
- g_message("Urgent Hint for 0x%lx: %s\n", self->window,
- ur ? "ON" : "OFF");
- /* fire the urgent callback if we're mapped, otherwise, wait until
- after we're mapped */
- if (self->frame)
- LOGICALHOOK(UrgentWindow, g_quark_try_string("client"), self);
- }
-}
-
-void client_update_title(Client *self)
-{
- gchar *data = NULL;
-
- if (self->title != NULL)
- g_free(self->title);
-
- /* try netwm */
- if (!PROP_GETS(self->window, net_wm_name, utf8, data)) {
- /* try old x stuff */
- if (PROP_GETS(self->window, wm_name, string, data)) {
- /* convert it to UTF-8 */
- gsize r, w;
- gchar *u;
-
- u = g_locale_to_utf8(data, -1, &r, &w, NULL);
- if (u == NULL) {
- g_warning("Unable to convert string to UTF-8");
- } else {
- g_free(data);
- data = u;
- }
- }
- }
-
- if (data == NULL)
- data = g_strdup("Unnamed Window");
-
- self->title = data;
-
- if (self->frame)
- frame_adjust_title(self->frame);
-}
-
-void client_update_icon_title(Client *self)
-{
- gchar *data = NULL;
-
- if (self->icon_title != NULL)
- g_free(self->icon_title);
-
- /* try netwm */
- if (!PROP_GETS(self->window, net_wm_icon_name, utf8, data)) {
- /* try old x stuff */
- if (PROP_GETS(self->window, wm_icon_name, string, data)) {
- /* convert it to UTF-8 */
- gsize r, w;
- gchar *u;
-
- u = g_locale_to_utf8(data, -1, &r, &w, NULL);
- if (u == NULL) {
- g_warning("Unable to convert string to UTF-8");
- } else {
- g_free(data);
- data = u;
- }
- }
- }
-
- if (data == NULL)
- data = g_strdup(self->title);
-
- self->icon_title = data;
-}
-
-void client_update_class(Client *self)
-{
- GPtrArray *data;
- gchar *s;
- guint i;
-
- if (self->res_name) g_free(self->res_name);
- if (self->res_class) g_free(self->res_class);
- if (self->role) g_free(self->role);
-
- self->res_name = self->res_class = self->role = NULL;
-
- data = g_ptr_array_new();
-
- if (PROP_GETSA(self->window, wm_class, string, data)) {
- if (data->len > 0)
- self->res_name = g_strdup(g_ptr_array_index(data, 0));
- if (data->len > 1)
- self->res_class = g_strdup(g_ptr_array_index(data, 1));
- }
-
- for (i = 0; i < data->len; ++i)
- g_free(g_ptr_array_index(data, i));
- g_ptr_array_free(data, TRUE);
-
- if (PROP_GETS(self->window, wm_window_role, string, s))
- self->role = g_strdup(s);
-
- if (self->res_name == NULL) self->res_name = g_strdup("");
- if (self->res_class == NULL) self->res_class = g_strdup("");
- if (self->role == NULL) self->role = g_strdup("");
-}
-
-void client_update_strut(Client *self)
-{
- gulong num = 4;
- gulong *data;
-
- if (PROP_GET32A(self->window, net_wm_strut, cardinal, data, num)) {
- STRUT_SET(self->strut, data[0], data[1], data[2], data[3]);
- g_free(data);
- } else
- STRUT_SET(self->strut, 0, 0, 0, 0);
-
- /* updating here is pointless while we're being mapped cuz we're not in
- the client list yet */
- if (self->frame)
- screen_update_struts();
-}
-
-void client_update_icons(Client *self)
-{
- unsigned long num;
- unsigned long *data;
- unsigned long w, h, i;
- int j;
-
- for (j = 0; j < self->nicons; ++j)
- g_free(self->icons[j].data);
- if (self->nicons > 0)
- g_free(self->icons);
- self->nicons = 0;
-
- if (PROP_GET32U(self->window, net_wm_icon, cardinal, data, num)) {
- /* figure out how many valid icons are in here */
- i = 0;
- while (num - i > 2) {
- w = data[i++];
- h = data[i++];
- i += w * h;
- if (i > num) break;
- ++self->nicons;
- }
-
- self->icons = g_new(Icon, self->nicons);
-
- /* store the icons */
- i = 0;
- for (j = 0; j < self->nicons; ++j) {
- w = self->icons[j].w = data[i++];
- h = self->icons[j].h = data[i++];
- self->icons[j].data =
- g_memdup(&data[i], w * h * sizeof(gulong));
- i += w * h;
- g_assert(i <= num);
- }
-
- g_free(data);
- }
-
- if (self->nicons <= 0) {
- self->nicons = 1;
- self->icons = g_new0(Icon, 1);
- }
-
- if (self->frame)
- frame_adjust_icon(self->frame);
-}
-
-void client_update_kwm_icon(Client *self)
-{
- Pixmap *data;
-
- if (PROP_GET32A(self->window, kwm_win_icon, kwm_win_icon, data, 2)) {
- self->pixmap_icon = data[0];
- self->pixmap_icon_mask = data[1];
- g_free(data);
- } else {
- self->pixmap_icon = self->pixmap_icon_mask = None;
- }
- if (self->frame)
- frame_adjust_icon(self->frame);
-}
-
-static void client_change_state(Client *self)
-{
- unsigned long state[2];
- Atom netstate[10];
- int num;
-
- state[0] = self->wmstate;
- state[1] = None;
- PROP_SET32A(self->window, wm_state, wm_state, state, 2);
-
- num = 0;
- if (self->modal)
- netstate[num++] = prop_atoms.net_wm_state_modal;
- if (self->shaded)
- netstate[num++] = prop_atoms.net_wm_state_shaded;
- if (self->iconic)
- netstate[num++] = prop_atoms.net_wm_state_hidden;
- if (self->skip_taskbar)
- netstate[num++] = prop_atoms.net_wm_state_skip_taskbar;
- if (self->skip_pager)
- netstate[num++] = prop_atoms.net_wm_state_skip_pager;
- if (self->fullscreen)
- netstate[num++] = prop_atoms.net_wm_state_fullscreen;
- if (self->max_vert)
- netstate[num++] = prop_atoms.net_wm_state_maximized_vert;
- if (self->max_horz)
- netstate[num++] = prop_atoms.net_wm_state_maximized_horz;
- if (self->above)
- netstate[num++] = prop_atoms.net_wm_state_above;
- if (self->below)
- netstate[num++] = prop_atoms.net_wm_state_below;
- PROP_SET32A(self->window, net_wm_state, atom, netstate, num);
-
- client_calc_layer(self);
-
- if (self->frame)
- frame_adjust_state(self->frame);
-}
-
-static Client *search_focus_tree(Client *node, Client *skip)
-{
- GSList *it;
- Client *ret;
-
- for (it = node->transients; it != NULL; it = g_slist_next(it)) {
- Client *c = it->data;
- if (c == skip) continue; /* circular? */
- if ((ret = search_focus_tree(c, skip))) return ret;
- if (c->focused) return c;
- }
- return NULL;
-}
-
-void client_calc_layer(Client *self)
-{
- StackLayer l;
- gboolean fs;
- Client *c;
-
- /* are we fullscreen, or do we have a fullscreen transient parent? */
- c = self;
- fs = FALSE;
- while (c) {
- if (c->fullscreen) {
- fs = TRUE;
- break;
- }
- c = c->transient_for;
- }
- if (!fs && self->fullscreen) {
- /* is one of our transients focused? */
- c = search_focus_tree(self, self);
- if (c != NULL) fs = TRUE;
- }
-
- if (self->iconic) l = Layer_Icon;
- else if (fs) l = Layer_Fullscreen;
- else if (self->type == Type_Desktop) l = Layer_Desktop;
- else if (self->type == Type_Dock) {
- if (!self->below) l = Layer_Top;
- else l = Layer_Normal;
- }
- else if (self->above) l = Layer_Above;
- else if (self->below) l = Layer_Below;
- else l = Layer_Normal;
-
- if (l != self->layer) {
- self->layer = l;
- if (self->frame)
- stacking_raise(self);
- }
-}
-
-void client_showhide(Client *self)
-{
- gboolean show;
-
- if (self->iconic) show = FALSE;
- else if (!(self->desktop == screen_desktop ||
- self->desktop == DESKTOP_ALL)) show = FALSE;
- else if (client_normal(self) && screen_showing_desktop) show = FALSE;
- else show = TRUE;
-
- if (show) frame_show(self->frame);
- else frame_hide(self->frame);
-}
-
-gboolean client_normal(Client *self) {
- return ! (self->type == Type_Desktop || self->type == Type_Dock ||
- self->type == Type_Splash);
-}
-
-static void client_apply_startup_state(Client *self)
-{
- /* these are in a carefully crafted order.. */
-
- if (self->iconic) {
- self->iconic = FALSE;
- client_iconify(self, TRUE, FALSE);
- }
- if (self->fullscreen) {
- self->fullscreen = FALSE;
- client_fullscreen(self, TRUE, FALSE);
- }
- if (self->shaded) {
- self->shaded = FALSE;
- client_shade(self, TRUE);
- }
- if (self->urgent)
- LOGICALHOOK(UrgentWindow, g_quark_try_string("client"), self);
-
- if (self->max_vert && self->max_horz) {
- self->max_vert = self->max_horz = FALSE;
- client_maximize(self, TRUE, 0, FALSE);
- } else if (self->max_vert) {
- self->max_vert = FALSE;
- client_maximize(self, TRUE, 2, FALSE);
- } else if (self->max_horz) {
- self->max_horz = FALSE;
- client_maximize(self, TRUE, 1, FALSE);
- }
-
- /* nothing to do for the other states:
- skip_taskbar
- skip_pager
- modal
- above
- below
- */
-}
-
-void client_configure(Client *self, Corner anchor, int x, int y, int w, int h,
- gboolean user, gboolean final)
-{
- w -= self->base_size.width;
- h -= self->base_size.height;
-
- if (user) {
- /* for interactive resizing. have to move half an increment in each
- direction. */
-
- /* how far we are towards the next size inc */
- int mw = w % self->size_inc.width;
- int mh = h % self->size_inc.height;
- /* amount to add */
- int aw = self->size_inc.width / 2;
- int ah = self->size_inc.height / 2;
- /* don't let us move into a new size increment */
- if (mw + aw >= self->size_inc.width)
- aw = self->size_inc.width - mw - 1;
- if (mh + ah >= self->size_inc.height)
- ah = self->size_inc.height - mh - 1;
- w += aw;
- h += ah;
-
- /* if this is a user-requested resize, then check against min/max
- sizes and aspect ratios */
-
- /* smaller than min size or bigger than max size? */
- if (w > self->max_size.width) w = self->max_size.width;
- if (w < self->min_size.width) w = self->min_size.width;
- if (h > self->max_size.height) h = self->max_size.height;
- if (h < self->min_size.height) h = self->min_size.height;
-
- /* adjust the height ot match the width for the aspect ratios */
- if (self->min_ratio)
- if (h * self->min_ratio > w) h = (int)(w / self->min_ratio);
- if (self->max_ratio)
- if (h * self->max_ratio < w) h = (int)(w / self->max_ratio);
- }
-
- /* keep to the increments */
- w /= self->size_inc.width;
- h /= self->size_inc.height;
-
- /* you cannot resize to nothing */
- if (w < 1) w = 1;
- if (h < 1) h = 1;
-
- /* store the logical size */
- SIZE_SET(self->logical_size, w, h);
-
- w *= self->size_inc.width;
- h *= self->size_inc.height;
-
- w += self->base_size.width;
- h += self->base_size.height;
-
- switch (anchor) {
- case Corner_TopLeft:
- break;
- case Corner_TopRight:
- x -= w - self->area.width;
- break;
- case Corner_BottomLeft:
- y -= h - self->area.height;
- break;
- case Corner_BottomRight:
- x -= w - self->area.width;
- y -= h - self->area.height;
- break;
- }
-
- RECT_SET(self->area, x, y, w, h);
-
- XResizeWindow(ob_display, self->window, w, h);
-
- /* move/resize the frame to match the request */
- if (self->frame) {
- /* Adjust the size and then the position, as required by the EWMH */
- frame_adjust_size(self->frame);
- frame_adjust_position(self->frame);
-
- if (!user || final) {
- XEvent event;
- event.type = ConfigureNotify;
- event.xconfigure.display = ob_display;
- event.xconfigure.event = self->window;
- event.xconfigure.window = self->window;
-
- /* root window coords with border in mind */
- event.xconfigure.x = x - self->border_width +
- self->frame->size.left;
- event.xconfigure.y = y - self->border_width +
- self->frame->size.top;
-
- event.xconfigure.width = self->area.width;
- event.xconfigure.height = self->area.height;
- event.xconfigure.border_width = self->border_width;
- event.xconfigure.above = self->frame->plate;
- event.xconfigure.override_redirect = FALSE;
- XSendEvent(event.xconfigure.display, event.xconfigure.window,
- FALSE, StructureNotifyMask, &event);
- }
- }
-}
-
-void client_fullscreen(Client *self, gboolean fs, gboolean savearea)
-{
- static int saved_func, saved_decor;
- int x, y, w, h;
-
- if (!(self->functions & Func_Fullscreen) || /* can't */
- self->fullscreen == fs) return; /* already done */
-
- self->fullscreen = fs;
- client_change_state(self); /* change the state hints on the client */
-
- if (fs) {
- /* save the functions and remove them */
- saved_func = self->functions;
- self->functions &= (Func_Close | Func_Fullscreen |
- Func_Iconify);
- /* save the decorations and remove them */
- saved_decor = self->decorations;
- self->decorations = 0;
- if (savearea) {
- long dimensions[4];
- dimensions[0] = self->area.x;
- dimensions[1] = self->area.y;
- dimensions[2] = self->area.width;
- dimensions[3] = self->area.height;
-
- PROP_SET32A(self->window, openbox_premax, cardinal,
- dimensions, 4);
- }
- x = 0;
- y = 0;
- w = screen_physical_size.width;
- h = screen_physical_size.height;
- } else {
- long *dimensions;
-
- self->functions = saved_func;
- self->decorations = saved_decor;
-
- if (PROP_GET32A(self->window, openbox_premax, cardinal,
- dimensions, 4)) {
- x = dimensions[0];
- y = dimensions[1];
- w = dimensions[2];
- h = dimensions[3];
- g_free(dimensions);
- } else {
- /* pick some fallbacks... */
- x = screen_area(self->desktop)->x +
- screen_area(self->desktop)->width / 4;
- y = screen_area(self->desktop)->y +
- screen_area(self->desktop)->height / 4;
- w = screen_area(self->desktop)->width / 2;
- h = screen_area(self->desktop)->height / 2;
- }
- }
-
- client_change_allowed_actions(self); /* based on the new _functions */
-
- /* when fullscreening, don't obey things like increments, fill the
- screen */
- client_configure(self, Corner_TopLeft, x, y, w, h, !fs, TRUE);
-
- /* raise (back) into our stacking layer */
- stacking_raise(self);
-
- /* try focus us when we go into fullscreen mode */
- client_focus(self);
-}
-
-void client_iconify(Client *self, gboolean iconic, gboolean curdesk)
-{
- if (self->iconic == iconic) return; /* nothing to do */
-
- g_message("%sconifying window: 0x%lx\n", (iconic ? "I" : "Uni"),
- self->window);
-
- self->iconic = iconic;
-
- if (iconic) {
- self->wmstate = IconicState;
- self->ignore_unmaps++;
- /* we unmap the client itself so that we can get MapRequest events,
- and because the ICCCM tells us to! */
- XUnmapWindow(ob_display, self->window);
- } else {
- if (curdesk)
- client_set_desktop(self, screen_desktop);
- self->wmstate = self->shaded ? IconicState : NormalState;
- XMapWindow(ob_display, self->window);
- }
- client_change_state(self);
- client_showhide(self);
- screen_update_struts();
-}
-
-void client_maximize(Client *self, gboolean max, int dir, gboolean savearea)
-{
- int x, y, w, h;
-
- g_assert(dir == 0 || dir == 1 || dir == 2);
- if (!(self->functions & Func_Maximize)) return; /* can't */
-
- /* check if already done */
- if (max) {
- if (dir == 0 && self->max_horz && self->max_vert) return;
- if (dir == 1 && self->max_horz) return;
- if (dir == 2 && self->max_vert) return;
- } else {
- if (dir == 0 && !self->max_horz && !self->max_vert) return;
- if (dir == 1 && !self->max_horz) return;
- if (dir == 2 && !self->max_vert) return;
- }
-
- x = self->frame->area.x;
- y = self->frame->area.y;
- w = self->frame->area.width;
- h = self->frame->area.height;
-
- if (max) {
- if (savearea) {
- long dimensions[4];
- long *readdim;
-
- dimensions[0] = x;
- dimensions[1] = y;
- dimensions[2] = w;
- dimensions[3] = h;
-
- /* get the property off the window and use it for the dimensions
- we are already maxed on */
- if (PROP_GET32A(self->window, openbox_premax, cardinal,
- readdim, 4)) {
- if (self->max_horz) {
- dimensions[0] = readdim[0];
- dimensions[2] = readdim[2];
- }
- if (self->max_vert) {
- dimensions[1] = readdim[1];
- dimensions[3] = readdim[3];
- }
- g_free(readdim);
- }
-
- PROP_SET32A(self->window, openbox_premax, cardinal,
- dimensions, 4);
- }
- if (dir == 0 || dir == 1) { /* horz */
- x = screen_area(self->desktop)->x;
- w = screen_area(self->desktop)->x +
- screen_area(self->desktop)->width;
- }
- if (dir == 0 || dir == 2) { /* vert */
- y = screen_area(self->desktop)->y;
- h = screen_area(self->desktop)->y +
- screen_area(self->desktop)->height -
- self->frame->size.top - self->frame->size.bottom;
- }
- } else {
- long *dimensions;
-
- if (PROP_GET32A(self->window, openbox_premax, cardinal,
- dimensions, 4)) {
- if (dir == 0 || dir == 1) { /* horz */
- x = dimensions[0];
- w = dimensions[2];
- }
- if (dir == 0 || dir == 2) { /* vert */
- y = dimensions[1];
- h = dimensions[3];
- }
- g_free(dimensions);
- } else {
- /* pick some fallbacks... */
- if (dir == 0 || dir == 1) { /* horz */
- x = screen_area(self->desktop)->x +
- screen_area(self->desktop)->width / 4;
- w = screen_area(self->desktop)->width / 2;
- }
- if (dir == 0 || dir == 2) { /* vert */
- y = screen_area(self->desktop)->y +
- screen_area(self->desktop)->height / 4;
- h = screen_area(self->desktop)->height / 2;
- }
- }
- }
-
- if (dir == 0 || dir == 1) /* horz */
- self->max_horz = max;
- if (dir == 0 || dir == 2) /* vert */
- self->max_vert = max;
-
- if (!self->max_horz && !self->max_vert)
- PROP_ERASE(self->window, openbox_premax);
-
- client_change_state(self); /* change the state hints on the client */
-
- /* figure out where the client should be going */
- frame_frame_gravity(self->frame, &x, &y);
- client_configure(self, Corner_TopLeft, x, y, w, h, TRUE, TRUE);
-}
-
-void client_shade(Client *self, gboolean shade)
-{
- if (!(self->functions & Func_Shade) || /* can't */
- self->shaded == shade) return; /* already done */
-
- /* when we're iconic, don't change the wmstate */
- if (!self->iconic)
- self->wmstate = shade ? IconicState : NormalState;
- self->shaded = shade;
- client_change_state(self);
- frame_adjust_size(self->frame);
-}
-
-void client_close(Client *self)
-{
- XEvent ce;
-
- if (!(self->functions & Func_Close)) return;
-
- /*
- XXX: itd be cool to do timeouts and shit here for killing the client's
- process off
- like... if the window is around after 5 seconds, then the close button
- turns a nice red, and if this function is called again, the client is
- explicitly killed.
- */
-
- ce.xclient.type = ClientMessage;
- ce.xclient.message_type = prop_atoms.wm_protocols;
- ce.xclient.display = ob_display;
- ce.xclient.window = self->window;
- ce.xclient.format = 32;
- ce.xclient.data.l[0] = prop_atoms.wm_delete_window;
- ce.xclient.data.l[1] = CurrentTime;
- ce.xclient.data.l[2] = 0l;
- ce.xclient.data.l[3] = 0l;
- ce.xclient.data.l[4] = 0l;
- XSendEvent(ob_display, self->window, FALSE, NoEventMask, &ce);
-}
-
-void client_set_desktop(Client *self, unsigned int target)
-{
- if (target == self->desktop) return;
-
- g_message("Setting desktop %u\n", target);
-
- if (!(target < screen_num_desktops ||
- target == DESKTOP_ALL))
- return;
-
- self->desktop = target;
- PROP_SET32(self->window, net_wm_desktop, cardinal, target);
- /* the frame can display the current desktop state */
- frame_adjust_state(self->frame);
- /* 'move' the window to the new desktop */
- client_showhide(self);
- screen_update_struts();
-}
-
-static Client *search_modal_tree(Client *node, Client *skip)
-{
- GSList *it;
- Client *ret;
-
- for (it = node->transients; it != NULL; it = it->next) {
- Client *c = it->data;
- if (c == skip) continue; /* circular? */
- if ((ret = search_modal_tree(c, skip))) return ret;
- if (c->modal) return c;
- }
- return NULL;
-}
-
-Client *client_find_modal_child(Client *self)
-{
- return search_modal_tree(self, self);
-}
-
-gboolean client_validate(Client *self)
-{
- XEvent e;
-
- XSync(ob_display, FALSE); /* get all events on the server */
-
- if (XCheckTypedWindowEvent(ob_display, self->window, DestroyNotify, &e) ||
- XCheckTypedWindowEvent(ob_display, self->window, UnmapNotify, &e)) {
- XPutBackEvent(ob_display, &e);
- return FALSE;
- }
-
- return FALSE;
-}
-
-void client_set_wm_state(Client *self, long state)
-{
- if (state == self->wmstate) return; /* no change */
-
- switch (state) {
- case IconicState:
- client_iconify(self, TRUE, TRUE);
- break;
- case NormalState:
- client_iconify(self, FALSE, TRUE);
- break;
- }
-}
-
-void client_set_state(Client *self, Atom action, long data1, long data2)
-{
- gboolean shaded = self->shaded;
- gboolean fullscreen = self->fullscreen;
- gboolean max_horz = self->max_horz;
- gboolean max_vert = self->max_vert;
- int i;
-
- if (!(action == prop_atoms.net_wm_state_add ||
- action == prop_atoms.net_wm_state_remove ||
- action == prop_atoms.net_wm_state_toggle))
- /* an invalid action was passed to the client message, ignore it */
- return;
-
- for (i = 0; i < 2; ++i) {
- Atom state = i == 0 ? data1 : data2;
-
- if (!state) continue;
-
- /* if toggling, then pick whether we're adding or removing */
- if (action == prop_atoms.net_wm_state_toggle) {
- if (state == prop_atoms.net_wm_state_modal)
- action = self->modal ? prop_atoms.net_wm_state_remove :
- prop_atoms.net_wm_state_add;
- else if (state == prop_atoms.net_wm_state_maximized_vert)
- action = self->max_vert ? prop_atoms.net_wm_state_remove :
- prop_atoms.net_wm_state_add;
- else if (state == prop_atoms.net_wm_state_maximized_horz)
- action = self->max_horz ? prop_atoms.net_wm_state_remove :
- prop_atoms.net_wm_state_add;
- else if (state == prop_atoms.net_wm_state_shaded)
- action = self->shaded ? prop_atoms.net_wm_state_remove :
- prop_atoms.net_wm_state_add;
- else if (state == prop_atoms.net_wm_state_skip_taskbar)
- action = self->skip_taskbar ?
- prop_atoms.net_wm_state_remove :
- prop_atoms.net_wm_state_add;
- else if (state == prop_atoms.net_wm_state_skip_pager)
- action = self->skip_pager ?
- prop_atoms.net_wm_state_remove :
- prop_atoms.net_wm_state_add;
- else if (state == prop_atoms.net_wm_state_fullscreen)
- action = self->fullscreen ?
- prop_atoms.net_wm_state_remove :
- prop_atoms.net_wm_state_add;
- else if (state == prop_atoms.net_wm_state_above)
- action = self->above ? prop_atoms.net_wm_state_remove :
- prop_atoms.net_wm_state_add;
- else if (state == prop_atoms.net_wm_state_below)
- action = self->below ? prop_atoms.net_wm_state_remove :
- prop_atoms.net_wm_state_add;
- }
-
- if (action == prop_atoms.net_wm_state_add) {
- if (state == prop_atoms.net_wm_state_modal) {
- /* XXX raise here or something? */
- self->modal = TRUE;
- } else if (state == prop_atoms.net_wm_state_maximized_vert) {
- max_vert = TRUE;
- } else if (state == prop_atoms.net_wm_state_maximized_horz) {
- max_horz = TRUE;
- } else if (state == prop_atoms.net_wm_state_shaded) {
- shaded = TRUE;
- } else if (state == prop_atoms.net_wm_state_skip_taskbar) {
- self->skip_taskbar = TRUE;
- } else if (state == prop_atoms.net_wm_state_skip_pager) {
- self->skip_pager = TRUE;
- } else if (state == prop_atoms.net_wm_state_fullscreen) {
- fullscreen = TRUE;
- } else if (state == prop_atoms.net_wm_state_above) {
- self->above = TRUE;
- } else if (state == prop_atoms.net_wm_state_below) {
- self->below = TRUE;
- }
-
- } else { /* action == prop_atoms.net_wm_state_remove */
- if (state == prop_atoms.net_wm_state_modal) {
- self->modal = FALSE;
- } else if (state == prop_atoms.net_wm_state_maximized_vert) {
- max_vert = FALSE;
- } else if (state == prop_atoms.net_wm_state_maximized_horz) {
- max_horz = FALSE;
- } else if (state == prop_atoms.net_wm_state_shaded) {
- shaded = FALSE;
- } else if (state == prop_atoms.net_wm_state_skip_taskbar) {
- self->skip_taskbar = FALSE;
- } else if (state == prop_atoms.net_wm_state_skip_pager) {
- self->skip_pager = FALSE;
- } else if (state == prop_atoms.net_wm_state_fullscreen) {
- fullscreen = FALSE;
- } else if (state == prop_atoms.net_wm_state_above) {
- self->above = FALSE;
- } else if (state == prop_atoms.net_wm_state_below) {
- self->below = FALSE;
- }
- }
- }
- if (max_horz != self->max_horz || max_vert != self->max_vert) {
- if (max_horz != self->max_horz && max_vert != self->max_vert) {
- /* toggling both */
- if (max_horz == max_vert) { /* both going the same way */
- client_maximize(self, max_horz, 0, TRUE);
- } else {
- client_maximize(self, max_horz, 1, TRUE);
- client_maximize(self, max_vert, 2, TRUE);
- }
- } else {
- /* toggling one */
- if (max_horz != self->max_horz)
- client_maximize(self, max_horz, 1, TRUE);
- else
- client_maximize(self, max_vert, 2, TRUE);
- }
- }
- /* change fullscreen state before shading, as it will affect if the window
- can shade or not */
- if (fullscreen != self->fullscreen)
- client_fullscreen(self, fullscreen, TRUE);
- if (shaded != self->shaded)
- client_shade(self, shaded);
- client_calc_layer(self);
- client_change_state(self); /* change the hint to relect these changes */
-}
-
-gboolean client_focus(Client *self)
-{
- XEvent ev;
- Client *child;
-
- /* if we have a modal child, then focus it, not us */
- child = client_find_modal_child(self);
- if (child)
- return client_focus(child);
-
- /* won't try focus if the client doesn't want it, or if the window isn't
- visible on the screen */
- if (!(self->frame->visible &&
- (self->can_focus || self->focus_notify)))
- return FALSE;
-
- /* do a check to see if the window has already been unmapped or destroyed
- do this intelligently while watching out for unmaps we've generated
- (ignore_unmaps > 0) */
- if (XCheckTypedWindowEvent(ob_display, self->window,
- DestroyNotify, &ev)) {
- XPutBackEvent(ob_display, &ev);
- return FALSE;
- }
- while (XCheckTypedWindowEvent(ob_display, self->window,
- UnmapNotify, &ev)) {
- if (self->ignore_unmaps) {
- self->ignore_unmaps--;
- } else {
- XPutBackEvent(ob_display, &ev);
- return FALSE;
- }
- }
-
- if (self->can_focus)
- XSetInputFocus(ob_display, self->window, RevertToNone, CurrentTime);
-
- if (self->focus_notify) {
- XEvent ce;
- ce.xclient.type = ClientMessage;
- ce.xclient.message_type = prop_atoms.wm_protocols;
- ce.xclient.display = ob_display;
- ce.xclient.window = self->window;
- ce.xclient.format = 32;
- ce.xclient.data.l[0] = prop_atoms.wm_take_focus;
- ce.xclient.data.l[1] = event_lasttime;
- ce.xclient.data.l[2] = 0l;
- ce.xclient.data.l[3] = 0l;
- ce.xclient.data.l[4] = 0l;
- XSendEvent(ob_display, self->window, FALSE, NoEventMask, &ce);
- }
-
- /*XSync(ob_display, FALSE); XXX Why sync? */
- return TRUE;
-}
-
-void client_unfocus(Client *self)
-{
- g_assert(focus_client == self);
- focus_set_client(NULL);
-}
+++ /dev/null
-#ifndef __client_h
-#define __client_h
-
-#include "geom.h"
-#include "obexport.h"
-#include <glib.h>
-#include <X11/Xlib.h>
-
-struct ClientWrap;
-struct Frame;
-
-
-/*! Holds an icon in ARGB format */
-typedef struct Icon {
- unsigned long w, h;
- unsigned long *data;
-} Icon;
-
-/*! The MWM Hints as retrieved from the window property
- This structure only contains 3 elements, even though the Motif 2.0
- structure contains 5. We only use the first 3, so that is all gets
- defined.
-*/
-typedef struct MwmHints {
- /*! A bitmask of Client::MwmFlags values */
- unsigned long flags;
- /*! A bitmask of Client::MwmFunctions values */
- unsigned long functions;
- /*! A bitmask of Client::MwmDecorations values */
- unsigned long decorations;
-} MwmHints;
-/*! The number of elements in the Client::MwmHints struct */
-#define MWM_ELEMENTS 3
-
-/*! Possible flags for MWM Hints (defined by Motif 2.0) */
-typedef enum {
- MwmFlag_Functions = 1 << 0, /*!< The MMW Hints define funcs */
- MwmFlag_Decorations = 1 << 1 /*!< The MWM Hints define decor */
-} MwmFlags;
-
-/*! Possible functions for MWM Hints (defined by Motif 2.0) */
-typedef enum {
- MwmFunc_All = 1 << 0, /*!< All functions */
- MwmFunc_Resize = 1 << 1, /*!< Allow resizing */
- MwmFunc_Move = 1 << 2, /*!< Allow moving */
- MwmFunc_Iconify = 1 << 3, /*!< Allow to be iconfied */
- MwmFunc_Maximize = 1 << 4 /*!< Allow to be maximized */
- /*MwmFunc_Close = 1 << 5 /!< Allow to be closed */
-} MwmFunctions;
-
-/*! Possible decorations for MWM Hints (defined by Motif 2.0) */
-typedef enum {
- MwmDecor_All = 1 << 0, /*!< All decorations */
- MwmDecor_Border = 1 << 1, /*!< Show a border */
- MwmDecor_Handle = 1 << 2, /*!< Show a handle (bottom) */
- MwmDecor_Title = 1 << 3, /*!< Show a titlebar */
- /*MwmDecor_Menu = 1 << 4, /!< Show a menu */
- MwmDecor_Iconify = 1 << 5, /*!< Show an iconify button */
- MwmDecor_Maximize = 1 << 6 /*!< Show a maximize button */
-} MemDecorations;
-
-
-typedef struct Client {
- Window window;
-
- struct Frame *frame;
-
- /*! The number of unmap events to ignore on the window */
- int ignore_unmaps;
-
- /*! The id of the group the window belongs to */
- Window group;
- /*! Whether or not the client is a transient window. This is guaranteed to
- be TRUE if transient_for != NULL, but not guaranteed to be FALSE if
- transient_for == NULL. */
- gboolean transient;
- /*! The client which this client is a transient (child) for */
- struct Client *transient_for;
- /*! The clients which are transients (children) of this client */
- GSList *transients;
- /*! The desktop on which the window resides (0xffffffff for all
- desktops) */
- unsigned int desktop;
-
- /*! Normal window title */
- gchar *title;
- /*! Window title when iconified */
- gchar *icon_title;
-
- /*! The application that created the window */
- gchar *res_name;
- /*! The class of the window, can used for grouping */
- gchar *res_class;
- /*! The specified role of the window, used for identification */
- gchar *role;
-
- /*! The type of window (what its function is) */
- WindowType type;
-
- /*! Position and size of the window
- This will not always be the actual position of the window on screen, it
- is, rather, the position requested by the client, to which the window's
- gravity is applied.
- */
- Rect area;
-
- /*! The window's strut
- The strut defines areas of the screen that are marked off-bounds for
- window placement. In theory, where this window exists.
- */
- Strut strut;
-
- /*! The logical size of the window
- The "logical" size of the window is refers to the user's perception of
- the size of the window, and is the value that should be displayed to the
- user. For example, with xterms, this value it the number of characters
- being displayed in the terminal, instead of the number of pixels.
- */
- Size logical_size;
-
- /*! Width of the border on the window.
- The window manager will set this to 0 while the window is being managed,
- but needs to restore it afterwards, so it is saved here.
- */
- guint border_width;
-
- /*! The minimum aspect ratio the client window can be sized to.
- A value of 0 means this is ignored.
- */
- float min_ratio;
- /*! The maximum aspect ratio the client window can be sized to.
- A value of 0 means this is ignored.
- */
- float max_ratio;
-
- /*! The minimum size of the client window
- If the min is > the max, then the window is not resizable
- */
- Size min_size;
- /*! The maximum size of the client window
- If the min is > the max, then the window is not resizable
- */
- Size max_size;
- /*! The size of increments to resize the client window by */
- Size size_inc;
- /*! The base size of the client window
- This value should be subtracted from the window's actual size when
- displaying its size to the user, or working with its min/max size
- */
- Size base_size;
-
- /*! Window decoration and functionality hints */
- MwmHints mwmhints;
-
- /*! Where to place the decorated window in relation to the undecorated
- window */
- int gravity;
-
- /*! The state of the window, one of WithdrawnState, IconicState, or
- NormalState */
- long wmstate;
-
- /*! True if the client supports the delete_window protocol */
- gboolean delete_window;
-
- /*! Was the window's position requested by the application? if not, we
- should place the window ourselves when it first appears */
- gboolean positioned;
-
- /*! Can the window receive input focus? */
- gboolean can_focus;
- /*! Urgency flag */
- gboolean urgent;
- /*! Notify the window when it receives focus? */
- gboolean focus_notify;
- /*! Does the client window have the input focus? */
- gboolean focused;
-
- /*! The window uses shape extension to be non-rectangular? */
- gboolean shaped;
-
- /*! The window is modal, so it must be processed before any windows it is
- related to can be focused */
- gboolean modal;
- /*! Only the window's titlebar is displayed */
- gboolean shaded;
- /*! The window is iconified */
- gboolean iconic;
- /*! The window is maximized to fill the screen vertically */
- gboolean max_vert;
- /*! The window is maximized to fill the screen horizontally */
- gboolean max_horz;
- /*! The window should not be displayed by pagers */
- gboolean skip_pager;
- /*! The window should not be displayed by taskbars */
- gboolean skip_taskbar;
- /*! The window is a 'fullscreen' window, and should be on top of all
- others */
- gboolean fullscreen;
- /*! The window should be on top of other windows of the same type */
- gboolean above;
- /*! The window should be underneath other windows of the same type */
- gboolean below;
-
- /*! The layer in which the window will be stacked, windows in lower layers
- are always below windows in higher layers. */
- StackLayer layer;
-
- /*! A bitmask of values in the Decoration enum
- The values in the variable are the decorations that the client wants to
- be displayed around it.
- */
- int decorations;
-
- /*! A bitmask of values in the Decoration enum.
- Specifies the decorations that should NOT be displayed on the client.
- */
- int disabled_decorations;
-
- /*! A bitmask of values in the Function enum
- The values in the variable specify the ways in which the user is allowed
- to modify this window.
- */
- int functions;
-
- /*! Icons for the client as specified on the client window */
- Icon *icons;
- /*! The number of icons in icons */
- int nicons;
-
- /*! The icon for the client specified in the WMHints or the KWM hints */
- Pixmap pixmap_icon;
- /*! The mask for the pixmap_icon, or None if its not masked */
- Pixmap pixmap_icon_mask;
-
- /* The instance of the wrapper class if one exists */
- struct ClientWrap *wrap;
-} Client;
-
-extern GSList *client_list;
-extern GHashTable *client_map;
-
-void client_startup();
-void client_shutdown();
-
-/*! Manages all existing windows */
-void client_manage_all();
-/*! Manages a given window */
-void client_manage(Window win);
-/*! Unmanages all managed windows */
-void client_unmanage_all();
-/*! Unmanages a given client */
-void client_unmanage(Client *client);
-
-/*! Sets the client list on the root window from the client_list */
-void client_set_list();
-
-/*! Reapplies the maximized state to the window
- Use this to make the window readjust its maximized size to new
- surroundings (struts, etc). */
-void client_remaximize(Client *self);
-
-/*! Shows the window if it should be shown, or hides it
- Used when changing desktops, the window's state, etc. */
-void client_showhide(Client *self);
-
-/*! Returns if the window should be treated as a normal window.
- Some windows (desktops, docks, splash screens) have special rules applied
- to them in a number of places regarding focus or user interaction. */
-gboolean client_normal(Client *self);
-
-/*! Internal version of the Client::resize function
- This also maintains things like the client's minsize, and size increments.
- @param anchor The corner to keep in the same position when resizing.
- @param x The x coordiante of the new position for the client.
- @param y The y coordiante of the new position for the client.
- @param w The width component of the new size for the client.
- @param h The height component of the new size for the client.
- @param user Specifies whether this is a user-requested change or a
- program requested change. For program requested changes, the
- constraints are not checked.
- @param final If user is true, then this should specify if this is a final
- configuration. e.g. Final should be FALSE if doing an
- interactive move/resize, and then be TRUE for the last call
- only.
-*/
-void client_configure(Client *self, Corner anchor, int x, int y, int w, int h,
- gboolean user, gboolean final);
-
-/*! Fullscreen's or unfullscreen's the client window
- @param fs true if the window should be made fullscreen; false if it should
- be returned to normal state.
- @param savearea true to have the client's current size and position saved;
- otherwise, they are not. You should not save when mapping a
- new window that is set to fullscreen. This has no effect
- when restoring a window from fullscreen.
-*/
-void client_fullscreen(Client *self, gboolean fs, gboolean savearea);
-
-/*! Iconifies or uniconifies the client window
- @param iconic true if the window should be iconified; false if it should be
- restored.
- @param curdesk If iconic is FALSE, then this determines if the window will
- be uniconified to the current viewable desktop (true) or to
- its previous desktop (false)
-*/
-void client_iconify(Client *self, gboolean iconic, gboolean curdesk);
-
-/*! Maximize or unmaximize the client window
- @param max true if the window should be maximized; false if it should be
- returned to normal size.
- @param dir 0 to set both horz and vert, 1 to set horz, 2 to set vert.
- @param savearea true to have the client's current size and position saved;
- otherwise, they are not. You should not save when mapping a
- new window that is set to fullscreen. This has no effect
- when unmaximizing a window.
-*/
-void client_maximize(Client *self, gboolean max, int dir,
- gboolean savearea);
-
-/*! Shades or unshades the client window
- @param shade true if the window should be shaded; false if it should be
- unshaded.
-*/
-void client_shade(Client *self, gboolean shade);
-
-/*! Request the client to close its window. */
-void client_close(Client *self);
-
-/*! Sends the window to the specified desktop */
-void client_set_desktop(Client *self, unsigned int target);
-
-/*! Return a modal child of the client window
- @return A modal child of the client window, or 0 if none was found.
-*/
-Client *client_find_modal_child(Client *self);
-
-/*! Validate client, by making sure no Destroy or Unmap events exist in
- the event queue for the window.
- @return true if the client is valid; false if the client has already
- been unmapped/destroyed, and so is invalid.
-*/
-gboolean client_validate(Client *self);
-
-/*! Sets the wm_state to the specified value */
-void client_set_wm_state(Client *self, long state);
-
-/*! Adjusts the window's net_state
- This should not be called as part of the window mapping process! It is for
- use when updating the state post-mapping.<br>
- client_apply_startup_state is used to do the same things during the mapping
- process.
-*/
-void client_set_state(Client *self, Atom action, long data1, long data2);
-
-/*! Attempt to focus the client window */
-gboolean client_focus(Client *self);
-
-/*! Remove focus from the client window */
-void client_unfocus(Client *self);
-
-/*! Calculates the stacking layer for the client window */
-void client_calc_layer(Client *self);
-
-/*! Updates the window's transient status, and any parents of it */
-void client_update_transient_for(Client *self);
-/*! Update the protocols that the window supports and adjusts things if they
- change */
-void client_update_protocols(Client *self);
-/*! Updates the WMNormalHints and adjusts things if they change */
-void client_update_normal_hints(Client *self);
-
-/*! Updates the WMHints and adjusts things if they change
- @param initstate Whether to read the initial_state property from the
- WMHints. This should only be used during the mapping
- process.
-*/
-void client_update_wmhints(Client *self);
-/*! Updates the window's title */
-void client_update_title(Client *self);
-/*! Updates the window's icon title */
-void client_update_icon_title(Client *self);
-/*! Updates the window's application name and class */
-void client_update_class(Client *self);
-/*! Updates the strut for the client */
-void client_update_strut(Client *self);
-/*! Updates the window's icons */
-void client_update_icons(Client *self);
-/*! Updates the window's kwm icon */
-void client_update_kwm_icon(Client *self);
-
-/*! Set up what decor should be shown on the window and what functions should
- be allowed (Client::_decorations and Client::_functions).
- This also updates the NET_WM_ALLOWED_ACTIONS hint.
-*/
-void client_setup_decor_and_functions(Client *self);
-
-/*! Retrieves the window's type and sets Client->type */
-void client_get_type(Client *self);
-
-#endif
+++ /dev/null
-#include "clientwrap.h"
-#include "client.h"
-#include "frame.h"
-#include "stacking.h"
-#include "focus.h"
-#include <glib.h>
-
-/***************************************************************************
-
- Define the type 'ClientWrap'
-
- ***************************************************************************/
-
-#define IS_CWRAP(v) ((v)->ob_type == &ClientWrapType)
-#define IS_VALID_CWRAP(v) ((v)->client != NULL)
-#define CHECK_CWRAP(self, funcname) { \
- if (!IS_CWRAP(self)) { \
- PyErr_SetString(PyExc_TypeError, \
- "descriptor '" funcname "' requires a 'Client' " \
- "object"); \
- return NULL; \
- } \
- if (!IS_VALID_CWRAP(self)) { \
- PyErr_SetString(PyExc_ValueError, \
- "This 'Client' is wrapping a client which no longer "\
- "exists."); \
- return NULL; \
- } \
-}
-
-
-staticforward PyTypeObject ClientWrapType;
-
-/***************************************************************************
-
- Attribute methods
-
- ***************************************************************************/
-
-static PyObject *cwrap_window(ClientWrap *self, PyObject *args)
-{
- CHECK_CWRAP(self, "window");
- if (!PyArg_ParseTuple(args, ":window"))
- return NULL;
- return PyInt_FromLong(self->client->window);
-}
-
-static PyObject *cwrap_group(ClientWrap *self, PyObject *args)
-{
- CHECK_CWRAP(self, "group");
- if (!PyArg_ParseTuple(args, ":group"))
- return NULL;
- return PyInt_FromLong(self->client->group);
-}
-
-static PyObject *cwrap_parent(ClientWrap *self, PyObject *args)
-{
- CHECK_CWRAP(self, "parent");
- if (!PyArg_ParseTuple(args, ":parent"))
- return NULL;
- if (self->client->transient_for != NULL)
- return clientwrap_new(self->client->transient_for);
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-static PyObject *cwrap_children(ClientWrap *self, PyObject *args)
-{
- PyObject *list;
- GSList *it;
- guint i, s;
-
- CHECK_CWRAP(self, "children");
- if (!PyArg_ParseTuple(args, ":children"))
- return NULL;
- s = g_slist_length(self->client->transients);
- list = PyList_New(s);
- for (i = 0, it = self->client->transients; i < s; ++i, it = it->next)
- PyList_SET_ITEM(list, i, clientwrap_new(it->data));
- return list;
-}
-
-static PyObject *cwrap_desktop(ClientWrap *self, PyObject *args)
-{
- CHECK_CWRAP(self, "desktop");
- if (!PyArg_ParseTuple(args, ":desktop"))
- return NULL;
- return PyInt_FromLong(self->client->desktop);
-}
-
-static PyObject *cwrap_title(ClientWrap *self, PyObject *args)
-{
- CHECK_CWRAP(self, "title");
- if (!PyArg_ParseTuple(args, ":title"))
- return NULL;
- return PyString_FromString(self->client->title);
-}
-
-static PyObject *cwrap_iconTitle(ClientWrap *self, PyObject *args)
-{
- CHECK_CWRAP(self, "iconTitle");
- if (!PyArg_ParseTuple(args, ":iconTitle"))
- return NULL;
- return PyString_FromString(self->client->icon_title);
-}
-
-static PyObject *cwrap_resName(ClientWrap *self, PyObject *args)
-{
- CHECK_CWRAP(self, "resName");
- if (!PyArg_ParseTuple(args, ":resName"))
- return NULL;
- return PyString_FromString(self->client->res_name);
-}
-
-static PyObject *cwrap_resClass(ClientWrap *self, PyObject *args)
-{
- CHECK_CWRAP(self, "resClass");
- if (!PyArg_ParseTuple(args, ":resClass"))
- return NULL;
- return PyString_FromString(self->client->res_class);
-}
-
-static PyObject *cwrap_role(ClientWrap *self, PyObject *args)
-{
- CHECK_CWRAP(self, "role");
- if (!PyArg_ParseTuple(args, ":role"))
- return NULL;
- return PyString_FromString(self->client->role);
-}
-
-static PyObject *cwrap_type(ClientWrap *self, PyObject *args)
-{
- CHECK_CWRAP(self, "type");
- if (!PyArg_ParseTuple(args, ":type"))
- return NULL;
- return PyInt_FromLong(self->client->type);
-}
-
-static PyObject *cwrap_area(ClientWrap *self, PyObject *args)
-{
- PyObject *tuple;
-
- CHECK_CWRAP(self, "area");
- if (!PyArg_ParseTuple(args, ":area"))
- return NULL;
- tuple = PyTuple_New(4);
- PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(self->client->area.x));
- PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(self->client->area.y));
- PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(self->client->area.width));
- PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(self->client->area.height));
- return tuple;
-}
-
-static PyObject *cwrap_screenArea(ClientWrap *self, PyObject *args)
-{
- PyObject *tuple;
-
- CHECK_CWRAP(self, "screenArea");
- if (!PyArg_ParseTuple(args, ":screenArea"))
- return NULL;
- tuple = PyTuple_New(4);
- PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(self->client->frame->area.x));
- PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(self->client->frame->area.y));
- PyTuple_SET_ITEM(tuple, 2,
- PyInt_FromLong(self->client->frame->area.width));
- PyTuple_SET_ITEM(tuple, 3,
- PyInt_FromLong(self->client->frame->area.height));
- return tuple;
-}
-
-static PyObject *cwrap_strut(ClientWrap *self, PyObject *args)
-{
- PyObject *tuple;
-
- CHECK_CWRAP(self, "strut");
- if (!PyArg_ParseTuple(args, ":strut"))
- return NULL;
- tuple = PyTuple_New(4);
- PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(self->client->strut.left));
- PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(self->client->strut.top));
- PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(self->client->strut.right));
- PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(self->client->strut.bottom));
- return tuple;
-}
-
-static PyObject *cwrap_logicalSize(ClientWrap *self, PyObject *args)
-{
- PyObject *tuple;
-
- CHECK_CWRAP(self, "logicalSize");
- if (!PyArg_ParseTuple(args, ":logicalSize"))
- return NULL;
- tuple = PyTuple_New(2);
- PyTuple_SET_ITEM(tuple, 0,
- PyInt_FromLong(self->client->logical_size.width));
- PyTuple_SET_ITEM(tuple, 1,
- PyInt_FromLong(self->client->logical_size.height));
- return tuple;
-}
-
-static PyObject *cwrap_minRatio(ClientWrap *self, PyObject *args)
-{
- CHECK_CWRAP(self, "minRatio");
- if (!PyArg_ParseTuple(args, ":minRatio"))
- return NULL;
- return PyFloat_FromDouble(self->client->min_ratio);
-}
-
-static PyObject *cwrap_maxRatio(ClientWrap *self, PyObject *args)
-{
- CHECK_CWRAP(self, "maxRatio");
- if (!PyArg_ParseTuple(args, ":maxRatio"))
- return NULL;
- return PyFloat_FromDouble(self->client->max_ratio);
-}
-
-static PyObject *cwrap_minSize(ClientWrap *self, PyObject *args)
-{
- PyObject *tuple;
-
- CHECK_CWRAP(self, "minSize");
- if (!PyArg_ParseTuple(args, ":minSize"))
- return NULL;
- tuple = PyTuple_New(2);
- PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(self->client->min_size.width));
- PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(self->client->min_size.height));
- return tuple;
-}
-
-static PyObject *cwrap_maxSize(ClientWrap *self, PyObject *args)
-{
- PyObject *tuple;
-
- CHECK_CWRAP(self, "maxSize");
- if (!PyArg_ParseTuple(args, ":maxSize"))
- return NULL;
- tuple = PyTuple_New(2);
- PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(self->client->max_size.width));
- PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(self->client->max_size.height));
- return tuple;
-}
-
-static PyObject *cwrap_sizeIncrement(ClientWrap *self, PyObject *args)
-{
- PyObject *tuple;
-
- CHECK_CWRAP(self, "sizeIncrement");
- if (!PyArg_ParseTuple(args, ":sizeIncrement"))
- return NULL;
- tuple = PyTuple_New(2);
- PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(self->client->size_inc.width));
- PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(self->client->size_inc.height));
- return tuple;
-}
-
-static PyObject *cwrap_baseSize(ClientWrap *self, PyObject *args)
-{
- PyObject *tuple;
-
- CHECK_CWRAP(self, "baseSize");
- if (!PyArg_ParseTuple(args, ":baseSize"))
- return NULL;
- tuple = PyTuple_New(2);
- PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(self->client->base_size.width));
- PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(self->client->base_size.height));
- return tuple;
-}
-
-static PyObject *cwrap_gravity(ClientWrap *self, PyObject *args)
-{
- CHECK_CWRAP(self, "gravity");
- if (!PyArg_ParseTuple(args, ":gravity"))
- return NULL;
- return PyInt_FromLong(self->client->gravity);
-}
-
-static PyObject *cwrap_canClose(ClientWrap *self, PyObject *args)
-{
- CHECK_CWRAP(self, "canClose");
- if (!PyArg_ParseTuple(args, ":canClose"))
- return NULL;
- return PyInt_FromLong(self->client->delete_window ? 1 : 0);
-}
-
-static PyObject *cwrap_positionRequested(ClientWrap *self, PyObject *args)
-{
- CHECK_CWRAP(self, "positionRequested");
- if (!PyArg_ParseTuple(args, ":positionRequested"))
- return NULL;
- return PyInt_FromLong(self->client->positioned ? 1 : 0);
-}
-
-static PyObject *cwrap_canFocus(ClientWrap *self, PyObject *args)
-{
- CHECK_CWRAP(self, "canFocus");
- if (!PyArg_ParseTuple(args, ":canFocus"))
- return NULL;
- return PyInt_FromLong(self->client->can_focus ||
- self->client->focus_notify);
-}
-
-static PyObject *cwrap_urgent(ClientWrap *self, PyObject *args)
-{
- CHECK_CWRAP(self, "urgent");
- if (!PyArg_ParseTuple(args, ":urgent"))
- return NULL;
- return PyInt_FromLong(self->client->urgent ? 1 : 0);
-}
-
-static PyObject *cwrap_focused(ClientWrap *self, PyObject *args)
-{
- CHECK_CWRAP(self, "focused");
- if (!PyArg_ParseTuple(args, ":focused"))
- return NULL;
- return PyInt_FromLong(self->client->focused ? 1 : 0);
-}
-
-static PyObject *cwrap_modal(ClientWrap *self, PyObject *args)
-{
- CHECK_CWRAP(self, "modal");
- if (!PyArg_ParseTuple(args, ":modal"))
- return NULL;
- return PyInt_FromLong(self->client->modal ? 1 : 0);
-}
-
-static PyObject *cwrap_shaded(ClientWrap *self, PyObject *args)
-{
- CHECK_CWRAP(self, "shaded");
- if (!PyArg_ParseTuple(args, ":shaded"))
- return NULL;
- return PyInt_FromLong(self->client->shaded ? 1 : 0);
-}
-
-static PyObject *cwrap_iconic(ClientWrap *self, PyObject *args)
-{
- CHECK_CWRAP(self, "iconic");
- if (!PyArg_ParseTuple(args, ":iconc"))
- return NULL;
- return PyInt_FromLong(self->client->iconic ? 1 : 0);
-}
-
-static PyObject *cwrap_maximizedVertical(ClientWrap *self, PyObject *args)
-{
- CHECK_CWRAP(self, "maximizedVertical");
- if (!PyArg_ParseTuple(args, ":maximizedVertical"))
- return NULL;
- return PyInt_FromLong(self->client->max_vert ? 1 : 0);
-}
-
-static PyObject *cwrap_maximizedHorizontal(ClientWrap *self, PyObject *args)
-{
- CHECK_CWRAP(self, "maximizedHorizontal");
- if (!PyArg_ParseTuple(args, ":maximizedHorizontal"))
- return NULL;
- return PyInt_FromLong(self->client->max_horz ? 1 : 0);
-}
-
-static PyObject *cwrap_skipPager(ClientWrap *self, PyObject *args)
-{
- CHECK_CWRAP(self, "skipPager");
- if (!PyArg_ParseTuple(args, ":skipPager"))
- return NULL;
- return PyInt_FromLong(self->client->skip_pager ? 1 : 0);
-}
-
-static PyObject *cwrap_skipTaskbar(ClientWrap *self, PyObject *args)
-{
- CHECK_CWRAP(self, "skipTaskbar");
- if (!PyArg_ParseTuple(args, ":skipTaskbar"))
- return NULL;
- return PyInt_FromLong(self->client->skip_taskbar ? 1 : 0);
-}
-
-static PyObject *cwrap_fullscreen(ClientWrap *self, PyObject *args)
-{
- CHECK_CWRAP(self, "fullscreen");
- if (!PyArg_ParseTuple(args, ":fullscreen"))
- return NULL;
- return PyInt_FromLong(self->client->fullscreen ? 1 : 0);
-}
-
-static PyObject *cwrap_above(ClientWrap *self, PyObject *args)
-{
- CHECK_CWRAP(self, "above");
- if (!PyArg_ParseTuple(args, ":above"))
- return NULL;
- return PyInt_FromLong(self->client->above ? 1 : 0);
-}
-
-static PyObject *cwrap_below(ClientWrap *self, PyObject *args)
-{
- CHECK_CWRAP(self, "below");
- if (!PyArg_ParseTuple(args, ":below"))
- return NULL;
- return PyInt_FromLong(self->client->below ? 1 : 0);
-}
-
-static PyObject *cwrap_layer(ClientWrap *self, PyObject *args)
-{
- CHECK_CWRAP(self, "layer");
- if (!PyArg_ParseTuple(args, ":layer"))
- return NULL;
- return PyInt_FromLong(self->client->layer);
-}
-
-static PyObject *cwrap_decorations(ClientWrap *self, PyObject *args)
-{
- CHECK_CWRAP(self, "decorations");
- if (!PyArg_ParseTuple(args, ":decorations"))
- return NULL;
- return PyInt_FromLong(self->client->decorations);
-}
-
-static PyObject *cwrap_disabledDecorations(ClientWrap *self, PyObject *args)
-{
- CHECK_CWRAP(self, "disabledDecorations");
- if (!PyArg_ParseTuple(args, ":disabledDecorations"))
- return NULL;
- return PyInt_FromLong(self->client->disabled_decorations);
-}
-
-static PyObject *cwrap_functions(ClientWrap *self, PyObject *args)
-{
- CHECK_CWRAP(self, "functions");
- if (!PyArg_ParseTuple(args, ":functions"))
- return NULL;
- return PyInt_FromLong(self->client->functions);
-}
-
-static PyObject *cwrap_visible(ClientWrap *self, PyObject *args)
-{
- CHECK_CWRAP(self, "visible");
- if (!PyArg_ParseTuple(args, ":visible"))
- return NULL;
- return PyInt_FromLong(self->client->frame->visible ? 1 : 0);
-}
-
-static PyObject *cwrap_decorationSize(ClientWrap *self, PyObject *args)
-{
- PyObject *tuple;
-
- CHECK_CWRAP(self, "decorationSize");
- if (!PyArg_ParseTuple(args, ":decorationSize"))
- return NULL;
- tuple = PyTuple_New(4);
- PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(self->client->frame->size.left));
- PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(self->client->frame->size.top));
- PyTuple_SET_ITEM(tuple, 2,
- PyInt_FromLong(self->client->frame->size.right));
- PyTuple_SET_ITEM(tuple, 3,
- PyInt_FromLong(self->client->frame->size.bottom));
- return tuple;
-}
-
-static PyObject *cwrap_normal(ClientWrap *self, PyObject *args)
-{
- CHECK_CWRAP(self, "normal");
- if (!PyArg_ParseTuple(args, ":normal"))
- return NULL;
- return PyInt_FromLong(client_normal(self->client) ? 1 : 0);
-}
-
-static PyObject *cwrap_setVisible(ClientWrap *self, PyObject *args)
-{
- int i;
-
- CHECK_CWRAP(self, "setVisible");
- if (!PyArg_ParseTuple(args, "i:setVisible", &i))
- return NULL;
- if (i)
- frame_show(self->client->frame);
- else
- frame_hide(self->client->frame);
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-static PyObject *cwrap_raiseWindow(ClientWrap *self, PyObject *args)
-{
- CHECK_CWRAP(self, "raiseWindow");
- if (!PyArg_ParseTuple(args, ":raiseWindow"))
- return NULL;
- stacking_raise(self->client);
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-static PyObject *cwrap_lowerWindow(ClientWrap *self, PyObject *args)
-{
- CHECK_CWRAP(self, "lowerWindow");
- if (!PyArg_ParseTuple(args, ":lowerWindow"))
- return NULL;
- stacking_lower(self->client);
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-static PyObject *cwrap_focus(ClientWrap *self, PyObject *args)
-{
- CHECK_CWRAP(self, "focus");
- if (!PyArg_ParseTuple(args, ":focus"))
- return NULL;
- return PyInt_FromLong(client_focus(self->client) ? 1 : 0);
-}
-
-static PyObject *cwrap_unfocus(ClientWrap *self, PyObject *args)
-{
- CHECK_CWRAP(self, "unfocus");
- if (!PyArg_ParseTuple(args, ":unfocus"))
- return NULL;
- client_unfocus(self->client);
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-static PyObject *cwrap_move(ClientWrap *self, PyObject *args)
-{
- int x, y;
- int final = TRUE;
- CHECK_CWRAP(self, "move");
- if (!PyArg_ParseTuple(args, "ii|i:unfocus", &x, &y, &final))
- return NULL;
- /* get the client's position based on x,y for the frame */
- frame_frame_gravity(self->client->frame, &x, &y);
-
- client_configure(self->client, Corner_TopLeft, x, y,
- self->client->area.width, self->client->area.height,
- TRUE, final);
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-#define ATTRMETH(n, d) {#n, (PyCFunction)cwrap_##n, METH_VARARGS, #d}
-
-static PyMethodDef ClientWrapMethods[] = {
- ATTRMETH(window,
- "c.window() -- Returns the window id for the Client."),
- ATTRMETH(group,
- "c.group() -- Returns the group id for the Client."),
- ATTRMETH(parent,
- "c.parent() -- Returns the parent Client for the Client, or the "
- "Client for which this Client is a transient. Returns None if it "
- "is not a transient."),
- ATTRMETH(children,
- "c.parent() -- Returns a list of child Clients for the Client, "
- "or the Clients transients."),
- ATTRMETH(desktop,
- "c.desktop() -- Returns the desktop on which the Client resides, "
- "or 0xffffffff for 'all desktops'."),
- ATTRMETH(title,
- "c.title() -- Returns the Client's title string. This is in "
- "UTF-8 encoding."),
- ATTRMETH(iconTitle,
- "c.iconTitle() -- Returns the Client's icon title string. This "
- "is in UTF-8 encoding."),
- ATTRMETH(resName,
- "c.resName() -- Returns the application's specified resource "
- "name."),
- ATTRMETH(resClass,
- "c.resClass() -- Returns the application's specified resource "
- "class."),
- ATTRMETH(role,
- "c.role() -- Returns the window's role, which should be unique "
- "for every window of an application, if it is not empty."),
- ATTRMETH(type,
- "c.type() -- Returns the window's type, one of the ob.Type_ "
- "constants. This is the logical type of the window."),
- ATTRMETH(area,
- "c.area() -- Returns the area rectangle for the Client in a "
- "tuple. The tuple's format is (x, y, width, height). This is "
- "not the area on-screen that the Client and frame occupies, but "
- "rather, the position and size that the Client has requested, "
- "before its gravity() and decorations have been applied. You "
- "should use the c.screenArea() to get the actual on-screen area "
- "for the Client."),
- ATTRMETH(screenArea,
- "c.screenArea() -- Returns the on-screen area rectangle for the "
- "Client in a tuple. The tuple's format is (x, y, width, height). "
- "This is the actual position and size of the Client plus its "
- "decorations."),
- ATTRMETH(strut,
- "c.strut() -- Returns the strut requested by the Client in a "
- "tuple. The format of the tuple is (left, top, right, bottom)."),
- ATTRMETH(logicalSize,
- "c.logicalSize() -- Returns the logical size of the Client. This "
- "is the 'user friendly' size for the Client, such as for an "
- "xterm, it will be the number of characters in the xterm "
- "instead of the number of pixels it takes up."),
- ATTRMETH(minRatio,
- "c.minRatio() -- Returns the minimum width:height ratio for "
- "the Client. A value of 0 implies no ratio enforcement."),
- ATTRMETH(maxRatio,
- "c.maxRatio() -- Returns the maximum width:height ratio for "
- "the Client. A value of 0 implies no ratio enforcement."),
- ATTRMETH(minSize,
- "c.minSize() -- Returns the minimum size of the Client."),
- ATTRMETH(maxSize,
- "c.maxSize() -- Returns the maximum size of the Client."),
- ATTRMETH(sizeIncrement,
- "c.sizeIncrement() -- Returns the size increments in which the "
- "Client must be resized."),
- ATTRMETH(baseSize,
- "c.baseSize() -- Returns the base size of the Client, which is "
- "subtracted from the Client's size before comparing to its "
- "various sizing constraints."),
- ATTRMETH(gravity,
- "c.gravity() -- Returns the gravity for the Client. One of the "
- "ob.Gravity_ constants."),
- ATTRMETH(canClose,
- "c.canClose() -- Returns whether or not the Client provides a "
- "means for Openbox to request that it close."),
- ATTRMETH(positionRequested,
- "c.positionRequested() -- Returns whether or not the Client has "
- "requested a specified position on screen. When it has it should "
- "probably not be placed using an algorithm when it is managed."),
- ATTRMETH(canFocus,
- "c.canFocus() -- Returns whether or not the Client can be "
- "given input focus."),
- ATTRMETH(urgent,
- "c.urgent() -- Returns the urgent state of the window (on/off)."),
- ATTRMETH(focused,
- "c.focused() -- Returns whether or not the Client has the input "
- "focus."),
- ATTRMETH(modal,
- "c.modal() -- Returns whether or not the Client is modal. A "
- "modal Client implies that it needs to be closed before its "
- "parent() can be used (focsed) again."),
- ATTRMETH(shaded,
- "c.shaded() -- Returns whether or not the Client is shaded. "
- "Shaded clients are hidden except for their titlebar."),
- ATTRMETH(iconic,
- "c.iconic() -- Returns whether or not the Client is iconic. "
- "Iconic windows are represented only by icons, or possibly "
- "hidden entirely."),
- ATTRMETH(maximizedVertical,
- "c.maximizedVertical() -- Returns whether or not the Client is "
- "maxized vertically. When a Client is maximized it will expand "
- "to fill as much of the screen as it can in that direction."),
- ATTRMETH(maximizedHorizontal,
- "c.maximizedHorizontal() -- Returns whether or not the Client is "
- "maxized horizontally. When a Client is maximized it will expand "
- "to fill as much of the screen as it can in that direction."),
- ATTRMETH(skipPager,
- "c.skipPager() -- Returns whether the Client as requested to be "
- "skipped by pagers."),
- ATTRMETH(skipTaskbar,
- "c.skipTaskbar() -- Returns whether the Client as requested to "
- "be skipped by taskbars."),
- ATTRMETH(fullscreen,
- "c.fullscreen() -- Returns whether the Client is in fullscreen "
- "mode."),
- ATTRMETH(above,
- "c.above() -- Returns whether the Client should be stacked above "
- "other windows of the same type."),
- ATTRMETH(below,
- "c.below() -- Returns whether the Client should be stacked below "
- "other windows of the same type."),
- ATTRMETH(layer,
- "c.layer() -- Returns the layer in which the window should be "
- "stacked. This is one of the ob.Layer_ constants. Windows in "
- "layers with higher values should be kept above windows in lower "
- "valued layers."),
- ATTRMETH(decorations,
- "c.decorations() -- Returns a mask of decorations which the "
- "Client will be given. It is made up of the ob.Decor_ constants. "
- "These can be turned off with the "
- " disabledDecorations()."),
- ATTRMETH(disabledDecorations,
- "c.disabledDecorations() -- returns a mask of decorations which "
- "are disabled on the Client. This is made up of the ob.Decor_ "
- "constants."),
- ATTRMETH(functions,
- "ob.functions() -- Returns the list of functionality for the "
- "Client, in a mask made up of the ob.Func_ constants."),
- ATTRMETH(visible,
- "ob.visible() -- Returns if the client is currently visible "
- "or hidden."),
- ATTRMETH(decorationSize,
- "c.decorationSize() -- Returns the size of the Client's "
- "decorations around the Client window, in a tuple. The format of "
- "the tuple is (left, top, right, bottom)."),
- ATTRMETH(normal,
- "c.normal() -- Returns if the window should be treated as a "
- "normal window. Some windows (desktops, docks, splash screens) "
- "should have special rules applied to them in a number of "
- "places regarding focus or user interaction."),
- ATTRMETH(setVisible,
- "c.setVisible(show) -- Shows or hides the Client."),
- ATTRMETH(raiseWindow,
- "c.raiseWindow() -- Raises the Client to the top of its layer."),
- ATTRMETH(lowerWindow,
- "c.lowerWindow() -- Lowers the Client to the bottom of its "
- "layer."),
- ATTRMETH(focus,
- "c.focus() -- Focuses the Client. Returns 1 if the Client will "
- "be focused, or 0 if it will not."),
- ATTRMETH(unfocus,
- "c.unfocus() -- Unfocuses the Client, leaving nothing focused."),
- ATTRMETH(move,
- "c.move(x, y) -- Moves the Client to the specified position. The "
- "top left corner of the Client's decorations is positioned at "
- "the given x, y."),
- { NULL, NULL, 0, NULL }
-};
-
-/***************************************************************************
-
- Type methods/struct
-
- ***************************************************************************/
-
-/*static PyObject *cwrap_getattr(ClientWrap *self, char *name)
-{
- CHECK_CWRAP(self, "getattr");
- return Py_FindMethod(ClientWrapAttributeMethods, (PyObject*)self, name);
-}*/
-
-static void cwrap_dealloc(ClientWrap *self)
-{
- if (self->client != NULL)
- self->client->wrap = NULL;
- PyObject_Del((PyObject*) self);
-}
-
-static PyObject *cwrap_repr(ClientWrap *self)
-{
- CHECK_CWRAP(self, "repr");
- return PyString_FromFormat("0x%x", (guint)self->client->window);
-}
-
-static int cwrap_compare(ClientWrap *self, ClientWrap *other)
-{
- Window w1, w2;
- if (!IS_VALID_CWRAP(self)) {
- PyErr_SetString(PyExc_ValueError,
- "This 'Client' is wrapping a client which no longer "
- "exists.");
- }
-
- w1 = self->client->window;
- w2 = self->client->window;
- return w1 > w2 ? 1 : w1 < w2 ? -1 : 0;
-}
-
-static PyTypeObject ClientWrapType = {
- PyObject_HEAD_INIT(NULL)
- 0,
- "Client",
- sizeof(ClientWrap),
- 0,
- (destructor) cwrap_dealloc, /*tp_dealloc*/
- 0, /*tp_print*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- (cmpfunc) cwrap_compare, /*tp_compare*/
- (reprfunc) cwrap_repr, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash */
-};
-
-/***************************************************************************
-
- External methods
-
- ***************************************************************************/
-
-void clientwrap_startup()
-{
- ClientWrapType.ob_type = &PyType_Type;
- ClientWrapType.tp_methods = ClientWrapMethods;
- PyType_Ready(&ClientWrapType);
-}
-
-void clientwrap_shutdown()
-{
-}
-
-PyObject *clientwrap_new(Client *client)
-{
- g_assert(client != NULL);
-
- if (client->wrap != NULL) {
- /* already has a wrapper! */
- Py_INCREF((PyObject*) client->wrap);
- } else {
- client->wrap = PyObject_New(ClientWrap, &ClientWrapType);
- client->wrap->client = client;
- }
- return (PyObject*) client->wrap;
-}
+++ /dev/null
-#ifndef __clientwrap_h
-#define __clientwrap_h
-
-#include <Python.h>
-
-struct Client;
-
-/* ClientWrap is a PyObject */
-typedef struct ClientWrap {
- PyObject_HEAD
- struct Client *client;
-} ClientWrap;
-
-void clientwrap_startup();
-void clientwrap_shutdown();
-
-PyObject *clientwrap_new(struct Client *client);
-
-#endif
+++ /dev/null
-#include "openbox.h"
-#include "client.h"
-#include "xerror.h"
-#include "prop.h"
-#include "screen.h"
-#include "frame.h"
-#include "focus.h"
-#include "hooks.h"
-#include "stacking.h"
-#include "kbind.h"
-#include "mbind.h"
-
-#include <X11/Xlib.h>
-#include <X11/keysym.h>
-#include <X11/Xatom.h>
-
-static void event_process(XEvent *e);
-static void event_handle_root(XEvent *e);
-static void event_handle_client(Client *c, XEvent *e);
-
-Time event_lasttime = 0;
-
-/*! A list of all possible combinations of keyboard lock masks */
-static unsigned int mask_list[8];
-/*! The value of the mask for the NumLock modifier */
-static unsigned int NumLockMask;
-/*! The value of the mask for the ScrollLock modifier */
-static unsigned int ScrollLockMask;
-/*! The key codes for the modifier keys */
-static XModifierKeymap *modmap;
-/*! Table of the constant modifier masks */
-static const int mask_table[] = {
- ShiftMask, LockMask, ControlMask, Mod1Mask,
- Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask
-};
-static int mask_table_size;
-
-void event_startup()
-{
- mask_table_size = sizeof(mask_table) / sizeof(mask_table[0]);
-
- /* get lock masks that are defined by the display (not constant) */
- modmap = XGetModifierMapping(ob_display);
- g_assert(modmap);
- if (modmap && modmap->max_keypermod > 0) {
- size_t cnt;
- const size_t size = mask_table_size * modmap->max_keypermod;
- /* get the values of the keyboard lock modifiers
- Note: Caps lock is not retrieved the same way as Scroll and Num
- lock since it doesn't need to be. */
- const KeyCode num_lock = XKeysymToKeycode(ob_display, XK_Num_Lock);
- const KeyCode scroll_lock = XKeysymToKeycode(ob_display,
- XK_Scroll_Lock);
-
- for (cnt = 0; cnt < size; ++cnt) {
- if (! modmap->modifiermap[cnt]) continue;
-
- if (num_lock == modmap->modifiermap[cnt])
- NumLockMask = mask_table[cnt / modmap->max_keypermod];
- if (scroll_lock == modmap->modifiermap[cnt])
- ScrollLockMask = mask_table[cnt / modmap->max_keypermod];
- }
- }
-
- mask_list[0] = 0;
- mask_list[1] = LockMask;
- mask_list[2] = NumLockMask;
- mask_list[3] = LockMask | NumLockMask;
- mask_list[4] = ScrollLockMask;
- mask_list[5] = ScrollLockMask | LockMask;
- mask_list[6] = ScrollLockMask | NumLockMask;
- mask_list[7] = ScrollLockMask | LockMask | NumLockMask;
-}
-
-void event_shutdown()
-{
- XFreeModifiermap(modmap);
-}
-
-void event_loop()
-{
- fd_set selset;
- XEvent e;
- int x_fd;
-
- while (TRUE) {
- /*
- There are slightly different event retrieval semantics here for
- local (or high bandwidth) versus remote (or low bandwidth)
- connections to the display/Xserver.
- */
- if (ob_remote) {
- if (!XPending(ob_display))
- break;
- } else {
- /*
- This XSync allows for far more compression of events, which
- makes things like Motion events perform far far better. Since
- it also means network traffic for every event instead of every
- X events (where X is the number retrieved at a time), it
- probably should not be used for setups where Openbox is
- running on a remote/low bandwidth display/Xserver.
- */
- XSync(ob_display, FALSE);
- if (!XEventsQueued(ob_display, QueuedAlready))
- break;
- }
- XNextEvent(ob_display, &e);
-
- event_process(&e);
- }
-
- x_fd = ConnectionNumber(ob_display);
- FD_ZERO(&selset);
- FD_SET(x_fd, &selset);
- select(x_fd + 1, &selset, NULL, NULL, NULL);
-}
-
-void event_process(XEvent *e)
-{
- XEvent ce;
- KeyCode *kp;
- Window window;
- int i, k;
- Client *client;
- GQuark context;
- static guint motion_button = 0;
-
- /* pick a window */
- switch (e->type) {
- case UnmapNotify:
- window = e->xunmap.window;
- break;
- case DestroyNotify:
- window = e->xdestroywindow.window;
- break;
- case ConfigureRequest:
- window = e->xconfigurerequest.window;
- break;
- default:
- window = e->xany.window;
- }
-
- /* grab the lasttime and hack up the state */
- switch (e->type) {
- case ButtonPress:
- case ButtonRelease:
- event_lasttime = e->xbutton.time;
- e->xbutton.state &= ~(LockMask | NumLockMask | ScrollLockMask);
- /* kill off the Button1Mask etc, only want the modifiers */
- e->xbutton.state &= (ControlMask | ShiftMask | Mod1Mask |
- Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask);
- break;
- case KeyPress:
- event_lasttime = e->xkey.time;
- e->xkey.state &= ~(LockMask | NumLockMask | ScrollLockMask);
- /* kill off the Button1Mask etc, only want the modifiers */
- e->xkey.state &= (ControlMask | ShiftMask | Mod1Mask |
- Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask);
- /* add to the state the mask of the modifier being pressed, if it is
- a modifier key being pressed (this is a little ugly..) */
-/* I'm commenting this out cuz i don't want "C-Control_L" being returned. */
-/* kp = modmap->modifiermap;*/
-/* for (i = 0; i < mask_table_size; ++i) {*/
-/* for (k = 0; k < modmap->max_keypermod; ++k) {*/
-/* if (*kp == e->xkey.keycode) {*/ /* found the keycode */
- /* add the mask for it */
-/* e->xkey.state |= mask_table[i];*/
- /* cause the first loop to break; */
-/* i = mask_table_size;*/
-/* break;*/ /* get outta here! */
-/* }*/
-/* ++kp;*/
-/* }*/
-/* }*/
-
- break;
- case KeyRelease:
- event_lasttime = e->xkey.time;
- e->xkey.state &= ~(LockMask | NumLockMask | ScrollLockMask);
- /* kill off the Button1Mask etc, only want the modifiers */
- e->xkey.state &= (ControlMask | ShiftMask | Mod1Mask |
- Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask);
- /* remove from the state the mask of the modifier being released, if
- it is a modifier key being released (this is a little ugly..) */
- kp = modmap->modifiermap;
- for (i = 0; i < mask_table_size; ++i) {
- for (k = 0; k < modmap->max_keypermod; ++k) {
- if (*kp == e->xkey.keycode) { /* found the keycode */
- /* remove the mask for it */
- e->xkey.state &= ~mask_table[i];
- /* cause the first loop to break; */
- i = mask_table_size;
- break; /* get outta here! */
- }
- ++kp;
- }
- }
- break;
- case MotionNotify:
- event_lasttime = e->xmotion.time;
- e->xmotion.state &= ~(LockMask | NumLockMask | ScrollLockMask);
- /* kill off the Button1Mask etc, only want the modifiers */
- e->xmotion.state &= (ControlMask | ShiftMask | Mod1Mask |
- Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask);
- /* compress events */
- while (XCheckTypedWindowEvent(ob_display, window, e->type, &ce)) {
- e->xmotion.x_root = ce.xmotion.x_root;
- e->xmotion.y_root = ce.xmotion.y_root;
- }
- break;
- case PropertyNotify:
- event_lasttime = e->xproperty.time;
- break;
- case FocusIn:
- case FocusOut:
- if (e->xfocus.mode == NotifyGrab)
- /*|| e.xfocus.mode == NotifyUngrab ||*/
-
- /* From Metacity, from WindowMaker, ignore all funky pointer
- root events. Its commented out cuz I don't think we need this
- at all. If problems arise we can look into it */
- /*e.xfocus.detail > NotifyNonlinearVirtual) */
- return; /* skip me! */
- if (e->type == FocusOut) {
- /* FocusOut events just make us look for FocusIn events. They
- are mostly ignored otherwise. */
- XEvent fi;
- if (XCheckTypedEvent(ob_display, FocusIn, &fi)) {
- event_process(&fi);
- /* dont unfocus the window we just focused! */
- if (fi.xfocus.window == e->xfocus.window)
- return;
- }
- }
- break;
- case EnterNotify:
- case LeaveNotify:
- event_lasttime = e->xcrossing.time;
- if (e->xcrossing.mode != NotifyNormal)
- return; /* skip me! */
- break;
- }
-
- client = g_hash_table_lookup(client_map, (gpointer)window);
- if (client) {
- event_handle_client(client, e);
- } else if (window == ob_root)
- event_handle_root(e);
- else if (e->type == ConfigureRequest) {
- /* unhandled configure requests must be used to configure the
- window directly */
- XWindowChanges xwc;
-
- xwc.x = e->xconfigurerequest.x;
- xwc.y = e->xconfigurerequest.y;
- xwc.width = e->xconfigurerequest.width;
- xwc.height = e->xconfigurerequest.height;
- xwc.border_width = e->xconfigurerequest.border_width;
- xwc.sibling = e->xconfigurerequest.above;
- xwc.stack_mode = e->xconfigurerequest.detail;
-
- g_message("Proxying configure event for 0x%lx\n", window);
-
- /* we are not to be held responsible if someone sends us an
- invalid request! */
- xerror_set_ignore(TRUE);
- XConfigureWindow(ob_display, window,
- e->xconfigurerequest.value_mask, &xwc);
- xerror_set_ignore(FALSE);
- }
-
- /* dispatch Crossing, Pointer and Key events to the hooks */
- switch(e->type) {
- case EnterNotify:
- context = frame_get_context(client, window);
- LOGICALHOOK(EnterWindow, context, client);
- break;
- case LeaveNotify:
- context = frame_get_context(client, window);
- LOGICALHOOK(LeaveWindow, context, client);
- break;
- case ButtonPress:
- if (!motion_button) motion_button = e->xbutton.button;
- context = frame_get_context(client, window);
- mbind_fire(e->xbutton.state, e->xbutton.button, context,
- Pointer_Press, client, e->xbutton.x_root,
- e->xbutton.y_root);
- break;
- case ButtonRelease:
- if (motion_button == e->xbutton.button) motion_button = 0;
- context = frame_get_context(client, window);
- mbind_fire(e->xbutton.state, e->xbutton.button, context,
- Pointer_Release, client, e->xbutton.x_root,
- e->xbutton.y_root);
- break;
- case MotionNotify:
- context = frame_get_context(client, window);
- mbind_fire(e->xkey.state, motion_button, context, Pointer_Motion,
- client, e->xmotion.x_root, e->xmotion.y_root);
- break;
- case KeyPress:
- kbind_fire(e->xkey.state, e->xkey.keycode, TRUE);
- break;
- case KeyRelease:
- kbind_fire(e->xkey.state, e->xkey.keycode, FALSE);
- break;
- }
-}
-
-static void event_handle_root(XEvent *e)
-{
- Atom msgtype;
-
- switch(e->type) {
- case MapRequest:
- g_message("MapRequest on root");
- client_manage(e->xmap.window);
- break;
- case ClientMessage:
- if (e->xclient.format != 32) break;
-
- msgtype = e->xclient.message_type;
- if (msgtype == prop_atoms.net_current_desktop) {
- unsigned int d = e->xclient.data.l[0];
- if (d <= screen_num_desktops)
- screen_set_desktop(d);
- } else if (msgtype == prop_atoms.net_number_of_desktops) {
- unsigned int d = e->xclient.data.l[0];
- if (d > 0)
- screen_set_num_desktops(d);
- } else if (msgtype == prop_atoms.net_showing_desktop) {
- screen_show_desktop(e->xclient.data.l[0] != 0);
- }
- break;
- case PropertyNotify:
- if (e->xproperty.atom == prop_atoms.net_desktop_names)
- screen_update_desktop_names();
- else if (e->xproperty.atom == prop_atoms.net_desktop_layout)
- screen_update_layout();
- break;
- }
-}
-
-static void event_handle_client(Client *client, XEvent *e)
-{
- XEvent ce;
- Atom msgtype;
-
- switch (e->type) {
- case FocusIn:
- client->focused = TRUE;
- frame_adjust_focus(client->frame);
-
- /* focus state can affect the stacking layer */
- client_calc_layer(client);
-
- focus_set_client(client);
- break;
- case FocusOut:
- client->focused = FALSE;
- frame_adjust_focus(client->frame);
-
- /* focus state can affect the stacking layer */
- client_calc_layer(client);
-
- if (focus_client == client)
- focus_set_client(NULL);
- break;
- case ConfigureRequest:
- g_message("ConfigureRequest for window %lx", client->window);
- /* compress these */
- while (XCheckTypedWindowEvent(ob_display, client->window,
- ConfigureRequest, &ce)) {
- /* XXX if this causes bad things.. we can compress config req's
- with the same mask. */
- e->xconfigurerequest.value_mask |=
- ce.xconfigurerequest.value_mask;
- if (ce.xconfigurerequest.value_mask & CWX)
- e->xconfigurerequest.x = ce.xconfigurerequest.x;
- if (ce.xconfigurerequest.value_mask & CWY)
- e->xconfigurerequest.y = ce.xconfigurerequest.y;
- if (ce.xconfigurerequest.value_mask & CWWidth)
- e->xconfigurerequest.width = ce.xconfigurerequest.width;
- if (ce.xconfigurerequest.value_mask & CWHeight)
- e->xconfigurerequest.height = ce.xconfigurerequest.height;
- if (ce.xconfigurerequest.value_mask & CWBorderWidth)
- e->xconfigurerequest.border_width =
- ce.xconfigurerequest.border_width;
- if (ce.xconfigurerequest.value_mask & CWStackMode)
- e->xconfigurerequest.detail = ce.xconfigurerequest.detail;
- }
-
- /* if we are iconic (or shaded (fvwm does this)) ignore the event */
- if (client->iconic || client->shaded) return;
-
- if (e->xconfigurerequest.value_mask & CWBorderWidth)
- client->border_width = e->xconfigurerequest.border_width;
-
- /* resize, then move, as specified in the EWMH section 7.7 */
- if (e->xconfigurerequest.value_mask & (CWWidth | CWHeight |
- CWX | CWY)) {
- int x, y, w, h;
- Corner corner;
-
- x = (e->xconfigurerequest.value_mask & CWX) ?
- e->xconfigurerequest.x : client->area.x;
- y = (e->xconfigurerequest.value_mask & CWY) ?
- e->xconfigurerequest.y : client->area.y;
- w = (e->xconfigurerequest.value_mask & CWWidth) ?
- e->xconfigurerequest.width : client->area.width;
- h = (e->xconfigurerequest.value_mask & CWHeight) ?
- e->xconfigurerequest.height : client->area.height;
-
- switch (client->gravity) {
- case NorthEastGravity:
- case EastGravity:
- corner = Corner_TopRight;
- break;
- case SouthWestGravity:
- case SouthGravity:
- corner = Corner_BottomLeft;
- break;
- case SouthEastGravity:
- corner = Corner_BottomRight;
- break;
- default: /* NorthWest, Static, etc */
- corner = Corner_TopLeft;
- }
-
- client_configure(client, corner, x, y, w, h, FALSE, FALSE);
- }
-
- if (e->xconfigurerequest.value_mask & CWStackMode) {
- switch (e->xconfigurerequest.detail) {
- case Below:
- case BottomIf:
- stacking_lower(client);
- break;
-
- case Above:
- case TopIf:
- default:
- stacking_raise(client);
- break;
- }
- }
- break;
- case UnmapNotify:
- if (client->ignore_unmaps) {
- client->ignore_unmaps--;
- break;
- }
- g_message("UnmapNotify for %lx", client->window);
- client_unmanage(client);
- break;
- case DestroyNotify:
- g_message("DestroyNotify for %lx", client->window);
- client_unmanage(client);
- break;
- case ReparentNotify:
- /* this is when the client is first taken captive in the frame */
- if (e->xreparent.parent == client->frame->plate) break;
-
- /*
- This event is quite rare and is usually handled in unmapHandler.
- However, if the window is unmapped when the reparent event occurs,
- the window manager never sees it because an unmap event is not sent
- to an already unmapped window.
- */
-
- /* we don't want the reparent event, put it back on the stack for the
- X server to deal with after we unmanage the window */
- XPutBackEvent(ob_display, e);
-
- client_unmanage(client);
- break;
- case MapRequest:
- /* we shouldn't be able to get this unless we're iconic */
- g_assert(client->iconic);
-
- LOGICALHOOK(RequestActivate, g_quark_try_string("client"), client);
- break;
- case ClientMessage:
- /* validate cuz we query stuff off the client here */
- if (!client_validate(client)) break;
-
- if (e->xclient.format != 32) return;
-
- msgtype = e->xclient.message_type;
- if (msgtype == prop_atoms.wm_change_state) {
- /* compress changes into a single change */
- while (XCheckTypedWindowEvent(ob_display, e->type,
- client->window, &ce)) {
- /* XXX: it would be nice to compress ALL messages of a
- type, not just messages in a row without other
- message types between. */
- if (ce.xclient.message_type != msgtype) {
- XPutBackEvent(ob_display, &ce);
- break;
- }
- e->xclient = ce.xclient;
- }
- client_set_wm_state(client, e->xclient.data.l[0]);
- } else if (msgtype == prop_atoms.net_wm_desktop) {
- /* compress changes into a single change */
- while (XCheckTypedWindowEvent(ob_display, e->type,
- client->window, &ce)) {
- /* XXX: it would be nice to compress ALL messages of a
- type, not just messages in a row without other
- message types between. */
- if (ce.xclient.message_type != msgtype) {
- XPutBackEvent(ob_display, &ce);
- break;
- }
- e->xclient = ce.xclient;
- }
- client_set_desktop(client, e->xclient.data.l[0]);
- } else if (msgtype == prop_atoms.net_wm_state) {
- /* can't compress these */
- g_message("net_wm_state %s %ld %ld for 0x%lx\n",
- (e->xclient.data.l[0] == 0 ? "Remove" :
- e->xclient.data.l[0] == 1 ? "Add" :
- e->xclient.data.l[0] == 2 ? "Toggle" : "INVALID"),
- e->xclient.data.l[1], e->xclient.data.l[2],
- client->window);
- client_set_state(client, e->xclient.data.l[0],
- e->xclient.data.l[1], e->xclient.data.l[2]);
- } else if (msgtype == prop_atoms.net_close_window) {
- g_message("net_close_window for 0x%lx\n", client->window);
- client_close(client);
- } else if (msgtype == prop_atoms.net_active_window) {
- g_message("net_active_window for 0x%lx\n", client->window);
- if (screen_showing_desktop)
- screen_show_desktop(FALSE);
- if (client->iconic)
- client_iconify(client, FALSE, TRUE);
- else if (!client->frame->visible)
- /* if its not visible for other reasons, then don't mess
- with it */
- return;
- LOGICALHOOK(RequestActivate, g_quark_try_string("client"), client);
- }
- break;
- case PropertyNotify:
- /* validate cuz we query stuff off the client here */
- if (!client_validate(client)) break;
-
- /* compress changes to a single property into a single change */
- while (XCheckTypedWindowEvent(ob_display, e->type,
- client->window, &ce)) {
- /* XXX: it would be nice to compress ALL changes to a property,
- not just changes in a row without other props between. */
- if (ce.xproperty.atom != e->xproperty.atom) {
- XPutBackEvent(ob_display, &ce);
- break;
- }
- }
-
- msgtype = e->xproperty.atom;
- if (msgtype == XA_WM_NORMAL_HINTS) {
- client_update_normal_hints(client);
- /* normal hints can make a window non-resizable */
- client_setup_decor_and_functions(client);
- } else if (msgtype == XA_WM_HINTS)
- client_update_wmhints(client);
- else if (msgtype == XA_WM_TRANSIENT_FOR) {
- client_update_transient_for(client);
- client_get_type(client);
- /* type may have changed, so update the layer */
- client_calc_layer(client);
- client_setup_decor_and_functions(client);
- }
- else if (msgtype == prop_atoms.net_wm_name ||
- msgtype == prop_atoms.wm_name)
- client_update_title(client);
- else if (msgtype == prop_atoms.net_wm_icon_name ||
- msgtype == prop_atoms.wm_icon_name)
- client_update_icon_title(client);
- else if (msgtype == prop_atoms.wm_class)
- client_update_class(client);
- else if (msgtype == prop_atoms.wm_protocols) {
- client_update_protocols(client);
- client_setup_decor_and_functions(client);
- }
- else if (msgtype == prop_atoms.net_wm_strut)
- client_update_strut(client);
- else if (msgtype == prop_atoms.net_wm_icon)
- client_update_icons(client);
- else if (msgtype == prop_atoms.kwm_win_icon)
- client_update_kwm_icon(client);
- }
-}
+++ /dev/null
-#ifndef __events_h
-#define __events_h
-
-/*! Time at which the last event with a timestamp occured. */
-extern Time event_lasttime;
-
-void event_startup();
-void event_shutdown();
-
-void event_loop();
-
-#endif
+++ /dev/null
-#include "eventdata.h"
-#include "openbox.h"
-#include "event.h"
-#include "clientwrap.h"
-#include <X11/Xlib.h>
-
-/*
- *
- * Define the type 'EventData'
- *
- */
-
-#define IS_EVENTDATA(v) ((v)->ob_type == &EventDataType)
-#define CHECK_EVENTDATA(self, funcname) { \
- if (!IS_EVENTDATA(self)) { \
- PyErr_SetString(PyExc_TypeError, \
- "descriptor '" funcname "' requires an 'EventData' " \
- "object"); \
- return NULL; \
- } \
-}
-
-staticforward PyTypeObject EventDataType;
-
-static PyObject *eventdata_type(EventData *self, PyObject *args)
-{
- CHECK_EVENTDATA(self, "type");
- if (!PyArg_ParseTuple(args, ":type"))
- return NULL;
- return PyInt_FromLong(self->type);
-}
-
-static PyObject *eventdata_time(EventData *self, PyObject *args)
-{
- CHECK_EVENTDATA(self, "time");
- if (!PyArg_ParseTuple(args, ":time"))
- return NULL;
- return PyInt_FromLong(event_lasttime);
-}
-
-static PyObject *eventdata_context(EventData *self, PyObject *args)
-{
- CHECK_EVENTDATA(self, "context");
- if (!PyArg_ParseTuple(args, ":context"))
- return NULL;
- return PyString_FromString(self->context);
-}
-
-static PyObject *eventdata_client(EventData *self, PyObject *args)
-{
- CHECK_EVENTDATA(self, "client");
- if (!PyArg_ParseTuple(args, ":client"))
- return NULL;
- if (self->client == NULL) {
- Py_INCREF(Py_None);
- return Py_None;
- } else {
- return clientwrap_new(self->client);
- }
-}
-
-static PyObject *eventdata_keycode(EventData *self, PyObject *args)
-{
- CHECK_EVENTDATA(self, "keycode");
- if (!PyArg_ParseTuple(args, ":keycode"))
- return NULL;
- switch (self->type) {
- case Key_Press:
- case Key_Release:
- break;
- default:
- PyErr_SetString(PyExc_TypeError,
- "The EventData object is not a Key event");
- return NULL;
- }
- return PyInt_FromLong(self->details.key->keycode);
-}
-
-static PyObject *eventdata_modifiers(EventData *self, PyObject *args)
-{
- CHECK_EVENTDATA(self, "key");
- if (!PyArg_ParseTuple(args, ":key"))
- return NULL;
- switch (self->type) {
- case Key_Press:
- case Key_Release:
- case Pointer_Press:
- case Pointer_Release:
- case Pointer_Motion:
- break;
- default:
- PyErr_SetString(PyExc_TypeError,
- "The EventData object is not a Key or Pointer event");
- return NULL;
- }
- return PyInt_FromLong(self->details.key->modifiers);
-}
-
-static PyObject *eventdata_keyName(EventData *self, PyObject *args)
-{
- GList *it;
- PyObject *tuple;
- int i;
-
- CHECK_EVENTDATA(self, "keyName");
- if (!PyArg_ParseTuple(args, ":keyName"))
- return NULL;
- switch (self->type) {
- case Key_Press:
- case Key_Release:
- break;
- default:
- PyErr_SetString(PyExc_TypeError,
- "The EventData object is not a Key event");
- return NULL;
- }
-
- if (self->details.key->keylist != NULL) {
- tuple = PyTuple_New(g_list_length(self->details.key->keylist));
- for (i = 0, it = self->details.key->keylist; it != NULL;
- it = it->next, ++i)
- PyTuple_SET_ITEM(tuple, i, PyString_FromString(it->data));
- return tuple;
- } else {
- GString *str = g_string_sized_new(0);
- KeySym sym;
-
- if (self->details.key->modifiers & ControlMask)
- g_string_append(str, "C-");
- if (self->details.key->modifiers & ShiftMask)
- g_string_append(str, "S-");
- if (self->details.key->modifiers & Mod1Mask)
- g_string_append(str, "Mod1-");
- if (self->details.key->modifiers & Mod2Mask)
- g_string_append(str, "Mod2-");
- if (self->details.key->modifiers & Mod3Mask)
- g_string_append(str, "Mod3-");
- if (self->details.key->modifiers & Mod4Mask)
- g_string_append(str, "Mod4-");
- if (self->details.key->modifiers & Mod5Mask)
- g_string_append(str, "Mod5-");
-
- sym = XKeycodeToKeysym(ob_display, self->details.key->keycode, 0);
- if (sym == NoSymbol)
- g_string_append(str, "NoSymbol");
- else {
- char *name = XKeysymToString(sym);
- if (name == NULL)
- name = "Undefined";
- g_string_append(str, name);
- }
-
- tuple = PyTuple_New(1);
- PyTuple_SET_ITEM(tuple, 0, PyString_FromString(str->str));
- g_string_free(str, TRUE);
-
- return tuple;
- }
-}
-
-static PyObject *eventdata_button(EventData *self, PyObject *args)
-{
- CHECK_EVENTDATA(self, "button");
- if (!PyArg_ParseTuple(args, ":button"))
- return NULL;
- switch (self->type) {
- case Pointer_Press:
- case Pointer_Release:
- case Pointer_Motion:
- break;
- default:
- PyErr_SetString(PyExc_TypeError,
- "The EventData object is not a Pointer event");
- return NULL;
- }
- return PyInt_FromLong(self->details.pointer->button);
-}
-
-static PyObject *eventdata_buttonName(EventData *self, PyObject *args)
-{
- CHECK_EVENTDATA(self, "buttonName");
- if (!PyArg_ParseTuple(args, ":buttonName"))
- return NULL;
- switch (self->type) {
- case Pointer_Press:
- case Pointer_Release:
- case Pointer_Motion:
- break;
- default:
- PyErr_SetString(PyExc_TypeError,
- "The EventData object is not a Pointer event");
- return NULL;
- }
-
- if (self->details.pointer->name != NULL) {
- return PyString_FromString(self->details.pointer->name);
- } else {
- PyObject *pystr;
- GString *str = g_string_sized_new(0);
-
- if (self->details.pointer->modifiers & ControlMask)
- g_string_append(str, "C-");
- if (self->details.pointer->modifiers & ShiftMask)
- g_string_append(str, "S-");
- if (self->details.pointer->modifiers & Mod1Mask)
- g_string_append(str, "Mod1-");
- if (self->details.pointer->modifiers & Mod2Mask)
- g_string_append(str, "Mod2-");
- if (self->details.pointer->modifiers & Mod3Mask)
- g_string_append(str, "Mod3-");
- if (self->details.pointer->modifiers & Mod4Mask)
- g_string_append(str, "Mod4-");
- if (self->details.pointer->modifiers & Mod5Mask)
- g_string_append(str, "Mod5-");
-
- g_string_append_printf(str, "%d", self->details.pointer->button);
-
- pystr = PyString_FromString(str->str);
-
- g_string_free(str, TRUE);
-
- return pystr;
- }
-}
-
-static PyObject *eventdata_position(EventData *self, PyObject *args)
-{
- PyObject *tuple;
-
- CHECK_EVENTDATA(self, "position");
- if (!PyArg_ParseTuple(args, ":position"))
- return NULL;
- switch (self->type) {
- case Pointer_Press:
- case Pointer_Release:
- case Pointer_Motion:
- break;
- default:
- PyErr_SetString(PyExc_TypeError,
- "The EventData object is not a Pointer event");
- return NULL;
- }
- tuple = PyTuple_New(2);
- PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(self->details.pointer->xroot));
- PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(self->details.pointer->yroot));
- return tuple;
-}
-
-static PyMethodDef EventDataAttributeMethods[] = {
- {"type", (PyCFunction)eventdata_type, METH_VARARGS,
- "data.type() -- Return the event type"},
- {"context", (PyCFunction)eventdata_context, METH_VARARGS,
- "data.context() -- Return the context for the event. If it is "
- "\"client\", then data.client() can be used to find out the "
- "client."},
- {"client", (PyCFunction)eventdata_client, METH_VARARGS,
- "data.client() -- Return the client for the event. This may be None if "
- "there is no client, even if data.context() gives Context_Client."},
- {"time", (PyCFunction)eventdata_time, METH_VARARGS,
- "data.time() -- Return the time at which the last X event occured with "
- "a timestamp. Should be the time at which this event, or the event that "
- "caused this event to occur happened."},
- {"modifiers", (PyCFunction)eventdata_modifiers, METH_VARARGS,
- "data.modifiers() -- Return the modifier keymask that was pressed "
- "when the event occured. A bitmask of ShiftMask, LockMask, ControlMask, "
- "Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, and Mod5Mask. Cannot be used "
- "when the data.type() is not a Key_* or Pointer_* event type."},
- {"keycode", (PyCFunction)eventdata_keycode, METH_VARARGS,
- "data.keycode() -- Return the keycode for the key which generated the "
- "event. Cannot be used when the data.type() is not a Key_* event type."},
- {"keyName", (PyCFunction)eventdata_keyName, METH_VARARGS,
- "data.keyName() -- Return a tuple of the string names of the key which "
- "generated the event. Cannot be used when the data.type() is not a Key_* "
- "event "
- "type."},
- {"button", (PyCFunction)eventdata_button, METH_VARARGS,
- "data.button() -- Return the pointer button which generated the event. "
- "Cannot be used when the data.type() is not a Pointer_* event type."},
- {"buttonName", (PyCFunction)eventdata_keyName, METH_VARARGS,
- "data.buttonName() -- Return the name of the button which generated the "
- "event. Cannot be used when the data.type() is not a Pointer_* event "
- "type."},
- {"position", (PyCFunction)eventdata_position, METH_VARARGS,
- "data.position() -- Returns the current position of the pointer on the "
- "root window when the event was generated. Gives the position in a tuple "
- "with a format of (x, y). Cannot be used when the data.type() is not a "
- "Pointer_* event type."},
- { NULL, NULL, 0, NULL }
-};
-
-static void data_dealloc(EventData *self)
-{
- GList *it;
-
- switch(self->type) {
- case Logical_EnterWindow:
- case Logical_LeaveWindow:
- case Logical_NewWindow:
- case Logical_CloseWindow:
- case Logical_Startup:
- case Logical_Shutdown:
- case Logical_RequestActivate:
- case Logical_WindowShow:
- case Logical_WindowHide:
- case Logical_Focus:
- case Logical_Bell:
- case Logical_UrgentWindow:
- g_free(self->details.logical);
- break;
- case Pointer_Press:
- case Pointer_Release:
- case Pointer_Motion:
- if (self->details.pointer->name != NULL)
- g_free(self->details.pointer->name);
- g_free(self->details.pointer);
- break;
- case Key_Press:
- case Key_Release:
- for (it = self->details.key->keylist; it != NULL; it = it->next)
- g_free(it->data);
- g_list_free(self->details.key->keylist);
- g_free(self->details.key);
- break;
- default:
- g_assert_not_reached();
- }
- PyObject_Del((PyObject*) self);
-}
-
-static PyObject *eventdata_getattr(EventData *self, char *name)
-{
- return Py_FindMethod(EventDataAttributeMethods, (PyObject*)self, name);
-}
-
-static PyTypeObject EventDataType = {
- PyObject_HEAD_INIT(NULL)
- 0,
- "EventData",
- sizeof(EventData),
- 0,
- (destructor) data_dealloc, /*tp_dealloc*/
- 0, /*tp_print*/
- (getattrfunc) eventdata_getattr, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_compare*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash */
-};
-
-
-
-void eventdata_startup()
-{
- EventDataType.ob_type = &PyType_Type;
- PyType_Ready(&EventDataType);
-}
-
-void eventdata_shutdown()
-{
-}
-
-void eventdata_free(EventData *data)
-{
- Py_DECREF(data);
-}
-
-EventData *eventdata_new_logical(EventType type, GQuark context,
- struct Client *client)
-{
- EventData *data;
-
- g_assert(type < Pointer_Press);
-
- data = PyObject_New(EventData, &EventDataType);
- data->type = type;
- data->context = g_quark_to_string(context);
- data->client = client;
- data->details.logical = g_new(LogicalEvent, 1);
- return data;
-}
-
-EventData *eventdata_new_pointer(EventType type, GQuark context,
- struct Client *client, guint modifiers,
- guint button, char *name,
- int xroot, int yroot)
-{
- EventData *data;
-
- g_assert(type >= Pointer_Press && type < Key_Press);
-
- data = PyObject_New(EventData, &EventDataType);
- data->type = type;
- data->context = g_quark_to_string(context);
- data->client = client;
- data->details.pointer = g_new(PointerEvent, 1);
- data->details.pointer->modifiers = modifiers;
- data->details.pointer->button = button;
- data->details.pointer->name = name == NULL ? name : g_strdup(name);
- data->details.pointer->xroot = xroot;
- data->details.pointer->yroot = yroot;
- return data;
-}
-
-EventData *eventdata_new_key(EventType type, GQuark context,
- struct Client *client, guint modifiers,
- guint keycode, GList *keylist)
-{
- EventData *data;
- GList *mykeylist, *it;
-
- g_assert(type >= Key_Press);
-
- data = PyObject_New(EventData, &EventDataType);
- data->type = type;
- data->context = g_quark_to_string(context);
- data->client = client;
- data->details.key = g_new(KeyEvent, 1);
-
- /* make a copy of the keylist.
- If the user were to clear the key bindings, then the keylist given here
- would no longer point at valid memory.*/
- mykeylist = g_list_copy(keylist); /* shallow copy */
- for (it = mykeylist; it != NULL; it = it->next) /* deep copy */
- it->data = g_strdup(it->data);
-
- data->details.key->keylist = mykeylist;
- data->details.key->keycode = keycode;
- data->details.key->modifiers = modifiers;
- return data;
-}
+++ /dev/null
-#ifndef __eventdata_h
-#define __eventdata_h
-
-#include "obexport.h"
-#include <Python.h>
-#include <glib.h>
-
-struct Client;
-
-typedef struct {
- int temp:1; /* just a placeholder to kill warnings for now.. */
-} LogicalEvent;
-
-typedef struct {
- /*! The button which generated the event */
- guint button;
- /*! The pointer's x position on the root window when the event occured */
- int xroot;
- /*! The pointer's y position on the root window when the event occured */
- int yroot;
- /*! The modifiers that were pressed when the event occured. A bitmask of:
- ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask,
- Mod4Mask, Mod5Mask */
- guint modifiers;
- /*! The name of the button/modifier combination being pressed,
- eg "Mod1-1" */
- char *name;
-} PointerEvent;
-
-typedef struct {
- /*! The keycode of the key which generated the event */
- guint keycode;
- /*! The modifiers that were pressed when the event occured. A bitmask of:
- ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask,
- Mod4Mask, Mod5Mask */
- guint modifiers;
- /* The list of strings which make up the chain that fired,
- eg ("Mod1-a", "a") */
- GList *keylist;
-} KeyEvent;
-
-/* EventData is a PyObject */
-typedef struct EventData {
- PyObject_HEAD
- /* The type of event which occured */
- EventType type;
- /*! The context in which the event occured, the type of window it occured
- for. */
- const char *context;
- /* The Client on which the event occured, or NULL */
- struct Client *client;
-
- union EventDetails {
- LogicalEvent *logical;
- PointerEvent *pointer;
- KeyEvent *key;
- } details;
-} EventData;
-
-void eventdata_startup();
-void eventdata_shutdown();
-
-EventData *eventdata_new_logical(EventType type, GQuark context,
- struct Client *client);
-EventData *eventdata_new_pointer(EventType type, GQuark context,
- struct Client *client, guint modifiers,
- guint button, char *name,
- int xroot, int yroot);
-EventData *eventdata_new_key(EventType type, GQuark context,
- struct Client *client, guint modifiers,
- guint keycode, GList *keylist);
-void eventdata_free(EventData *data);
-
-#endif
+++ /dev/null
-#include "openbox.h"
-#include "extensions.h"
-
-gboolean extensions_xkb = FALSE;
-int extensions_xkb_event_basep;
-gboolean extensions_shape = FALSE;
-int extensions_shape_event_basep;
-gboolean extensions_xinerama = FALSE;
-int extensions_xinerama_event_basep;
-
-
-void extensions_query_all()
-{
- int junk;
- (void)junk;
-
-#ifdef XKB
- extensions_xkb =
- XkbQueryExtension(ob_display, &junk, &extensions_xkb_event_basep,
- &junk, NULL, NULL);
-#endif
-
-#ifdef SHAPE
- extensions_shape =
- XShapeQueryExtension(ob_display, &extensions_shape_event_basep,
- &junk);
-#endif
-
-#ifdef XINERAMA
- extensions_xinerama =
- XineramaQueryExtension(ob_display, &extensions_xinerama_event_basep,
- &junk);
-#endif
-}
+++ /dev/null
-#ifndef __extensions_h
-#define __extensions_h
-
-#include <X11/Xlib.h>
-#ifdef XKB
-#include <X11/XKBlib.h>
-#endif
-#ifdef SHAPE
-#include <X11/extensions/shape.h>
-#endif
-#ifdef XINERAMA
-#include <X11/extensions/Xinerama.h>
-#endif
-#include <glib.h>
-
-/*! Does the display have the XKB extension? */
-extern gboolean extensions_xkb;
-/*! Base for events for the XKB extension */
-extern int extensions_xkb_event_basep;
-
-/*! Does the display have the Shape extension? */
-extern gboolean extensions_shape;
-/*! Base for events for the Shape extension */
-extern int extensions_shape_event_basep;
-
-/*! Does the display have the Xinerama extension? */
-extern gboolean extensions_xinerama;
-/*! Base for events for the Xinerama extension */
-extern int extensions_xinerama_event_basep;
-
-void extensions_query_all();
-
-#endif
+++ /dev/null
-#include "openbox.h"
-#include "client.h"
-#include "screen.h"
-#include "prop.h"
-#include "hooks.h"
-#include <X11/Xlib.h>
-
-Client *focus_client = NULL;
-
-Window focus_backup = None;
-
-void focus_set_client(Client *client);
-
-void focus_startup()
-{
- /* create the window which gets focus when no clients get it. Have to
- make it override-redirect so we don't try manage it, since it is
- mapped. */
- XSetWindowAttributes attrib;
-
- attrib.override_redirect = TRUE;
- focus_backup = XCreateWindow(ob_display, ob_root,
- -100, -100, 1, 1, 0, 0, InputOnly,
- CopyFromParent, CWOverrideRedirect, &attrib);
- XMapRaised(ob_display, focus_backup);
-
- /* start with nothing focused */
- focus_set_client(NULL);
-}
-
-void focus_set_client(Client *client)
-{
- Window active;
-
- /* sometimes this is called with the already-focused window, this is
- important for the python scripts to work (eg, c = 0 twice). don't just
- return if _focused_client == c */
-
- /* uninstall the old colormap, and install the new one */
- screen_install_colormap(focus_client, FALSE);
- screen_install_colormap(client, TRUE);
-
-
- if (client == NULL) {
- /* when nothing will be focused, send focus to the backup target */
- XSetInputFocus(ob_display, focus_backup, RevertToNone, CurrentTime);
- }
-
- focus_client = client;
-
- /* set the NET_ACTIVE_WINDOW hint */
- active = client ? client->window : None;
- PROP_SET32(ob_root, net_active_window, window, active);
-
- LOGICALHOOK(Focus, g_quark_try_string("client"), client);
-}
+++ /dev/null
-#ifndef __focus_h
-#define __focus_h
-
-#include <X11/Xlib.h>
-
-struct Client;
-
-/*! The window which gets focus when nothing else will be focused */
-extern Window focus_backup;
-
-/*! The client which is currently focused */
-extern struct Client *focus_client;
-
-void focus_startup();
-
-/*! Specify which client is currently focused, this doesn't actually
- send focus anywhere, its called by the Focus event handlers */
-void focus_set_client(struct Client *client);
-
-#endif
+++ /dev/null
-#include "openbox.h"
-#include "frame.h"
-#include "extensions.h"
-#include "hooks.h"
-
-#define PLATE_EVENTMASK (SubstructureRedirectMask | ButtonPressMask)
-#define FRAME_EVENTMASK (EnterWindowMask | LeaveWindowMask)
-
-static Window createWindow(Window parent, unsigned long mask,
- XSetWindowAttributes *attrib)
-{
- /* XXX DONT USE THE DEFAULT SHIT */
- return XCreateWindow(ob_display, parent, 0, 0, 1, 1, 0,
- DefaultDepth(ob_display, ob_screen), InputOutput,
- DefaultVisual(ob_display, ob_screen),
- mask, attrib);
-
-}
-
-Frame *frame_new(Client *client)
-{
- XSetWindowAttributes attrib;
- unsigned long mask;
- Frame *self;
-
- self = g_new(Frame, 1);
-
- self->client = client;
- self->visible = FALSE;
-
- /* create all of the decor windows */
- mask = CWOverrideRedirect | CWEventMask;
- attrib.event_mask = FRAME_EVENTMASK;
- attrib.override_redirect = TRUE;
- self->window = createWindow(ob_root, mask, &attrib);
-
- mask = 0;
- self->plate = createWindow(self->window, mask, &attrib);
- mask = CWEventMask;
- attrib.event_mask = (ButtonPressMask | ButtonReleaseMask |
- ButtonMotionMask | ExposureMask);
- self->title = createWindow(self->window, mask, &attrib);
- self->label = createWindow(self->title, mask, &attrib);
- self->max = createWindow(self->title, mask, &attrib);
- self->close = createWindow(self->title, mask, &attrib);
- self->desk = createWindow(self->title, mask, &attrib);
- self->icon = createWindow(self->title, mask, &attrib);
- self->iconify = createWindow(self->title, mask, &attrib);
- self->handle = createWindow(self->window, mask, &attrib);
- mask |= CWCursor;
- attrib.cursor = ob_cursors.ll_angle;
- self->lgrip = createWindow(self->handle, mask, &attrib);
- attrib.cursor = ob_cursors.lr_angle;
- self->rgrip = createWindow(self->handle, mask, &attrib);
-
- /* the other stuff is shown based on decor settings */
- XMapWindow(ob_display, self->plate);
- XMapWindow(ob_display, self->lgrip);
- XMapWindow(ob_display, self->rgrip);
- XMapWindow(ob_display, self->label);
-
-
- /* XXX TEMPORARY OF COURSE!@&*(@! */
-
- XSetWindowBackground(ob_display, self->title, 0x3333aa);
- XSetWindowBackground(ob_display, self->handle, 0x3333aa);
- XSetWindowBackground(ob_display, self->lgrip, 0x2233aa);
- XSetWindowBackground(ob_display, self->rgrip, 0x2233aa);
-
- XSetWindowBorder(ob_display, self->window, 0);
- XSetWindowBorder(ob_display, self->label, 0);
- XSetWindowBorder(ob_display, self->rgrip, 0);
- XSetWindowBorder(ob_display, self->lgrip, 0);
- XSetWindowBorder(ob_display, self->plate, 0x771122);
-
- /* XXX /TEMPORARY OF COURSE!@&*(@! */
-
- /* set all the windows for the frame in the client_map */
- g_hash_table_insert(client_map, (gpointer)self->window, self->client);
- g_hash_table_insert(client_map, (gpointer)self->plate, self->client);
- g_hash_table_insert(client_map, (gpointer)self->title, self->client);
- g_hash_table_insert(client_map, (gpointer)self->label, self->client);
- g_hash_table_insert(client_map, (gpointer)self->max, self->client);
- g_hash_table_insert(client_map, (gpointer)self->close, self->client);
- g_hash_table_insert(client_map, (gpointer)self->desk, self->client);
- g_hash_table_insert(client_map, (gpointer)self->icon, self->client);
- g_hash_table_insert(client_map, (gpointer)self->iconify, self->client);
- g_hash_table_insert(client_map, (gpointer)self->handle, self->client);
- g_hash_table_insert(client_map, (gpointer)self->lgrip, self->client);
- g_hash_table_insert(client_map, (gpointer)self->rgrip, self->client);
-
- return self;
-}
-
-void frame_free(Frame *self)
-{
- /* remove all the windows for the frame from the client_map */
- g_hash_table_remove(client_map, (gpointer)self->window);
- g_hash_table_remove(client_map, (gpointer)self->plate);
- g_hash_table_remove(client_map, (gpointer)self->title);
- g_hash_table_remove(client_map, (gpointer)self->label);
- g_hash_table_remove(client_map, (gpointer)self->max);
- g_hash_table_remove(client_map, (gpointer)self->close);
- g_hash_table_remove(client_map, (gpointer)self->desk);
- g_hash_table_remove(client_map, (gpointer)self->icon);
- g_hash_table_remove(client_map, (gpointer)self->iconify);
- g_hash_table_remove(client_map, (gpointer)self->handle);
- g_hash_table_remove(client_map, (gpointer)self->lgrip);
- g_hash_table_remove(client_map, (gpointer)self->rgrip);
-
- XDestroyWindow(ob_display, self->window);
-
- g_free(self);
-}
-
-void frame_grab_client(Frame *self)
-{
- /* reparent the client to the frame */
- XReparentWindow(ob_display, self->client->window, self->plate, 0, 0);
- /*
- When reparenting the client window, it is usually not mapped yet, since
- this occurs from a MapRequest. However, in the case where Openbox is
- starting up, the window is already mapped, so we'll see unmap events for
- it. There are 2 unmap events generated that we see, one with the 'event'
- member set the root window, and one set to the client, but both get
- handled and need to be ignored.
- */
- if (ob_state == State_Starting)
- self->client->ignore_unmaps += 2;
-
- /* select the event mask on the client's parent (to receive config/map
- req's) the ButtonPress is to catch clicks on the client border */
- XSelectInput(ob_display, self->plate, PLATE_EVENTMASK);
-
- /* map the client so it maps when the frame does */
- XMapWindow(ob_display, self->client->window);
-
- frame_adjust_size(self);
- frame_adjust_position(self);
-}
-
-void frame_release_client(Frame *self)
-{
- XEvent ev;
-
- /* check if the app has already reparented its window away */
- if (XCheckTypedWindowEvent(ob_display, self->client->window,
- ReparentNotify, &ev)) {
- XPutBackEvent(ob_display, &ev);
- /* re-map the window since the unmanaging process unmaps it */
- XMapWindow(ob_display, self->client->window);
- } else {
- /* according to the ICCCM - if the client doesn't reparent itself,
- then we will reparent the window to root for them */
- XReparentWindow(ob_display, self->client->window, ob_root,
- self->client->area.x, self->client->area.y);
- }
-}
-
-void frame_show(Frame *self)
-{
- if (!self->visible) {
- self->visible = TRUE;
- XMapWindow(ob_display, self->window);
- LOGICALHOOK(WindowShow, g_quark_try_string("client"), self->client);
- }
-}
-
-void frame_hide(Frame *self)
-{
- if (self->visible) {
- self->visible = FALSE;
- self->client->ignore_unmaps++;
- XUnmapWindow(ob_display, self->window);
- LOGICALHOOK(WindowHide, g_quark_try_string("client"), self->client);
- }
-}
-
-void frame_adjust_size(Frame *self)
-{
- self->decorations = self->client->decorations;
-
- /* XXX set shit from the style */
- self->geom.font_height = 10;
- self->geom.bevel = 1;
- self->geom.button_size = self->geom.font_height - 2;
- self->geom.handle_height = 2;
- self->geom.grip_width = self->geom.button_size * 2;
- XResizeWindow(ob_display, self->lgrip, self->geom.grip_width,
- self->geom.handle_height);
- XResizeWindow(ob_display, self->rgrip, self->geom.grip_width,
- self->geom.handle_height);
-
-
-
-
- if (self->decorations & Decor_Border) {
- self->geom.bwidth = 1;/*XXX style->frameBorderWidth(); */
- self->geom.cbwidth = 1; /*XXX style->clientBorderWidth(); */
- } else {
- self->geom.bwidth = self->geom.cbwidth = 0;
- }
- STRUT_SET(self->innersize, self->geom.cbwidth, self->geom.cbwidth,
- self->geom.cbwidth, self->geom.cbwidth);
- self->geom.width = self->client->area.width + self->geom.cbwidth * 2;
- g_assert(self->geom.width > 0);
-
- /* set border widths */
- XSetWindowBorderWidth(ob_display, self->plate, self->geom.cbwidth);
- XSetWindowBorderWidth(ob_display, self->window, self->geom.bwidth);
- XSetWindowBorderWidth(ob_display, self->title, self->geom.bwidth);
- XSetWindowBorderWidth(ob_display, self->handle, self->geom.bwidth);
- XSetWindowBorderWidth(ob_display, self->lgrip, self->geom.bwidth);
- XSetWindowBorderWidth(ob_display, self->rgrip, self->geom.bwidth);
-
- /* position/size and map/unmap all the windows */
-
- if (self->decorations & Decor_Titlebar) {
- self->geom.title_height = self->geom.font_height +
- self->geom.bevel * 2;
- XMoveResizeWindow(ob_display, self->title,
- -self->geom.bwidth, -self->geom.bwidth,
- self->geom.width, self->geom.title_height);
- self->innersize.top += self->geom.title_height + self->geom.bwidth;
- XMapWindow(ob_display, self->title);
-
- /* layout the title bar elements */
- /*XXX layoutTitle(); */
- } else {
- XUnmapWindow(ob_display, self->title);
- /* make all the titlebar stuff not render */
- self->decorations &= ~(Decor_Icon | Decor_Iconify |
- Decor_Maximize | Decor_Close |
- Decor_AllDesktops);
- }
-
- if (self->decorations & Decor_Handle) {
- self->geom.handle_y = self->innersize.top +
- self->client->area.height + self->geom.cbwidth;
- XMoveResizeWindow(ob_display, self->handle,
- -self->geom.bwidth, self->geom.handle_y,
- self->geom.width, self->geom.handle_height);
- XMoveWindow(ob_display, self->lgrip,
- -self->geom.bwidth, -self->geom.bwidth);
- XMoveWindow(ob_display, self->rgrip,
- -self->geom.bwidth + self->geom.width -
- self->geom.grip_width, -self->geom.bwidth);
- self->innersize.bottom += self->geom.handle_height +
- self->geom.bwidth;
- XMapWindow(ob_display, self->handle);
- } else
- XUnmapWindow(ob_display, self->handle);
-
- XResizeWindow(ob_display, self->window, self->geom.width,
- (self->client->shaded ? self->geom.title_height :
- self->innersize.top + self->innersize.bottom +
- self->client->area.height));
-
- /* do this in two steps because clients whose gravity is set to
- 'Static' don't end up getting moved at all with an XMoveResizeWindow */
- XMoveWindow(ob_display, self->plate,
- self->innersize.left - self->geom.cbwidth,
- self->innersize.top - self->geom.cbwidth);
- XResizeWindow(ob_display, self->plate, self->client->area.width,
- self->client->area.height);
-
- STRUT_SET(self->size,
- self->innersize.left + self->geom.bwidth,
- self->innersize.right + self->geom.bwidth,
- self->innersize.top + self->geom.bwidth,
- self->innersize.bottom + self->geom.bwidth);
-
- RECT_SET_SIZE(self->area,
- self->client->area.width +
- self->size.left + self->size.right,
- self->client->area.height +
- self->size.top + self->size.bottom);
-
- /*
- // render all the elements
- int screen = _client->screen();
- bool focus = _client->focused();
- if (_decorations & Client::Decor_Titlebar) {
- render(screen, otk::Size(geom.width, geom.title_height()), _title,
- &_title_sur, *(focus ? style->titlebarFocusBackground() :
- style->titlebarUnfocusBackground()), false);
-
- renderLabel();
- renderMax();
- renderDesk();
- renderIconify();
- renderIcon();
- renderClose();
- }
-
- if (_decorations & Client::Decor_Handle) {
- render(screen, otk::Size(geom.width, geom.handle_height), _handle,
- &_handle_sur, *(focus ? style->handleFocusBackground() :
- style->handleUnfocusBackground()));
- render(screen, otk::Size(geom.grip_width(), geom.handle_height), _lgrip,
- &_grip_sur, *(focus ? style->gripFocusBackground() :
- style->gripUnfocusBackground()));
- if ((focus ? style->gripFocusBackground() :
- style->gripUnfocusBackground())->parentRelative())
- XSetWindowBackgroundPixmap(**otk::display, _rgrip, ParentRelative);
- else {
- XSetWindowBackgroundPixmap(**otk::display, _rgrip, _grip_sur->pixmap());
- }
- XClearWindow(**otk::display, _rgrip);
- }
-
- XSetWindowBorder(**otk::display, _plate,
- focus ? style->clientBorderFocusColor()->pixel() :
- style->clientBorderUnfocusColor()->pixel());
-
- */
-
- frame_adjust_shape(self);
-}
-
-void frame_adjust_position(Frame *self)
-{
- self->area.x = self->client->area.x;
- self->area.y = self->client->area.y;
- frame_client_gravity(self, &self->area.x, &self->area.y);
- XMoveWindow(ob_display, self->window, self->area.x, self->area.y);
-}
-
-void frame_adjust_shape(Frame *self)
-{
-#ifdef SHAPE
- int num;
- XRectangle xrect[2];
-
- if (!self->client->shaped) {
- /* clear the shape on the frame window */
- XShapeCombineMask(ob_display, self->window, ShapeBounding,
- self->innersize.left,
- self->innersize.top,
- None, ShapeSet);
- } else {
- /* make the frame's shape match the clients */
- XShapeCombineShape(ob_display, self->window, ShapeBounding,
- self->innersize.left,
- self->innersize.top,
- self->client->window, ShapeBounding, ShapeSet);
-
- num = 0;
- if (self->decorations & Decor_Titlebar) {
- xrect[0].x = -self->geom.bevel;
- xrect[0].y = -self->geom.bevel;
- xrect[0].width = self->geom.width + self->geom.bwidth * 2;
- xrect[0].height = self->geom.title_height +
- self->geom.bwidth * 2;
- ++num;
- }
-
- if (self->decorations & Decor_Handle) {
- xrect[1].x = -self->geom.bevel;
- xrect[1].y = self->geom.handle_y;
- xrect[1].width = self->geom.width + self->geom.bwidth * 2;
- xrect[1].height = self->geom.handle_height +
- self->geom.bwidth * 2;
- ++num;
- }
-
- XShapeCombineRectangles(ob_display, self->window,
- ShapeBounding, 0, 0, xrect, num,
- ShapeUnion, Unsorted);
- }
-#endif
-}
-
-void frame_client_gravity(Frame *self, int *x, int *y)
-{
- /* horizontal */
- switch (self->client->gravity) {
- default:
- case NorthWestGravity:
- case SouthWestGravity:
- case WestGravity:
- break;
-
- case NorthGravity:
- case SouthGravity:
- case CenterGravity:
- *x -= (self->size.left + self->size.right) / 2;
- break;
-
- case NorthEastGravity:
- case SouthEastGravity:
- case EastGravity:
- *x -= self->size.left + self->size.right;
- break;
-
- case ForgetGravity:
- case StaticGravity:
- *x -= self->size.left;
- break;
- }
-
- /* vertical */
- switch (self->client->gravity) {
- default:
- case NorthWestGravity:
- case NorthEastGravity:
- case NorthGravity:
- break;
-
- case CenterGravity:
- case EastGravity:
- case WestGravity:
- *y -= (self->size.top + self->size.bottom) / 2;
- break;
-
- case SouthWestGravity:
- case SouthEastGravity:
- case SouthGravity:
- *y -= self->size.top + self->size.bottom;
- break;
-
- case ForgetGravity:
- case StaticGravity:
- *y -= self->size.top;
- break;
- }
-}
-
-void frame_frame_gravity(Frame *self, int *x, int *y)
-{
- /* horizontal */
- switch (self->client->gravity) {
- default:
- case NorthWestGravity:
- case WestGravity:
- case SouthWestGravity:
- break;
- case NorthGravity:
- case CenterGravity:
- case SouthGravity:
- *x += (self->size.left + self->size.right) / 2;
- break;
- case NorthEastGravity:
- case EastGravity:
- case SouthEastGravity:
- *x += self->size.left + self->size.right;
- break;
- case StaticGravity:
- case ForgetGravity:
- x += self->size.left;
- break;
- }
-
- /* vertical */
- switch (self->client->gravity) {
- default:
- case NorthWestGravity:
- case WestGravity:
- case SouthWestGravity:
- break;
- case NorthGravity:
- case CenterGravity:
- case SouthGravity:
- *y += (self->size.top + self->size.bottom) / 2;
- break;
- case NorthEastGravity:
- case EastGravity:
- case SouthEastGravity:
- *y += self->size.top + self->size.bottom;
- break;
- case StaticGravity:
- case ForgetGravity:
- *y += self->size.top;
- break;
- }
-}
-
-void frame_adjust_state(Frame *self)
-{
- /* XXX do shit.. buttons? */
-}
-
-void frame_adjust_focus(Frame *self)
-{
- /* XXX optimizations later... */
- frame_adjust_size(self);
-}
-
-void frame_adjust_title(Frame *self)
-{
- /* XXX optimizations later... */
- frame_adjust_size(self);
-}
-
-void frame_adjust_icon(Frame *self)
-{
- /* XXX render icon */
-}
-
-GQuark frame_get_context(Client *client, Window win)
-{
- Frame *self;
-
- if (win == ob_root) return g_quark_try_string("root");
- if (client == NULL) return g_quark_try_string("none");
- if (win == client->window) return g_quark_try_string("client");
-
- self = client->frame;
- if (win == self->window) return g_quark_try_string("frame");
- if (win == self->plate) return g_quark_try_string("frame");
- if (win == self->title) return g_quark_try_string("titlebar");
- if (win == self->label) return g_quark_try_string("titlebar");
- if (win == self->handle) return g_quark_try_string("handle");
- if (win == self->lgrip) return g_quark_try_string("blcorner");
- if (win == self->rgrip) return g_quark_try_string("brcorner");
-
- return g_quark_try_string("none");
-}
-
-void frame_startup(void)
-{
- g_quark_from_string("none");
- g_quark_from_string("root");
- g_quark_from_string("client");
- g_quark_from_string("titlebar");
- g_quark_from_string("handle");
- g_quark_from_string("frame");
- g_quark_from_string("blcorner");
- g_quark_from_string("brcorner");
- g_quark_from_string("tlcorner");
- g_quark_from_string("trcorner");
- g_quark_from_string("foo");
-}
+++ /dev/null
-#ifndef __frame_h
-#define __frame_h
-
-#include <X11/Xlib.h>
-#include "geom.h"
-#include "client.h"
-
-/*! Varius geometry settings in the frame decorations */
-typedef struct {
- int width; /* title and handle */
- int font_height;
-/* int title_height() { return font_height + bevel*2; } */
- int title_height;
- int label_width;
-/* int label_height() { return font_height; } */
- int handle_height; /* static, from the style */
- int icon_x; /* x-position of the window icon button */
- int title_x; /* x-position of the window title */
- int iconify_x; /* x-position of the window iconify button */
- int desktop_x; /* x-position of the window all-desktops button */
- int max_x; /* x-position of the window maximize button */
- int close_x; /* x-position of the window close button */
- int handle_y;
- int button_size; /* static, from the style */
-/* int grip_width() { return button_size * 2; } */
- int grip_width;
- int bevel; /* static, from the style */
- int bwidth; /* frame elements' border width */
- int cbwidth; /* client border width */
-} FrameGeometry;
-
-typedef struct Frame {
- Window window;
- Window plate;
- Window title;
- Window label;
- Window max;
- Window close;
- Window desk;
- Window icon;
- Window iconify;
- Window handle;
- Window lgrip;
- Window rgrip;
-
- Strut size;
- Strut innersize;
- Rect area;
- FrameGeometry geom;
-
- Client *client;
- int decorations;
-
- gboolean visible;
-} Frame;
-
-Frame *frame_new(struct Client *client);
-void frame_free(Frame *self);
-
-void frame_grab_client(Frame *self);
-void frame_release_client(Frame *self);
-
-/*! Update the frame's size to match the client */
-void frame_adjust_size(Frame *self);
-/*! Update the frame's position to match the client */
-void frame_adjust_position(Frame *self);
-/*! Shape the frame window to the client window */
-void frame_adjust_shape(Frame *self);
-/*! Update the frame to match the client's new state (for things like toggle
- buttons, focus, and the title) XXX break this up */
-void frame_adjust_state(Frame *self);
-/*! Update the frame to match the client's focused state */
-void frame_adjust_focus(Frame *self);
-/*! Update the frame to display the client's current title */
-void frame_adjust_title(Frame *self);
-/*! Update the frame to display the client's current icon */
-void frame_adjust_icon(Frame *self);
-
-/*! Applies gravity to the client's position to find where the frame should
- be positioned.
- @return The proper coordinates for the frame, based on the client.
-*/
-void frame_client_gravity(Frame *self, int *x, int *y);
-
-/*! Reversly applies gravity to the frame's position to find where the client
- should be positioned.
- @return The proper coordinates for the client, based on the frame.
-*/
-void frame_frame_gravity(Frame *self, int *x, int *y);
-
-/*! Shows the frame */
-void frame_show(Frame *self);
-/*! Hides the frame */
-void frame_hide(Frame *self);
-
-/*! inits quarks - this will go in engines later */
-void frame_startup(void);
-
-GQuark frame_get_context(Client *client, Window win);
-
-#endif
+++ /dev/null
-#ifndef __geom_h
-#define __geom_h
-
-#ifdef HAVE_ASSERT_H
-# include <assert.h>
-#endif
-
-typedef struct Point {
- int x;
- int y;
-} Point;
-
-#define POINT_SET(pt, nx, ny) {pt.x = nx; pt.y = ny;}
-
-typedef struct Size {
- int width;
- int height;
-} Size;
-
-#define SIZE_SET(sz, w, h) {sz.width = w; sz.height = h;}
-
-typedef struct Rect {
- int x;
- int y;
- int width;
- int height;
-} Rect;
-
-#define RECT_SET_POINT(r, nx, ny) \
- {r.x = ny; r.y = ny;}
-#define RECT_SET_SIZE(r, w, h) \
- {r.width = w; r.height = h;}
-#define RECT_SET(r, nx, ny, w, h) \
- {r.x = nx; r.y = ny; r.width = w; r.height = h;}
-
-#define RECT_EQUAL(r1, r2) (r1.x == r2.x && r1.y == r2.y && \
- r1.width == r2.width && r1.height == r2.height)
-
-typedef struct Strut {
- int left;
- int top;
- int right;
- int bottom;
-} Strut;
-
-#define STRUT_SET(s, l, t, r, b) \
- {s.left = l; s.top = t; s.right = r; s.bottom = b; }
-
-#define STRUT_ADD(s1, s2) \
- {s1.left = MAX(s1.left, s2.left); s1.right = MAX(s1.right, s2.right); \
- s1.top = MAX(s1.top, s2.top); s1.bottom = MAX(s1.bottom, s2.bottom); }
-
-#endif
+++ /dev/null
-/* Convenience header for conditional use of GNU <libintl.h>.
- Copyright (C) 1995-1998, 2000-2002 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU Library General Public License as published
- by the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
- USA. */
-
-#ifndef _LIBGETTEXT_H
-#define _LIBGETTEXT_H 1
-
-
-/* NLS can be disabled through the configure --disable-nls option. */
-#if ENABLE_NLS
-
-/* Get declarations of GNU message catalog functions. */
-# include <libintl.h>
-
-#else
-
-/* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which
- chokes if dcgettext is defined as a macro. So include it now, to make
- later inclusions of <locale.h> a NOP. We don't include <libintl.h>
- as well because people using "gettext.h" will not include <libintl.h>,
- and also including <libintl.h> would fail on SunOS 4, whereas <locale.h>
- is OK. */
-#if defined(__sun)
-# include <locale.h>
-#endif
-
-/* Disabled NLS.
- The casts to 'const char *' serve the purpose of producing warnings
- for invalid uses of the value returned from these functions.
- On pre-ANSI systems without 'const', the config.h file is supposed to
- contain "#define const". */
-# define gettext(Msgid) ((const char *) (Msgid))
-# define dgettext(Domainname, Msgid) ((const char *) (Msgid))
-# define dcgettext(Domainname, Msgid, Category) ((const char *) (Msgid))
-# define ngettext(Msgid1, Msgid2, N) \
- ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
-# define dngettext(Domainname, Msgid1, Msgid2, N) \
- ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
-# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \
- ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
-# define textdomain(Domainname) ((const char *) (Domainname))
-# define bindtextdomain(Domainname, Dirname) ((const char *) (Dirname))
-# define bind_textdomain_codeset(Domainname, Codeset) ((const char *) (Codeset))
-
-#endif
-
-/* A pseudo function call that serves as a marker for the automated
- extraction of messages, but does not call gettext(). The run-time
- translation is done at a different place in the code.
- The argument, String, should be a literal string. Concatenated strings
- and other string expressions won't work.
- The macro's expansion is not parenthesized, so that it is suitable as
- initializer for static 'char[]' or 'const char[]' variables. */
-#define gettext_noop(String) String
-
-/* Custom macro to make life easier */
-#define _(str) gettext(str)
-
-#endif /* _LIBGETTEXT_H */
+++ /dev/null
-#include "hooks.h"
-#include <Python.h>
-#include <glib.h>
-
-/* the 'hooks' module and its dictionary */
-static PyObject *hooks = NULL, *hooksdict = NULL;
-
-/*
- *
- * Define the type 'Hook'
- *
- */
-#define IS_HOOK(v) ((v)->ob_type == &HookType)
-
-staticforward PyTypeObject HookType;
-
-typedef struct {
- PyObject_HEAD
- GSList *funcs;
-} HookObject;
-
-static PyObject *create_Hook(PyObject *self, PyObject *args)
-{
- HookObject *hook;
- char *name;
- int ret;
-
- (void) self;
-
- if (!PyArg_ParseTuple(args, "s:Hook", &name))
- return NULL;
-
- hook = PyObject_New(HookObject, &HookType);
- hook->funcs = NULL;
-
- /* add it to the hooks module */
- ret = PyDict_SetItemString(hooksdict, name, (PyObject*) hook);
- Py_DECREF(hook);
-
- if (ret == -1) {
- char *s = g_strdup_printf(
- "Failed to add the hook '%s' to the 'hooks' module", name);
- PyErr_SetString(PyExc_RuntimeError, s);
- g_free(s);
- return NULL;
- }
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-static void hook_dealloc(HookObject *self)
-{
- GSList *it;
-
- for (it = self->funcs; it != NULL; it = it->next)
- Py_DECREF((PyObject*) it->data);
-
- PyObject_Del((PyObject*) self);
-}
-
-static PyObject *hook_fire(HookObject *self, PyObject *args)
-{
- GSList *it;
-
- if (!IS_HOOK(self)) {
- PyErr_SetString(PyExc_TypeError,
- "descriptor 'fire' requires a 'Hook' object");
- return NULL;
- }
-
- for (it = self->funcs; it != NULL; it = it->next) {
- PyObject *ret = PyObject_CallObject(it->data, args);
- if (ret == NULL)
- return NULL;
- Py_DECREF(ret);
- }
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-static PyObject *hook_add(HookObject *self, PyObject *args)
-{
- PyObject *func;
-
- if (!IS_HOOK(self)) {
- PyErr_SetString(PyExc_TypeError,
- "descriptor 'add' requires a 'Hook' object");
- return NULL;
- }
- if (!PyArg_ParseTuple(args, "O:add", &func))
- return NULL;
- if (!PyCallable_Check(func)) {
- PyErr_SetString(PyExc_TypeError,
- "descriptor 'add' requires a callable argument");
- return NULL;
- }
- self->funcs = g_slist_append(self->funcs, func);
- Py_INCREF(func);
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-static PyObject *hook_remove(HookObject *self, PyObject *args)
-{
- PyObject *func;
- GSList *it;
-
- if (!IS_HOOK(self)) {
- PyErr_SetString(PyExc_TypeError,
- "descriptor 'remove' requires a 'Hook' object");
- return NULL;
- }
- if (!PyArg_ParseTuple(args, "O:remove", &func))
- return NULL;
- if (!PyCallable_Check(func)) {
- PyErr_SetString(PyExc_TypeError,
- "descriptor 'remove' requires a callable argument");
- return NULL;
- }
- it = g_slist_find(self->funcs, func);
- if (it != NULL) {
- self->funcs = g_slist_delete_link(self->funcs, it);
- Py_DECREF(func);
-
- Py_INCREF(Py_None);
- return Py_None;
- }
- PyErr_SetString(PyExc_TypeError,
- "given callable object was not found in Hook");
- return NULL;
-}
-
-static PyObject *hook_count(HookObject *self, PyObject *args)
-{
- if (!IS_HOOK(self)) {
- PyErr_SetString(PyExc_TypeError,
- "descriptor 'fire' requires a 'Hook' object");
- return NULL;
- }
- if (!PyArg_ParseTuple(args, ":count"))
- return NULL;
-
- return PyInt_FromLong(g_slist_length(self->funcs));
-}
-
-static PyTypeObject HookType = {
- PyObject_HEAD_INIT(NULL)
- 0,
- "Hook",
- sizeof(HookObject),
- 0,
- (destructor) hook_dealloc, /*tp_dealloc*/
- 0, /*tp_print*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_compare*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash */
-};
-
-static PyMethodDef HookMethods[] = {
- {"fire", (PyCFunction)hook_fire, METH_VARARGS,
- "hook.fire() -- Fire the added hook functions for the Hook."},
- {"add", (PyCFunction)hook_add, METH_VARARGS,
- "hook.add(func) -- Add a function to the hook." },
- {"remove", (PyCFunction)hook_remove, METH_VARARGS,
- "hook.remove(func) -- Remove a function from the hook." },
- {"count", (PyCFunction)hook_count, METH_VARARGS,
- "hook.count() -- Return the number of functions in the hook." },
-
- { NULL, NULL, 0, NULL }
-};
-
-
-/*
- *
- * Module initialization/finalization
- *
- */
-
-/* the "events" hook */
-static HookObject *events_hook = NULL, *keyboard_hook = NULL,
- *pointer_hook = NULL;
-
-static PyMethodDef HooksMethods[] = {
- {"create", create_Hook, METH_VARARGS,
- "hooks.create('name') -- Add a hook called 'name' to the hooks module."},
-
- { NULL, NULL, 0, NULL }
-};
-
-void hooks_startup()
-{
- int ret;
-
- HookType.ob_type = &PyType_Type;
- HookType.tp_methods = HookMethods;
- PyType_Ready(&HookType);
-
- Py_InitModule("hooks", HooksMethods);
-
- /* get the hooks module/dict */
- hooks = PyImport_ImportModule("hooks"); /* new */
- g_assert(hooks != NULL);
- hooksdict = PyModule_GetDict(hooks); /* borrowed */
- g_assert(hooksdict != NULL);
-
- /* create the "events" hook */
- events_hook = PyObject_New(HookObject, &HookType);
- events_hook->funcs = NULL;
-
- /* add it to the hooks module */
- ret = PyDict_SetItemString(hooksdict, "events", (PyObject*) events_hook);
- g_assert(ret == 0);
-
- /* create the "keyboard" hook */
- keyboard_hook = PyObject_New(HookObject, &HookType);
- keyboard_hook->funcs = NULL;
-
- /* add it to the hooks module */
- ret = PyDict_SetItemString(hooksdict, "keyboard",
- (PyObject*) keyboard_hook);
- g_assert(ret == 0);
-
- /* create the "pointer" hook */
- pointer_hook = PyObject_New(HookObject, &HookType);
- pointer_hook->funcs = NULL;
-
- /* add it to the hooks module */
- ret = PyDict_SetItemString(hooksdict, "pointer", (PyObject*) pointer_hook);
- g_assert(ret == 0);
-}
-
-void hooks_shutdown()
-{
- Py_DECREF(pointer_hook);
- Py_DECREF(keyboard_hook);
- Py_DECREF(events_hook);
- Py_DECREF(hooks);
-}
-
-void hooks_fire(EventData *data)
-{
- PyObject *ret, *args;
-
- g_assert(events_hook != NULL);
-
- args = Py_BuildValue("(O)", data);
- ret = hook_fire(events_hook, args);
- Py_DECREF(args);
- if (ret == NULL)
- PyErr_Print();
-}
-
-void hooks_fire_keyboard(EventData *data)
-{
- PyObject *ret, *args;
-
- g_assert(events_hook != NULL);
-
- args = Py_BuildValue("(O)", data);
- ret = hook_fire(keyboard_hook, args);
- Py_DECREF(args);
- if (ret == NULL)
- PyErr_Print();
-}
-
-void hooks_fire_pointer(EventData *data)
-{
- PyObject *ret, *args;
-
- g_assert(events_hook != NULL);
-
- args = Py_BuildValue("(O)", data);
- ret = hook_fire(pointer_hook, args);
- Py_DECREF(args);
- if (ret == NULL)
- PyErr_Print();
-}
+++ /dev/null
-#ifndef __hooks_h
-#define __hooks_h
-
-#include "eventdata.h"
-
-void hooks_startup();
-void hooks_shutdown();
-
-void hooks_fire(EventData *data);
-
-void hooks_fire_keyboard(EventData *data);
-
-void hooks_fire_pointer(EventData *data);
-
-#define LOGICALHOOK(type, context, client) \
-{ EventData *data = eventdata_new_logical(Logical_##type, \
- context, client); \
- g_assert(data != NULL); \
- hooks_fire(data); \
- eventdata_free(data); \
-}
-
-#endif
+++ /dev/null
-#include "focus.h"
-#include "openbox.h"
-#include "hooks.h"
-#include "kbind.h"
-
-#include <glib.h>
-#ifdef HAVE_STRING_H
-# include <string.h>
-#endif
-
-typedef struct KeyBindingTree {
- guint state;
- guint key;
- GList *keylist;
-
- /* the next binding in the tree at the same level */
- struct KeyBindingTree *next_sibling;
- /* the first child of this binding (next binding in a chained sequence).*/
- struct KeyBindingTree *first_child;
-} KeyBindingTree;
-
-
-static KeyBindingTree *firstnode, *curpos;
-static guint reset_key, reset_state;
-static gboolean grabbed, user_grabbed;
-
-guint kbind_translate_modifier(char *str)
-{
- if (!strcmp("Mod1", str)) return Mod1Mask;
- else if (!strcmp("Mod2", str)) return Mod2Mask;
- else if (!strcmp("Mod3", str)) return Mod3Mask;
- else if (!strcmp("Mod4", str)) return Mod4Mask;
- else if (!strcmp("Mod5", str)) return Mod5Mask;
- else if (!strcmp("C", str)) return ControlMask;
- else if (!strcmp("S", str)) return ShiftMask;
- g_warning("Invalid modifier '%s' in binding.", str);
- return 0;
-}
-
-static gboolean translate(char *str, guint *state, guint *keycode)
-{
- char **parsed;
- char *l;
- int i;
- gboolean ret = FALSE;
- KeySym sym;
-
- parsed = g_strsplit(str, "-", -1);
-
- /* first, find the key (last token) */
- l = NULL;
- for (i = 0; parsed[i] != NULL; ++i)
- l = parsed[i];
- if (l == NULL)
- goto translation_fail;
-
- /* figure out the mod mask */
- *state = 0;
- for (i = 0; parsed[i] != l; ++i) {
- guint m = kbind_translate_modifier(parsed[i]);
- if (!m) goto translation_fail;
- *state |= m;
- }
-
- /* figure out the keycode */
- sym = XStringToKeysym(l);
- if (sym == NoSymbol) {
- g_warning("Invalid key name '%s' in key binding.", l);
- goto translation_fail;
- }
- *keycode = XKeysymToKeycode(ob_display, sym);
- if (!keycode) {
- g_warning("Key '%s' does not exist on the display.", l);
- goto translation_fail;
- }
-
- ret = TRUE;
-
-translation_fail:
- g_strfreev(parsed);
- return ret;
-}
-
-static void destroytree(KeyBindingTree *tree)
-{
- KeyBindingTree *c;
-
- while (tree) {
- destroytree(tree->next_sibling);
- c = tree->first_child;
- if (c == NULL) {
- GList *it;
- for (it = tree->keylist; it != NULL; it = it->next)
- g_free(it->data);
- g_list_free(tree->keylist);
- }
- g_free(tree);
- tree = c;
- }
-}
-
-static KeyBindingTree *buildtree(GList *keylist)
-{
- GList *it;
- KeyBindingTree *ret = NULL, *p;
-
- if (g_list_length(keylist) <= 0)
- return NULL; /* nothing in the list.. */
-
- for (it = g_list_last(keylist); it != NULL; it = it->prev) {
- p = ret;
- ret = g_new(KeyBindingTree, 1);
- ret->next_sibling = NULL;
- if (p == NULL) {
- GList *it;
-
- /* this is the first built node, the bottom node of the tree */
- ret->keylist = g_list_copy(keylist); /* shallow copy */
- for (it = ret->keylist; it != NULL; it = it->next) /* deep copy */
- it->data = g_strdup(it->data);
- }
- ret->first_child = p;
- if (!translate(it->data, &ret->state, &ret->key)) {
- destroytree(ret);
- return NULL;
- }
- }
- return ret;
-}
-
-static void assimilate(KeyBindingTree *node)
-{
- KeyBindingTree *a, *b, *tmp, *last;
-
- if (firstnode == NULL) {
- /* there are no nodes at this level yet */
- firstnode = node;
- } else {
- a = firstnode;
- last = a;
- b = node;
- while (a) {
- last = a;
- if (!(a->state == b->state && a->key == b->key)) {
- a = a->next_sibling;
- } else {
- tmp = b;
- b = b->first_child;
- g_free(tmp);
- a = a->first_child;
- }
- }
- if (!(last->state == b->state && last->key == a->key))
- last->next_sibling = b;
- else {
- last->first_child = b->first_child;
- g_free(b);
- }
- }
-}
-
-KeyBindingTree *find(KeyBindingTree *search, gboolean *conflict)
-{
- KeyBindingTree *a, *b;
-
- *conflict = FALSE;
-
- a = firstnode;
- b = search;
- while (a && b) {
- if (!(a->state == b->state && a->key == b->key)) {
- a = a->next_sibling;
- } else {
- if ((a->first_child == NULL) == (b->first_child == NULL)) {
- if (a->first_child == NULL) {
- /* found it! (return the actual node, not the search's) */
- return a;
- }
- } else {
- *conflict = TRUE;
- return NULL; /* the chain status' don't match (conflict!) */
- }
- b = b->first_child;
- a = a->first_child;
- }
- }
- return NULL; // it just isn't in here
-}
-
-static void grab_keys(gboolean grab)
-{
- if (!grab) {
- XUngrabKey(ob_display, AnyKey, AnyModifier, ob_root);
- } else {
- KeyBindingTree *p = firstnode;
- while (p) {
- XGrabKey(ob_display, p->key, p->state, ob_root, FALSE,
- GrabModeAsync, GrabModeSync);
- p = p->next_sibling;
- }
- }
-}
-
-void reset_chains()
-{
- /* XXX kill timer */
- curpos = NULL;
- if (grabbed) {
- grabbed = FALSE;
- g_message("reset chains. user: %d", user_grabbed);
- if (!user_grabbed)
- XUngrabKeyboard(ob_display, CurrentTime);
- }
-}
-
-void kbind_fire(guint state, guint key, gboolean press)
-{
- EventData *data;
- struct Client *c = focus_client;
- GQuark context = c != NULL ? g_quark_try_string("client")
- : g_quark_try_string("root");
-
- if (user_grabbed) {
- data = eventdata_new_key(press ? Key_Press : Key_Release,
- context, c, state, key, NULL);
- g_assert(data != NULL);
- hooks_fire_keyboard(data);
- eventdata_free(data);
- }
-
- if (key == reset_key && state == reset_state) {
- reset_chains();
- XAllowEvents(ob_display, AsyncKeyboard, CurrentTime);
- } else {
- KeyBindingTree *p;
- if (curpos == NULL)
- p = firstnode;
- else
- p = curpos->first_child;
- while (p) {
- if (p->key == key && p->state == state) {
- if (p->first_child != NULL) { /* part of a chain */
- /* XXX TIMER */
- if (!grabbed && !user_grabbed) {
- /*grab should never fail because we should have a sync
- grab at this point */
- XGrabKeyboard(ob_display, ob_root, 0, GrabModeAsync,
- GrabModeSync, CurrentTime);
- }
- grabbed = TRUE;
- curpos = p;
- XAllowEvents(ob_display, AsyncKeyboard, CurrentTime);
- } else {
- data = eventdata_new_key(press ? Key_Press : Key_Release,
- context, c, state, key,
- p->keylist);
- g_assert(data != NULL);
- hooks_fire(data);
- eventdata_free(data);
-
- XAllowEvents(ob_display, AsyncKeyboard, CurrentTime);
- reset_chains();
- }
- break;
- }
- p = p->next_sibling;
- }
- }
-}
-
-gboolean kbind_add(GList *keylist)
-{
- KeyBindingTree *tree, *t;
- gboolean conflict;
-
- if (!(tree = buildtree(keylist)))
- return FALSE; /* invalid binding requested */
-
- t = find(tree, &conflict);
- if (conflict) {
- /* conflicts with another binding */
- destroytree(tree);
- return FALSE;
- }
-
- if (t != NULL) {
- /* already bound to something */
- destroytree(tree);
- } else {
- /* grab the server here to make sure no key pressed go missed */
- XGrabServer(ob_display);
- XSync(ob_display, FALSE);
-
- grab_keys(FALSE);
-
- /* assimilate this built tree into the main tree */
- assimilate(tree); // assimilation destroys/uses the tree
-
- grab_keys(TRUE);
-
- XUngrabServer(ob_display);
- XFlush(ob_display);
- }
-
- return TRUE;
-}
-
-void kbind_clearall()
-{
- grab_keys(FALSE);
- destroytree(firstnode);
- firstnode = NULL;
- grab_keys(TRUE);
-}
-
-void kbind_startup()
-{
- gboolean b;
-
- curpos = firstnode = NULL;
- grabbed = user_grabbed = FALSE;
-
- b = translate("C-G", &reset_state, &reset_key);
- g_assert(b);
-}
-
-void kbind_shutdown()
-{
- if (grabbed || user_grabbed) {
- grabbed = FALSE;
- kbind_grab_keyboard(FALSE);
- }
- grab_keys(FALSE);
- destroytree(firstnode);
- firstnode = NULL;
-}
-
-gboolean kbind_grab_keyboard(gboolean grab)
-{
- gboolean ret = TRUE;
-
- if (!grab)
- g_message("grab_keyboard(false). grabbed: %d", grabbed);
-
- user_grabbed = grab;
- if (!grabbed) {
- if (grab)
- ret = XGrabKeyboard(ob_display, ob_root, 0, GrabModeAsync,
- GrabModeAsync, CurrentTime) == GrabSuccess;
- else
- XUngrabKeyboard(ob_display, CurrentTime);
- }
- return ret;
-}
+++ /dev/null
-#ifndef __kbind_h
-#define __kbind_h
-
-#include <glib.h>
-
-void kbind_startup();
-void kbind_shutdown();
-
-/*! Adds a new key binding
- A binding will fail to be added if the binding already exists (as part of
- a chain or not), or if any of the strings in the keylist are invalid.
- @return TRUE if the binding could be added; FALSE if it could not.
-*/
-gboolean kbind_add(GList *keylist);
-void kbind_clearall();
-
-guint kbind_translate_modifier(char *str);
-
-void kbind_fire(guint state, guint key, gboolean press);
-
-gboolean kbind_grab_keyboard(gboolean grab);
-
-#endif
+++ /dev/null
-#include "mbind.h"
-#include "kbind.h"
-#include "frame.h"
-#include "openbox.h"
-#include "eventdata.h"
-#include "hooks.h"
-
-#include <glib.h>
-#ifdef HAVE_STDLIB_H
-# include <stdlib.h>
-#endif
-
-/* GData of GSList*'s of PointerBinding*'s. */
-static GData *bound_contexts;
-
-static gboolean grabbed;
-
-struct mbind_foreach_grab_temp {
- Client *client;
- gboolean grab;
-};
-
-typedef struct {
- guint state;
- guint button;
- char *name;
-} PointerBinding;
-
-static gboolean translate(char *str, guint *state, guint *button)
-{
- char **parsed;
- char *l;
- int i;
- gboolean ret = FALSE;
-
- parsed = g_strsplit(str, "-", -1);
-
- /* first, find the button (last token) */
- l = NULL;
- for (i = 0; parsed[i] != NULL; ++i)
- l = parsed[i];
- if (l == NULL)
- goto translation_fail;
-
- /* figure out the mod mask */
- *state = 0;
- for (i = 0; parsed[i] != l; ++i) {
- guint m = kbind_translate_modifier(parsed[i]);
- if (!m) goto translation_fail;
- *state |= m;
- }
-
- /* figure out the button */
- *button = atoi(l);
- if (!*button) {
- g_warning("Invalid button '%s' in pointer binding.", l);
- goto translation_fail;
- }
-
- ret = TRUE;
-
-translation_fail:
- g_strfreev(parsed);
- return ret;
-}
-
-void grab_button(Client *client, guint state, guint button, GQuark context,
- gboolean grab)
-{
- Window win;
- int mode = GrabModeAsync;
- unsigned int mask;
-
- if (context == g_quark_try_string("frame")) {
- win = client->frame->window;
- mask = ButtonPressMask | ButtonMotionMask | ButtonReleaseMask;
- } else if (context == g_quark_try_string("client")) {
- win = client->frame->plate;
- mode = GrabModeSync; /* this is handled in mbind_fire */
- mask = ButtonPressMask; /* can't catch more than this with Sync mode
- the release event is manufactured in
- mbind_fire */
- } else return;
-
- if (grab)
- XGrabButton(ob_display, button, state, win, FALSE, mask, mode,
- GrabModeAsync, None, None);
- else
- XUngrabButton(ob_display, button, state, win);
-}
-
-static void mbind_foreach_grab(GQuark key, gpointer data, gpointer user_data)
-{
- struct mbind_foreach_grab_temp *d = user_data;
- PointerBinding *b = ((GSList *)data)->data;
- if (b != NULL)
- grab_button(d->client, b->state, b->button, key, d->grab);
-}
-
-void mbind_grab_all(Client *client, gboolean grab)
-{
- struct mbind_foreach_grab_temp bt;
- bt.client = client;
- bt.grab = grab;
- g_datalist_foreach(&bound_contexts, mbind_foreach_grab, &bt);
-}
-
-void grab_all_clients(gboolean grab)
-{
- GSList *it;
-
- for (it = client_list; it != NULL; it = it->next)
- mbind_grab_all(it->data, grab);
-}
-
-void mbind_startup()
-{
- grabbed = FALSE;
- g_datalist_init(&bound_contexts);
-}
-
-void mbind_shutdown()
-{
- if (grabbed)
- mbind_grab_pointer(FALSE);
- mbind_clearall();
- g_datalist_clear(&bound_contexts);
-}
-
-gboolean mbind_add(char *name, GQuark context)
-{
- guint state, button;
- PointerBinding *b;
- GSList *it;
-
- if (!translate(name, &state, &button))
- return FALSE;
-
- for (it = g_datalist_id_get_data(&bound_contexts, context);
- it != NULL; it = it->next){
- b = it->data;
- if (b->state == state && b->button == button)
- return TRUE; /* already bound */
- }
-
- grab_all_clients(FALSE);
-
- /* add the binding */
- b = g_new(PointerBinding, 1);
- b->state = state;
- b->button = button;
- b->name = g_strdup(name);
- g_datalist_id_set_data(&bound_contexts, context,
- g_slist_append(g_datalist_id_get_data(&bound_contexts, context), b));
- grab_all_clients(TRUE);
-
- return TRUE;
-}
-
-static void mbind_foreach_clear(GQuark key, gpointer data, gpointer user_data)
-{
- GSList *it;
- user_data = user_data;
- for (it = data; it != NULL; it = it->next) {
- PointerBinding *b = it->data;
- g_free(b->name);
- g_free(b);
- }
- g_slist_free(data);
-}
-void mbind_clearall()
-{
- grab_all_clients(FALSE);
- g_datalist_foreach(&bound_contexts, mbind_foreach_clear, NULL);
-}
-
-void mbind_fire(guint state, guint button, GQuark context, EventType type,
- Client *client, int xroot, int yroot)
-{
- GSList *it;
-
- if (grabbed) {
- EventData *data;
- data = eventdata_new_pointer(type, context, client, state, button,
- NULL, xroot, yroot);
- g_assert(data != NULL);
- hooks_fire_pointer(data);
- eventdata_free(data);
- return;
- }
-
- for (it = g_datalist_id_get_data(&bound_contexts, context);
- it != NULL; it = it->next){
- PointerBinding *b = it->data;
- if (b->state == state && b->button == button) {
- EventData *data;
- data = eventdata_new_pointer(type, context, client, state, button,
- b->name, xroot, yroot);
- g_assert(data != NULL);
- hooks_fire(data);
- eventdata_free(data);
- break;
- }
- }
-}
-
-gboolean mbind_grab_pointer(gboolean grab)
-{
- gboolean ret = TRUE;
- if (grab)
- ret = XGrabPointer(ob_display, ob_root, FALSE, (ButtonPressMask |
- ButtonReleaseMask |
- ButtonMotionMask |
- PointerMotionMask),
- GrabModeAsync, GrabModeAsync, None, None,
- CurrentTime) == GrabSuccess;
- else
- XUngrabPointer(ob_display, CurrentTime);
- return ret;
-}
+++ /dev/null
-#ifndef __mbind_h
-#define __mbind_h
-
-#include "obexport.h"
-#include "client.h"
-#include <glib.h>
-
-void mbind_startup();
-void mbind_shutdown();
-
-/*! Adds a new pointer binding */
-gboolean mbind_add(char *name, GQuark context);
-void mbind_clearall();
-
-void mbind_fire(guint state, guint button, GQuark context, EventType type,
- Client *client, int xroot, int yroot);
-
-void mbind_grab_all(Client *client, gboolean grab);
-gboolean mbind_grab_pointer(gboolean grab);
-
-#endif
+++ /dev/null
-#include "obexport.h"
-#include <Python.h>
-#include <glib.h>
-
-static PyMethodDef obMethods[] = {
- { NULL, NULL, 0, NULL }
-};
-
-#define ADD_INT_CONST(n) (PyModule_AddIntConstant(ob, #n, n))
-
-void obexport_startup()
-{
- PyObject *ob, *obdict;
-
- Py_InitModule("ob", obMethods);
-
- /* get the ob module/dict */
- ob = PyImport_ImportModule("ob"); /* new */
- g_assert(ob != NULL);
- obdict = PyModule_GetDict(ob); /* borrowed */
- g_assert(obdict != NULL);
-
- /* define all the constants! */
-
- /* State */
- ADD_INT_CONST(State_Starting);
- ADD_INT_CONST(State_Exiting);
- ADD_INT_CONST(State_Running);
-
- /* Corner */
- ADD_INT_CONST(Corner_TopLeft);
- ADD_INT_CONST(Corner_TopRight);
- ADD_INT_CONST(Corner_BottomLeft);
- ADD_INT_CONST(Corner_BottomRight);
-
- /* Orientation */
- ADD_INT_CONST(Orientation_Horz);
- ADD_INT_CONST(Orientation_Vert);
-
- /* Gravity */
- ADD_INT_CONST(Gravity_Forget);
- ADD_INT_CONST(Gravity_NE);
- ADD_INT_CONST(Gravity_N);
- ADD_INT_CONST(Gravity_NW);
- ADD_INT_CONST(Gravity_W);
- ADD_INT_CONST(Gravity_SW);
- ADD_INT_CONST(Gravity_S);
- ADD_INT_CONST(Gravity_SE);
- ADD_INT_CONST(Gravity_E);
- ADD_INT_CONST(Gravity_Center);
- ADD_INT_CONST(Gravity_Static);
-
- /* WindowType */
- ADD_INT_CONST(Type_Desktop);
- ADD_INT_CONST(Type_Dock);
- ADD_INT_CONST(Type_Toolbar);
- ADD_INT_CONST(Type_Menu);
- ADD_INT_CONST(Type_Utility);
- ADD_INT_CONST(Type_Splash);
- ADD_INT_CONST(Type_Dialog);
- ADD_INT_CONST(Type_Normal);
-
- /* Function */
- ADD_INT_CONST(Func_Resize);
- ADD_INT_CONST(Func_Move);
- ADD_INT_CONST(Func_Iconify);
- ADD_INT_CONST(Func_Maximize);
- ADD_INT_CONST(Func_Shade);
- ADD_INT_CONST(Func_Fullscreen);
- ADD_INT_CONST(Func_Close);
-
- /* Decoration */
- ADD_INT_CONST(Decor_Titlebar);
- ADD_INT_CONST(Decor_Handle);
- ADD_INT_CONST(Decor_Border);
- ADD_INT_CONST(Decor_Icon);
- ADD_INT_CONST(Decor_Iconify);
- ADD_INT_CONST(Decor_Maximize);
- ADD_INT_CONST(Decor_AllDesktops);
- ADD_INT_CONST(Decor_Close);
-
- /* StackLayer */
- ADD_INT_CONST(Layer_Icon);
- ADD_INT_CONST(Layer_Desktop);
- ADD_INT_CONST(Layer_Below);
- ADD_INT_CONST(Layer_Normal);
- ADD_INT_CONST(Layer_Above);
- ADD_INT_CONST(Layer_Top);
- ADD_INT_CONST(Layer_Fullscreen);
- ADD_INT_CONST(Layer_Internal);
-
- /* EventType */
- ADD_INT_CONST(Logical_EnterWindow);
- ADD_INT_CONST(Logical_LeaveWindow);
- ADD_INT_CONST(Logical_NewWindow);
- ADD_INT_CONST(Logical_CloseWindow);
- ADD_INT_CONST(Logical_Startup);
- ADD_INT_CONST(Logical_Shutdown);
- ADD_INT_CONST(Logical_RequestActivate);
- ADD_INT_CONST(Logical_Focus);
- ADD_INT_CONST(Logical_Bell);
- ADD_INT_CONST(Logical_UrgentWindow);
- ADD_INT_CONST(Logical_WindowShow);
- ADD_INT_CONST(Logical_WindowHide);
- ADD_INT_CONST(Pointer_Press);
- ADD_INT_CONST(Pointer_Release);
- ADD_INT_CONST(Pointer_Motion);
- ADD_INT_CONST(Key_Press);
- ADD_INT_CONST(Key_Release);
-
- Py_DECREF(ob);
-}
-
-void obexport_shutdown()
-{
-}
+++ /dev/null
-#ifndef __obexport_h
-#define __obexport_h
-
-#include <X11/Xlib.h>
-
-/* Define values which will be exported in the 'ob' module. */
-
-typedef enum {
- /*! Occurs when the mouse enters a window */
- Logical_EnterWindow,
- /*! Occurs when the mouse enters a window */
- Logical_LeaveWindow,
- /*! Occurs when a window is finished being managed, just before it is
- (possibly) displayed.
- The python scripts are reponsible for showing the window when this is
- called if they want it to be shown.
- */
- Logical_NewWindow,
- /*! Occurs when a window is being unmanaged */
- Logical_CloseWindow,
- /*! Occurs when the window manager starts up */
- Logical_Startup,
- /*! Occurs when the window manager is shutting down */
- Logical_Shutdown,
- /*! Occurs when a client is requesting/requested to be activated (i.e.
- focused, raised, unshaded) */
- Logical_RequestActivate,
- /*! Occurs when the input focus target changes
- The data.client will be NULL of no client is focused. */
- Logical_Focus,
- /*! Occurs when the system is fired through X.
- The data.client will hold the client associated with the bell if
- one has been specified, or NULL. */
- Logical_Bell,
- /*! Occurs when a client toggles its urgent status.
- The client.urgent member can be used to get the status. */
- Logical_UrgentWindow,
- /*! Occurs when a client becomes visible */
- Logical_WindowShow,
- /*! Occurs when a client becomes non-visible */
- Logical_WindowHide,
- /*! Occurs when a pointer button is pressed on a client or its
- decorations.
- Note: to get the event for the client's window or for the entire
- window+decorations, you need to do an mgrab for the window. */
- Pointer_Press,
- /*! Occurs when a pointer button is released on a client or its
- decorations.
- Note: to get the event for the client's window or for the entire
- window+decorations, you need to do an mgrab for the window. */
- Pointer_Release,
- /*! Occurs when a pointer button is held and the pointer is dragged on a
- client or its decorations.
- Note: to get the event for the client's window or for the entire
- window+decorations, you need to do an mgrab for the window, or an
- mgrab_pointer (in which case it may not be a drag). */
- Pointer_Motion,
- /*! Occurs when a key is pressed.
- Note: in order to recieve a key event, a kgrab must be done for the
- key combination, or a kgrab_keyboard.
- */
- Key_Press,
- /*! Occurs when a key is released.
- Note: in order to recieve a key event, a kgrab must be done for the
- key combination, or a kgrab_keyboard.
- */
- Key_Release
-} EventType;
-
-/* create the 'ob' module */
-void obexport_startup();
-void obexport_shutdown();
-
-#endif
+++ /dev/null
-#include "openbox.h"
-#include "event.h"
-#include "client.h"
-#include "xerror.h"
-#include "prop.h"
-#include "screen.h"
-#include "focus.h"
-#include "extensions.h"
-#include "python.h"
-#include "hooks.h"
-#include "eventdata.h"
-#include "gettext.h"
-#include "clientwrap.h"
-#include "screenwrap.h"
-#include "kbind.h"
-#include "mbind.h"
-#include "frame.h"
-
-#ifdef HAVE_FCNTL_H
-# include <fcntl.h>
-#endif
-#ifdef HAVE_SYS_SELECT_H
-# include <sys/select.h>
-#endif
-#ifdef HAVE_SIGNAL_H
-# include <signal.h>
-#endif
-#ifdef HAVE_STDLIB_H
-# include <stdlib.h>
-#endif
-#ifdef HAVE_SYS_WAIT_H
-# include <sys/types.h>
-# include <sys/wait.h>
-#endif
-#ifdef HAVE_LOCALE_H
-# include <locale.h>
-#endif
-
-#include <X11/cursorfont.h>
-
-Display *ob_display = NULL;
-int ob_screen;
-Window ob_root;
-State ob_state;
-gboolean ob_shutdown = FALSE;
-gboolean ob_restart = FALSE;
-gboolean ob_remote = FALSE;
-gboolean ob_sync = TRUE;
-Cursors ob_cursors;
-
-void signal_handler(int signal);
-
-int main(int argc, char **argv)
-{
- struct sigaction action;
- sigset_t sigset;
-
- ob_state = State_Starting;
-
- /* initialize the locale */
- if (!setlocale(LC_ALL, ""))
- g_warning("Couldn't set locale from environment.\n");
- bindtextdomain(PACKAGE, LOCALEDIR);
- bind_textdomain_codeset(PACKAGE, "UTF-8");
- textdomain(PACKAGE);
-
- /* set up signal handler */
- sigemptyset(&sigset);
- action.sa_handler = signal_handler;
- action.sa_mask = sigset;
- action.sa_flags = SA_NOCLDSTOP | SA_NODEFER;
- sigaction(SIGUSR1, &action, (struct sigaction *) NULL);
- sigaction(SIGPIPE, &action, (struct sigaction *) NULL);
- sigaction(SIGSEGV, &action, (struct sigaction *) NULL);
- sigaction(SIGFPE, &action, (struct sigaction *) NULL);
- sigaction(SIGTERM, &action, (struct sigaction *) NULL);
- sigaction(SIGINT, &action, (struct sigaction *) NULL);
- sigaction(SIGHUP, &action, (struct sigaction *) NULL);
- sigaction(SIGCHLD, &action, (struct sigaction *) NULL);
-
- /* anything that died while we were restarting won't give us a SIGCHLD */
- while (waitpid(-1, NULL, WNOHANG) > 0);
-
- /* XXX parse out command line args */
- (void)argc;(void)argv;
-
- /* critical warnings will exit the program */
- g_log_set_always_fatal(G_LOG_LEVEL_CRITICAL);
-
- ob_display = XOpenDisplay(NULL);
- if (ob_display == NULL)
- /* print a message and exit */
- g_critical("Failed to open the display.");
- if (fcntl(ConnectionNumber(ob_display), F_SETFD, 1) == -1)
- /* print a message and exit */
- g_critical("Failed to set display as close-on-exec.");
-
- ob_screen = DefaultScreen(ob_display);
- ob_root = RootWindow(ob_display, ob_screen);
-
- /* XXX fork self onto other screens */
-
- XSynchronize(ob_display, ob_sync);
-
- /* check for locale support */
- if (!XSupportsLocale())
- g_warning("X server does not support locale.");
- if (!XSetLocaleModifiers(""))
- g_warning("Cannot set locale modifiers for the X server.");
-
- /* set our error handler */
- XSetErrorHandler(xerror_handler);
-
- /* set the DISPLAY environment variable for any lauched children, to the
- display we're using, so they open in the right place. */
- putenv(g_strdup_printf("DISPLAY=%s", DisplayString(ob_display)));
-
- ob_cursors.left_ptr = XCreateFontCursor(ob_display, XC_left_ptr);
- ob_cursors.ll_angle = XCreateFontCursor(ob_display, XC_ll_angle);
- ob_cursors.lr_angle = XCreateFontCursor(ob_display, XC_lr_angle);
-
- prop_init(); /* get atoms values for the display */
- extensions_query_all(); /* find which extensions are present */
-
- if (screen_annex()) { /* it will be ours! */
- frame_startup();
- python_startup();
- obexport_startup();
- hooks_startup();
- screenwrap_startup();
- clientwrap_startup();
- eventdata_startup();
- event_startup();
- screen_startup();
- focus_startup();
- client_startup();
- kbind_startup();
- mbind_startup();
-
- /* load the user's settings */
- if (!python_import("rc"))
- g_warning("ERROR LOADING RC FILE");
-
- LOGICALHOOK(Startup, g_quark_try_string("none"), NULL);
-
- /* get all the existing windows */
- client_manage_all();
-
- ob_state = State_Running;
- while (!ob_shutdown) {
- event_loop();
- }
- ob_state = State_Exiting;
-
- client_unmanage_all();
-
- LOGICALHOOK(Shutdown, g_quark_try_string("none"), NULL);
-
- mbind_shutdown();
- kbind_shutdown();
- client_shutdown();
- screen_shutdown();
- event_shutdown();
- eventdata_shutdown();
- clientwrap_shutdown();
- screenwrap_shutdown();
- hooks_shutdown();
- obexport_shutdown();
- python_shutdown();
- }
-
- XCloseDisplay(ob_display);
-
- /* XXX if (ob_restart) */
-
- return 0;
-}
-
-void signal_handler(int signal)
-{
- switch (signal) {
- case SIGUSR1:
- g_message("Caught SIGUSR1 signal. Restarting.");
- ob_shutdown = ob_restart = TRUE;
- break;
-
- case SIGCHLD:
- wait(NULL);
- break;
-
- case SIGHUP:
- case SIGINT:
- case SIGTERM:
- case SIGPIPE:
- g_message("Caught signal %d. Exiting.", signal);
- ob_shutdown = TRUE;
- break;
-
- case SIGFPE:
- case SIGSEGV:
- g_error("Caught signal %d. Aborting and dumping core.", signal);
- }
-}
+++ /dev/null
-#ifndef __openbox_h
-#define __openbox_h
-
-#include "obexport.h"
-#include <glib.h>
-#include <X11/Xlib.h>
-
-/*! The X display */
-extern Display *ob_display;
-/*! The number of the screen on which we're running */
-extern int ob_screen;
-/*! The root window */
-extern Window ob_root;
-
-/* The state of execution of the window manager */
-State ob_state;
-
-/*! When set to true, Openbox will exit */
-extern gboolean ob_shutdown;
-/*! When set to true, Openbox will restart instead of shutting down */
-extern gboolean ob_restart;
-
-/*! Runtime option to specify running on a remote display */
-extern gboolean ob_remote;
-/*! Runtime option to run in synchronous mode */
-extern gboolean ob_sync;
-
-typedef struct Cursors {
- Cursor left_ptr;
- Cursor ll_angle;
- Cursor lr_angle;
-} Cursors;
-Cursors ob_cursors;
-
-#endif
+++ /dev/null
-#include "prop.h"
-#include "openbox.h"
-#include <X11/Xatom.h>
-
-Atoms prop_atoms;
-
-#define CREATE(var, name) (prop_atoms.var = \
- XInternAtom(ob_display, name, FALSE))
-
-void prop_init()
-{
- g_assert(ob_display != NULL);
-
- CREATE(cardinal, "CARDINAL");
- CREATE(window, "WINDOW");
- CREATE(pixmap, "PIXMAP");
- CREATE(atom, "ATOM");
- CREATE(string, "STRING");
- CREATE(utf8, "UTF8_STRING");
-
- CREATE(wm_colormap_windows, "WM_COLORMAP_WINDOWS");
- CREATE(wm_protocols, "WM_PROTOCOLS");
- CREATE(wm_state, "WM_STATE");
- CREATE(wm_change_state, "WM_CHANGE_STATE");
- CREATE(wm_delete_window, "WM_DELETE_WINDOW");
- CREATE(wm_take_focus, "WM_TAKE_FOCUS");
- CREATE(wm_name, "WM_NAME");
- CREATE(wm_icon_name, "WM_ICON_NAME");
- CREATE(wm_class, "WM_CLASS");
- CREATE(wm_window_role, "WM_WINDOW_ROLE");
- CREATE(motif_wm_hints, "_MOTIF_WM_HINTS");
-
- CREATE(net_supported, "_NET_SUPPORTED");
- CREATE(net_client_list, "_NET_CLIENT_LIST");
- CREATE(net_client_list_stacking, "_NET_CLIENT_LIST_STACKING");
- CREATE(net_number_of_desktops, "_NET_NUMBER_OF_DESKTOPS");
- CREATE(net_desktop_geometry, "_NET_DESKTOP_GEOMETRY");
- CREATE(net_desktop_viewport, "_NET_DESKTOP_VIEWPORT");
- CREATE(net_current_desktop, "_NET_CURRENT_DESKTOP");
- CREATE(net_desktop_names, "_NET_DESKTOP_NAMES");
- CREATE(net_active_window, "_NET_ACTIVE_WINDOW");
- CREATE(net_workarea, "_NET_WORKAREA");
- CREATE(net_supporting_wm_check, "_NET_SUPPORTING_WM_CHECK");
-/* CREATE(net_virtual_roots, "_NET_VIRTUAL_ROOTS"); */
- CREATE(net_desktop_layout, "_NET_DESKTOP_LAYOUT");
- CREATE(net_showing_desktop, "_NET_SHOWING_DESKTOP");
-
- CREATE(net_close_window, "_NET_CLOSE_WINDOW");
- CREATE(net_wm_moveresize, "_NET_WM_MOVERESIZE");
-
-/* CREATE(net_properties, "_NET_PROPERTIES"); */
- CREATE(net_wm_name, "_NET_WM_NAME");
- CREATE(net_wm_visible_name, "_NET_WM_VISIBLE_NAME");
- CREATE(net_wm_icon_name, "_NET_WM_ICON_NAME");
- CREATE(net_wm_visible_icon_name, "_NET_WM_VISIBLE_ICON_NAME");
- CREATE(net_wm_desktop, "_NET_WM_DESKTOP");
- CREATE(net_wm_window_type, "_NET_WM_WINDOW_TYPE");
- CREATE(net_wm_state, "_NET_WM_STATE");
- CREATE(net_wm_strut, "_NET_WM_STRUT");
-/* CREATE(net_wm_icon_geometry, "_NET_WM_ICON_GEOMETRY"); */
- CREATE(net_wm_icon, "_NET_WM_ICON");
-/* CREATE(net_wm_pid, "_NET_WM_PID"); */
-/* CREATE(net_wm_handled_icons, "_NET_WM_HANDLED_ICONS"); */
- CREATE(net_wm_allowed_actions, "_NET_WM_ALLOWED_ACTIONS");
-
-/* CREATE(net_wm_ping, "_NET_WM_PING"); */
-
- CREATE(net_wm_window_type_desktop, "_NET_WM_WINDOW_TYPE_DESKTOP");
- CREATE(net_wm_window_type_dock, "_NET_WM_WINDOW_TYPE_DOCK");
- CREATE(net_wm_window_type_toolbar, "_NET_WM_WINDOW_TYPE_TOOLBAR");
- CREATE(net_wm_window_type_menu, "_NET_WM_WINDOW_TYPE_MENU");
- CREATE(net_wm_window_type_utility, "_NET_WM_WINDOW_TYPE_UTILITY");
- CREATE(net_wm_window_type_splash, "_NET_WM_WINDOW_TYPE_SPLASH");
- CREATE(net_wm_window_type_dialog, "_NET_WM_WINDOW_TYPE_DIALOG");
- CREATE(net_wm_window_type_normal, "_NET_WM_WINDOW_TYPE_NORMAL");
-
- CREATE(net_wm_moveresize_size_topleft, "_NET_WM_MOVERESIZE_SIZE_TOPLEFT");
- CREATE(net_wm_moveresize_size_topright,
- "_NET_WM_MOVERESIZE_SIZE_TOPRIGHT");
- CREATE(net_wm_moveresize_size_bottomleft,
- "_NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT");
- CREATE(net_wm_moveresize_size_bottomright,
- "_NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT");
- CREATE(net_wm_moveresize_move, "_NET_WM_MOVERESIZE_MOVE");
-
- CREATE(net_wm_action_move, "_NET_WM_ACTION_MOVE");
- CREATE(net_wm_action_resize, "_NET_WM_ACTION_RESIZE");
- CREATE(net_wm_action_minimize, "_NET_WM_ACTION_MINIMIZE");
- CREATE(net_wm_action_shade, "_NET_WM_ACTION_SHADE");
- CREATE(net_wm_action_stick, "_NET_WM_ACTION_STICK");
- CREATE(net_wm_action_maximize_horz, "_NET_WM_ACTION_MAXIMIZE_HORZ");
- CREATE(net_wm_action_maximize_vert, "_NET_WM_ACTION_MAXIMIZE_VERT");
- CREATE(net_wm_action_fullscreen, "_NET_WM_ACTION_FULLSCREEN");
- CREATE(net_wm_action_change_desktop, "_NET_WM_ACTION_CHANGE_DESKTOP");
- CREATE(net_wm_action_close, "_NET_WM_ACTION_CLOSE");
- CREATE(net_wm_state_modal, "_NET_WM_STATE_MODAL");
- CREATE(net_wm_state_sticky, "_NET_WM_STATE_STICKY");
- CREATE(net_wm_state_maximized_vert, "_NET_WM_STATE_MAXIMIZED_VERT");
- CREATE(net_wm_state_maximized_horz, "_NET_WM_STATE_MAXIMIZED_HORZ");
- CREATE(net_wm_state_shaded, "_NET_WM_STATE_SHADED");
- CREATE(net_wm_state_skip_taskbar, "_NET_WM_STATE_SKIP_TASKBAR");
- CREATE(net_wm_state_skip_pager, "_NET_WM_STATE_SKIP_PAGER");
- CREATE(net_wm_state_hidden, "_NET_WM_STATE_HIDDEN");
- CREATE(net_wm_state_fullscreen, "_NET_WM_STATE_FULLSCREEN");
- CREATE(net_wm_state_above, "_NET_WM_STATE_ABOVE");
- CREATE(net_wm_state_below, "_NET_WM_STATE_BELOW");
-
- prop_atoms.net_wm_state_add = 1;
- prop_atoms.net_wm_state_remove = 0;
- prop_atoms.net_wm_state_toggle = 2;
-
- prop_atoms.net_wm_orientation_horz = 0;
- prop_atoms.net_wm_orientation_vert = 1;
- prop_atoms.net_wm_topleft = 0;
- prop_atoms.net_wm_topright = 1;
- prop_atoms.net_wm_bottomright = 2;
- prop_atoms.net_wm_bottomleft = 3;
-
- CREATE(kde_net_system_tray_windows, "_KDE_NET_SYSTEM_TRAY_WINDOWS");
- CREATE(kde_net_wm_system_tray_window_for,
- "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR");
- CREATE(kde_net_wm_window_type_override,
- "_KDE_NET_WM_WINDOW_TYPE_OVERRIDE");
-
- CREATE(kwm_win_icon, "KWM_WIN_ICON");
-
- CREATE(rootpmapid, "_XROOTPMAP_ID");
- CREATE(esetrootid, "ESETROOT_PMAP_ID");
-
- CREATE(openbox_pid, "_OPENBOX_PID");
- CREATE(openbox_premax, "_OPENBOX_PREMAX");
-}
-
-gboolean prop_get(Window win, Atom prop, Atom type, int size,
- guchar **data, gulong num)
-{
- gboolean ret = FALSE;
- int res;
- guchar *xdata = NULL;
- Atom ret_type;
- int ret_size;
- gulong ret_items, bytes_left;
- long num32 = 32 / size * num; /* num in 32-bit elements */
-
- res = XGetWindowProperty(ob_display, win, prop, 0l, num32,
- FALSE, type, &ret_type, &ret_size,
- &ret_items, &bytes_left, &xdata);
- if (res == Success && ret_items && xdata) {
- if (ret_size == size && ret_items >= num) {
- *data = g_memdup(xdata, num * (size / 8));
- ret = TRUE;
- }
- XFree(xdata);
- }
- return ret;
-}
-
-gboolean prop_get_prealloc(Window win, Atom prop, Atom type, int size,
- guchar *data, gulong num)
-{
- gboolean ret = FALSE;
- int res;
- guchar *xdata = NULL;
- Atom ret_type;
- int ret_size;
- gulong ret_items, bytes_left;
- long num32 = 32 / size * num; /* num in 32-bit elements */
-
- res = XGetWindowProperty(ob_display, win, prop, 0l, num32,
- FALSE, type, &ret_type, &ret_size,
- &ret_items, &bytes_left, &xdata);
- if (res == Success && ret_items && xdata) {
- if (ret_size == size && ret_items >= num) {
- gulong i;
- for (i = 0; i < num; ++i)
- switch (size) {
- case 8:
- data[i] = xdata[i];
- break;
- case 16:
- ((guint16*)data)[i] = ((guint16*)xdata)[i];
- break;
- case 32:
- ((guint32*)data)[i] = ((guint32*)xdata)[i];
- break;
- default:
- g_assert_not_reached(); /* unhandled size */
- }
- ret = TRUE;
- }
- XFree(xdata);
- }
- return ret;
-}
-
-gboolean prop_get_all(Window win, Atom prop, Atom type, int size,
- guchar **data, gulong *num)
-{
- gboolean ret = FALSE;
- int res;
- guchar *xdata = NULL;
- Atom ret_type;
- int ret_size;
- gulong ret_items, bytes_left;
-
- res = XGetWindowProperty(ob_display, win, prop, 0l, G_MAXLONG,
- FALSE, type, &ret_type, &ret_size,
- &ret_items, &bytes_left, &xdata);
- if (res == Success) {
- if (ret_size == size && ret_items > 0) {
- *data = g_memdup(xdata, ret_items * (size / 8));
- *num = ret_items;
- ret = TRUE;
- }
- XFree(xdata);
- }
- return ret;
-}
-
-gboolean prop_get_string(Window win, Atom prop, Atom type, guchar **data)
-{
- guchar *raw;
- gulong num;
- GString *str;
-
- if (prop_get_all(win, prop, type, 8, &raw, &num)) {
- str = g_string_new_len((char*)raw, num);
- g_assert(str->str[num] == '\0');
-
- g_free(raw);
-
- *data = (guchar*)g_string_free(str, FALSE);
- return TRUE;
- }
- return FALSE;
-}
-
-gboolean prop_get_strings(Window win, Atom prop, Atom type,
- GPtrArray *data)
-{
- guchar *raw;
- gulong num;
- GString *str, *str2;
- guint i, start;
-
- if (prop_get_all(win, prop, type, 8, &raw, &num)) {
- str = g_string_new_len((gchar*)raw, num);
- g_assert(str->str[num] == '\0'); /* assuming this is always true.. */
-
- g_free(raw);
-
- /* split it into the list */
- for (start = 0, i = 0; i < str->len; ++i) {
- if (str->str[i] == '\0') {
- str2 = g_string_new_len(&str->str[start], i - start);
- g_ptr_array_add(data, g_string_free(str2, FALSE));
- start = i + 1;
- }
- }
- g_string_free(str, TRUE);
-
- if (data->len > 0)
- return TRUE;
- }
- return FALSE;
-}
-
-void prop_erase(Window win, Atom prop)
-{
- XDeleteProperty(ob_display, win, prop);
-}
+++ /dev/null
-#ifndef __atoms_h
-#define __atoms_h
-
-#include <X11/Xlib.h>
-#include <glib.h>
-#ifdef HAVE_STRING_H
-# include <string.h>
-#endif
-
-#include "openbox.h"
-
-/*! The atoms on the X server which this class will cache */
-typedef struct Atoms {
- /* types */
- Atom cardinal; /*!< The atom which represents the Cardinal data type */
- Atom window; /*!< The atom which represents window ids */
- Atom pixmap; /*!< The atom which represents pixmap ids */
- Atom atom; /*!< The atom which represents atom values */
- Atom string; /*!< The atom which represents ascii strings */
- Atom utf8; /*!< The atom which represents utf8-encoded strings */
-
- /* window hints */
- Atom wm_colormap_windows;
- Atom wm_protocols;
- Atom wm_state;
- Atom wm_delete_window;
- Atom wm_take_focus;
- Atom wm_change_state;
- Atom wm_name;
- Atom wm_icon_name;
- Atom wm_class;
- Atom wm_window_role;
- Atom motif_wm_hints;
-
- /* NETWM atoms */
-
- /* root window properties */
- Atom net_supported;
- Atom net_client_list;
- Atom net_client_list_stacking;
- Atom net_number_of_desktops;
- Atom net_desktop_geometry;
- Atom net_desktop_viewport;
- Atom net_current_desktop;
- Atom net_desktop_names;
- Atom net_active_window;
- Atom net_workarea;
- Atom net_supporting_wm_check;
-/* Atom net_virtual_roots; */
- Atom net_desktop_layout;
- Atom net_showing_desktop;
- /* root window messages */
- Atom net_close_window;
- Atom net_wm_moveresize;
- /* application window properties */
-/* Atom net_properties; */
- Atom net_wm_name;
- Atom net_wm_visible_name;
- Atom net_wm_icon_name;
- Atom net_wm_visible_icon_name;
- Atom net_wm_desktop;
- Atom net_wm_window_type;
- Atom net_wm_state;
- Atom net_wm_strut;
-/* Atom net_wm_icon_geometry; */
- Atom net_wm_icon;
-/* Atom net_wm_pid; */
-/* Atom net_wm_handled_icons; */
- Atom net_wm_allowed_actions;
- /* application protocols */
-/* Atom Atom net_wm_ping; */
-
- Atom net_wm_window_type_desktop;
- Atom net_wm_window_type_dock;
- Atom net_wm_window_type_toolbar;
- Atom net_wm_window_type_menu;
- Atom net_wm_window_type_utility;
- Atom net_wm_window_type_splash;
- Atom net_wm_window_type_dialog;
- Atom net_wm_window_type_normal;
-
- Atom net_wm_moveresize_size_topleft;
- Atom net_wm_moveresize_size_topright;
- Atom net_wm_moveresize_size_bottomleft;
- Atom net_wm_moveresize_size_bottomright;
- Atom net_wm_moveresize_move;
-
- Atom net_wm_action_move;
- Atom net_wm_action_resize;
- Atom net_wm_action_minimize;
- Atom net_wm_action_shade;
- Atom net_wm_action_stick;
- Atom net_wm_action_maximize_horz;
- Atom net_wm_action_maximize_vert;
- Atom net_wm_action_fullscreen;
- Atom net_wm_action_change_desktop;
- Atom net_wm_action_close;
-
- Atom net_wm_state_modal;
- Atom net_wm_state_sticky;
- Atom net_wm_state_maximized_vert;
- Atom net_wm_state_maximized_horz;
- Atom net_wm_state_shaded;
- Atom net_wm_state_skip_taskbar;
- Atom net_wm_state_skip_pager;
- Atom net_wm_state_hidden;
- Atom net_wm_state_fullscreen;
- Atom net_wm_state_above;
- Atom net_wm_state_below;
-
- Atom net_wm_state_add;
- Atom net_wm_state_remove;
- Atom net_wm_state_toggle;
-
- Atom net_wm_orientation_horz;
- Atom net_wm_orientation_vert;
- Atom net_wm_topleft;
- Atom net_wm_topright;
- Atom net_wm_bottomright;
- Atom net_wm_bottomleft;
-
- /* Extra atoms */
-
- Atom kde_net_system_tray_windows;
- Atom kde_net_wm_system_tray_window_for;
- Atom kde_net_wm_window_type_override;
-
- Atom kwm_win_icon;
-
- Atom rootpmapid;
- Atom esetrootid;
-
- /* Openbox specific atoms */
-
- Atom openbox_pid;
- Atom openbox_premax;
-} Atoms;
-Atoms prop_atoms;
-
-void prop_init();
-
-gboolean prop_get(Window win, Atom prop, Atom type, int size,
- guchar **data, gulong num);
-
-gboolean prop_get_prealloc(Window win, Atom prop, Atom type, int size,
- guchar *data, gulong num);
-
-gboolean prop_get_all(Window win, Atom prop, Atom type, int size,
- guchar **data, gulong *num);
-
-gboolean prop_get_string(Window win, Atom prop, Atom type, guchar **data);
-gboolean prop_get_strings(Window win, Atom prop, Atom type,
- GPtrArray *data);
-
-void prop_erase(Window win, Atom prop);
-
-/* Set an 8-bit property from a string */
-#define PROP_SETS(win, prop, type, value) \
- (XChangeProperty(ob_display, win, prop_atoms.prop, prop_atoms.type, 8, \
- PropModeReplace, (guchar*)value, strlen(value)))
-/* Set a 32-bit property from a single value */
-#define PROP_SET32(win, prop, type, value) \
- (XChangeProperty(ob_display, win, prop_atoms.prop, prop_atoms.type, 32, \
- PropModeReplace, (guchar*)&value, 1))
-/* Set a 32-bit property from an array */
-#define PROP_SET32A(win, prop, type, value, num) \
- (XChangeProperty(ob_display, win, prop_atoms.prop, prop_atoms.type, 32, \
- PropModeReplace, (guchar*)value, num))
-
-/* Get an 8-bit property into a string */
-#define PROP_GETS(win, prop, type, value) \
- (prop_get_string(win, prop_atoms.prop, prop_atoms.type, \
- (guchar**)&value))
-/* Get an 8-bit property into a GPtrArray of strings
- (The strings must be freed, the GPtrArray must already be created.) */
-#define PROP_GETSA(win, prop, type, value) \
- (prop_get_strings(win, prop_atoms.prop, prop_atoms.type, \
- value))
-
-/* Get an entire 8-bit property into an array (which must be freed) */
-#define PROP_GET8U(win, prop, type, value, num) \
- (prop_get_all(win, prop_atoms.prop, prop_atoms.type, 8, \
- (guchar**)&value, &num))
-
-/* Get 1 element of a 32-bit property into a given variable */
-#define PROP_GET32(win, prop, type, value) \
- (prop_get_prealloc(win, prop_atoms.prop, prop_atoms.type, 32, \
- (guchar*)&value, 1))
-
-/* Get an amount of a 32-bit property into an array (which must be freed) */
-#define PROP_GET32A(win, prop, type, value, num) \
- (prop_get(win, prop_atoms.prop, prop_atoms.type, 32, \
- (guchar**)&value, num))
-
-/* Get an entire 32-bit property into an array (which must be freed) */
-#define PROP_GET32U(win, prop, type, value, num) \
- (prop_get_all(win, prop_atoms.prop, prop_atoms.type, 32, \
- (guchar**)&value, &num))
-
-#define PROP_ERASE(win, prop) (prop_erase(win, prop_atoms.prop))
-
-#endif
+++ /dev/null
-#include <Python.h>
-#include <glib.h>
-
-#ifdef HAVE_STDLIB_H
-# include <stdlib.h>
-#endif
-
-void python_startup()
-{
- PyObject *sys, *sysdict, *syspath, *path1, *path2;
- char *home, *homescriptdir;
-
- Py_Initialize();
-
- /* fix up the system path */
-
- sys = PyImport_ImportModule((char*)"sys"); /* new */
- sysdict = PyModule_GetDict(sys); /* borrowed */
- syspath = PyDict_GetItemString(sysdict, (char*)"path"); /* borrowed */
-
- path1 = PyString_FromString(SCRIPTDIR); /* new */
- PyList_Insert(syspath, 0, path1);
- Py_DECREF(path1);
-
- home = getenv("HOME");
- if (home != NULL) {
- homescriptdir = g_strdup_printf("%s/.openbox", home);
- path2 = PyString_FromString(homescriptdir); /* new */
- g_free(homescriptdir);
-
- PyList_Insert(syspath, 0, path2);
- Py_DECREF(path2);
- } else
- g_warning("Failed to read the $HOME environment variable");
-
- Py_DECREF(sys);
-}
-
-void python_shutdown()
-{
- Py_Finalize();
-}
-
-gboolean python_import(char *module)
-{
- PyObject *mod;
-
- mod = PyImport_ImportModule(module); /* new */
- if (mod == NULL) {
- PyErr_Print();
- return FALSE;
- }
- Py_DECREF(mod);
- return TRUE;
-}
+++ /dev/null
-#ifndef __python_h
-#define __python_h
-
-void python_startup();
-void python_shutdown();
-
-/*! Import a python module */
-gboolean python_import(char *module);
-
-#endif
+++ /dev/null
-#include "openbox.h"
-#include "prop.h"
-#include "screen.h"
-#include "client.h"
-#include "focus.h"
-
-#include <X11/Xlib.h>
-#ifdef HAVE_UNISTD_H
-# include <sys/types.h>
-# include <unistd.h>
-#endif
-
-/*! The event mask to grab on the root window */
-#define ROOT_EVENTMASK (/*ColormapChangeMask |*/ PropertyChangeMask | \
- EnterWindowMask | LeaveWindowMask | \
- SubstructureNotifyMask | SubstructureRedirectMask | \
- ButtonPressMask | ButtonReleaseMask | ButtonMotionMask)
-
-guint screen_num_desktops = 1;
-guint screen_desktop = 0;
-Size screen_physical_size;
-gboolean screen_showing_desktop;
-DesktopLayout screen_desktop_layout;
-GPtrArray *screen_desktop_names;
-
-static Rect *area = NULL;
-static Strut *strut = NULL;
-
-static void screen_update_area();
-
-static gboolean running;
-static int another_running(Display *d, XErrorEvent *e)
-{
- (void)d;(void)e;
- g_message("A window manager is already running on screen %d",
- ob_screen);
- running = TRUE;
- return -1;
-}
-
-gboolean screen_annex()
-{
- XErrorHandler old;
- Window support;
- pid_t pid;
- int i, num_support;
- Atom *supported;
-
- running = FALSE;
- old = XSetErrorHandler(another_running);
- XSelectInput(ob_display, ob_root, ROOT_EVENTMASK);
- XSync(ob_display, FALSE);
- XSetErrorHandler(old);
- if (running)
- return FALSE;
-
- g_message("Managing screen %d", ob_screen);
-
- /* set the mouse cursor for the root window (the default cursor) */
- XDefineCursor(ob_display, ob_root, ob_cursors.left_ptr);
-
- /* set the OPENBOX_PID hint */
- pid = getpid();
- PROP_SET32(ob_root, openbox_pid, cardinal, pid);
-
- /* create the netwm support window */
- support = XCreateSimpleWindow(ob_display, ob_root, 0, 0, 1, 1, 0, 0, 0);
-
- /* set supporting window */
- PROP_SET32(ob_root, net_supporting_wm_check, window, support);
-
- /* set properties on the supporting window */
- PROP_SETS(support, net_wm_name, utf8, "Openbox");
- PROP_SET32(support, net_supporting_wm_check, window, support);
-
- /* set the _NET_SUPPORTED_ATOMS hint */
- num_support = 48;
- i = 0;
- supported = g_new(Atom, num_support);
- supported[i++] = prop_atoms.net_current_desktop;
- supported[i++] = prop_atoms.net_number_of_desktops;
- supported[i++] = prop_atoms.net_desktop_geometry;
- supported[i++] = prop_atoms.net_desktop_viewport;
- supported[i++] = prop_atoms.net_active_window;
- supported[i++] = prop_atoms.net_workarea;
- supported[i++] = prop_atoms.net_client_list;
- supported[i++] = prop_atoms.net_client_list_stacking;
- supported[i++] = prop_atoms.net_desktop_names;
- supported[i++] = prop_atoms.net_close_window;
- supported[i++] = prop_atoms.net_desktop_layout;
- supported[i++] = prop_atoms.net_showing_desktop;
- supported[i++] = prop_atoms.net_wm_name;
- supported[i++] = prop_atoms.net_wm_visible_name;
- supported[i++] = prop_atoms.net_wm_icon_name;
- supported[i++] = prop_atoms.net_wm_visible_icon_name;
- supported[i++] = prop_atoms.net_wm_desktop;
- supported[i++] = prop_atoms.net_wm_strut;
- supported[i++] = prop_atoms.net_wm_window_type;
- supported[i++] = prop_atoms.net_wm_window_type_desktop;
- supported[i++] = prop_atoms.net_wm_window_type_dock;
- supported[i++] = prop_atoms.net_wm_window_type_toolbar;
- supported[i++] = prop_atoms.net_wm_window_type_menu;
- supported[i++] = prop_atoms.net_wm_window_type_utility;
- supported[i++] = prop_atoms.net_wm_window_type_splash;
- supported[i++] = prop_atoms.net_wm_window_type_dialog;
- supported[i++] = prop_atoms.net_wm_window_type_normal;
- supported[i++] = prop_atoms.net_wm_allowed_actions;
- supported[i++] = prop_atoms.net_wm_action_move;
- supported[i++] = prop_atoms.net_wm_action_resize;
- supported[i++] = prop_atoms.net_wm_action_minimize;
- supported[i++] = prop_atoms.net_wm_action_shade;
- supported[i++] = prop_atoms.net_wm_action_maximize_horz;
- supported[i++] = prop_atoms.net_wm_action_maximize_vert;
- supported[i++] = prop_atoms.net_wm_action_fullscreen;
- supported[i++] = prop_atoms.net_wm_action_change_desktop;
- supported[i++] = prop_atoms.net_wm_action_close;
- supported[i++] = prop_atoms.net_wm_state;
- supported[i++] = prop_atoms.net_wm_state_modal;
- supported[i++] = prop_atoms.net_wm_state_maximized_vert;
- supported[i++] = prop_atoms.net_wm_state_maximized_horz;
- supported[i++] = prop_atoms.net_wm_state_shaded;
- supported[i++] = prop_atoms.net_wm_state_skip_taskbar;
- supported[i++] = prop_atoms.net_wm_state_skip_pager;
- supported[i++] = prop_atoms.net_wm_state_hidden;
- supported[i++] = prop_atoms.net_wm_state_fullscreen;
- supported[i++] = prop_atoms.net_wm_state_above;
- supported[i++] = prop_atoms.net_wm_state_below;
- g_assert(i == num_support);
-/*
- supported[] = prop_atoms.net_wm_moveresize;
- supported[] = prop_atoms.net_wm_moveresize_size_topleft;
- supported[] = prop_atoms.net_wm_moveresize_size_topright;
- supported[] = prop_atoms.net_wm_moveresize_size_bottomleft;
- supported[] = prop_atoms.net_wm_moveresize_size_bottomright;
- supported[] = prop_atoms.net_wm_moveresize_move;
- supported[] = prop_atoms.net_wm_action_stick;
-*/
-
- PROP_SET32A(ob_root, net_supported, atom, supported, num_support);
- g_free(supported);
-
- return TRUE;
-}
-
-void screen_startup()
-{
- screen_desktop_names = g_ptr_array_new();
-
- /* get the initial size */
- screen_resize();
-
- screen_set_num_desktops(4);
- screen_set_desktop(0);
-
- /* don't start in showing-desktop mode */
- screen_showing_desktop = FALSE;
- PROP_SET32(ob_root, net_showing_desktop, cardinal, screen_showing_desktop);
-
- screen_update_layout();
-}
-
-void screen_shutdown()
-{
- guint i;
- for (i = 0; i < screen_desktop_names->len; ++i)
- g_free(g_ptr_array_index(screen_desktop_names, i));
- g_ptr_array_free(screen_desktop_names, TRUE);
- g_free(strut);
- g_free(area);
-}
-
-void screen_resize()
-{
- /* Set the _NET_DESKTOP_GEOMETRY hint */
- /* XXX RandR support here? */
- int geometry[2];
-
- geometry[0] = WidthOfScreen(ScreenOfDisplay(ob_display, ob_screen));
- geometry[1] = HeightOfScreen(ScreenOfDisplay(ob_display, ob_screen));
- PROP_SET32A(ob_root, net_desktop_geometry, cardinal, geometry, 2);
- screen_physical_size.width = geometry[0];
- screen_physical_size.height = geometry[1];
-
- if (ob_state == State_Starting)
- return;
-
- screen_update_struts();
-
- /* XXX adjust more stuff ? */
-}
-
-void screen_set_num_desktops(guint num)
-{
- unsigned long *viewport;
-
- g_assert(num > 0);
-
- /* move windows on desktops that will no longer exist! */
- /* XXX
- std::list<Client*>::iterator it, end = clients.end();
- for (it = clients.begin(); it != end; ++it) {
- unsigned int d = (*it)->desktop();
- if (d >= num && d != 0xffffffff) {
- XEvent ce;
- ce.xclient.type = ClientMessage;
- ce.xclient.message_type = otk::Property::atoms.net_wm_desktop;
- ce.xclient.display = **otk::display;
- ce.xclient.window = (*it)->window();
- ce.xclient.format = 32;
- ce.xclient.data.l[0] = num - 1;
- XSendEvent(**otk::display, _info->rootWindow(), false,
- SubstructureNotifyMask | SubstructureRedirectMask, &ce);
- }
- }
- */
-
- screen_num_desktops = num;
- PROP_SET32(ob_root, net_number_of_desktops, cardinal, num);
-
- /* set the viewport hint */
- viewport = g_new0(unsigned long, num * 2);
- PROP_SET32A(ob_root, net_desktop_viewport, cardinal, viewport, num * 2);
- g_free(viewport);
-
- /* change our struts/area to match */
- screen_update_struts();
-
- /* the number of rows/columns will differ */
- screen_update_layout();
-
- /* may be some unnamed desktops that we need to fill in with names */
- screen_update_desktop_names();
-
- /* change our desktop if we're on one that no longer exists! */
- if (screen_desktop >= screen_num_desktops)
- screen_set_desktop(num - 1);
-}
-
-void screen_set_desktop(guint num)
-{
- guint old = screen_desktop;
-
- g_assert(num < screen_num_desktops);
-
- g_message("Moving to desktop %u", num);
-
- screen_desktop = num;
- PROP_SET32(ob_root, net_current_desktop, cardinal, num);
-
- if (old == num) return;
-
- /* XXX show/hide all the clients
- std::list<Client*>::iterator it, end = clients.end();
- for (it = clients.begin(); it != end; ++it)
- (*it)->showhide(); */
-
- /* XXX force the callbacks to fire
- if (!openbox->focusedClient())
- openbox->setFocusedClient(0); */
-}
-
-void screen_update_layout()
-{
- unsigned long *data = NULL;
-
- /* defaults */
- screen_desktop_layout.orientation = prop_atoms.net_wm_orientation_horz;
- screen_desktop_layout.start_corner = prop_atoms.net_wm_topleft;
- screen_desktop_layout.rows = 1;
- screen_desktop_layout.columns = screen_num_desktops;
-
- if (PROP_GET32A(ob_root, net_desktop_layout, cardinal, data, 4)) {
- if (data[0] == prop_atoms.net_wm_orientation_vert)
- screen_desktop_layout.orientation = data[0];
- if (data[3] == prop_atoms.net_wm_topright)
- screen_desktop_layout.start_corner = data[3];
- else if (data[3] == prop_atoms.net_wm_bottomright)
- screen_desktop_layout.start_corner = data[3];
- else if (data[3] == prop_atoms.net_wm_bottomleft)
- screen_desktop_layout.start_corner = data[3];
-
- /* fill in a zero rows/columns */
- if (!(data[1] == 0 && data[2] == 0)) { /* both 0's is bad data.. */
- if (data[1] == 0) {
- data[1] = (screen_num_desktops +
- screen_num_desktops % data[2]) / data[2];
- } else if (data[2] == 0) {
- data[2] = (screen_num_desktops +
- screen_num_desktops % data[1]) / data[1];
- }
- screen_desktop_layout.columns = data[1];
- screen_desktop_layout.rows = data[2];
- }
-
- /* bounds checking */
- if (screen_desktop_layout.orientation ==
- prop_atoms.net_wm_orientation_horz) {
- if (screen_desktop_layout.rows > screen_num_desktops)
- screen_desktop_layout.rows = screen_num_desktops;
- if (screen_desktop_layout.columns > ((screen_num_desktops +
- screen_num_desktops %
- screen_desktop_layout.rows) /
- screen_desktop_layout.rows))
- screen_desktop_layout.columns =
- (screen_num_desktops + screen_num_desktops %
- screen_desktop_layout.rows) /
- screen_desktop_layout.rows;
- } else {
- if (screen_desktop_layout.columns > screen_num_desktops)
- screen_desktop_layout.columns = screen_num_desktops;
- if (screen_desktop_layout.rows > ((screen_num_desktops +
- screen_num_desktops %
- screen_desktop_layout.columns) /
- screen_desktop_layout.columns))
- screen_desktop_layout.rows =
- (screen_num_desktops + screen_num_desktops %
- screen_desktop_layout.columns) /
- screen_desktop_layout.columns;
- }
- g_free(data);
- }
-}
-
-void screen_update_desktop_names()
-{
- guint i;
-
- /* empty the array */
- for (i = 0; i < screen_desktop_names->len; ++i)
- g_free(g_ptr_array_index(screen_desktop_names, i));
- g_ptr_array_set_size(screen_desktop_names, 0);
-
- PROP_GETSA(ob_root, net_desktop_names, utf8, screen_desktop_names);
-
- while (screen_desktop_names->len < screen_num_desktops)
- g_ptr_array_add(screen_desktop_names, g_strdup("Unnamed Desktop"));
-}
-
-void screen_show_desktop(gboolean show)
-{
- GSList *it;
- static Window saved_focus = 0;
-
- if (show == screen_showing_desktop) return; /* no change */
-
- /* save the window focus, and restore it when leaving the show-desktop
- mode */
- if (show && focus_client)
- saved_focus = focus_client->window;
-
- screen_showing_desktop = show;
-
- for (it = client_list; it; it = g_slist_next(it)) {
- Client *client = it->data;
- if (client->type == Type_Desktop) {
- if (show) client_focus(client);
- } else
- client_showhide(client);
- }
-
- if (!show) {
- Client *f = focus_client;
- if (!f || f->type == Type_Desktop) {
- Client *c = g_hash_table_lookup(client_map,
- (gpointer)saved_focus);
- if (c) client_focus(c);
- }
- }
-
- show = show ? 1 : 0; /* make it boolean */
- PROP_SET32(ob_root, net_showing_desktop, cardinal, show);
-}
-
-void screen_install_colormap(Client *client, gboolean install)
-{
- if (client == NULL) {
- /* XXX DONT USE THE DEFAULT SHIT HERE */
- if (install)
- XInstallColormap(ob_display,
- DefaultColormap(ob_display, ob_screen));
- else
- XUninstallColormap(ob_display,
- DefaultColormap(ob_display, ob_screen));
- } else {
- XWindowAttributes wa;
- if (XGetWindowAttributes(ob_display, client->window, &wa)) {
- if (install)
- XInstallColormap(ob_display, wa.colormap);
- else
- XUninstallColormap(ob_display, wa.colormap);
- }
- }
-}
-
-void screen_update_struts()
-{
- GSList *it;
- guint i;
-
- if (strut != NULL)
- g_free(strut);
- strut = g_new0(Strut, screen_num_desktops + 1);
-
- for (it = client_list; it; it = it->next) {
- Client *c = it->data;
- if (c->iconic) continue; /* these dont count in the strut */
-
- if (c->desktop == 0xffffffff) {
- for (i = 0; i < screen_num_desktops; ++i)
- STRUT_ADD(strut[i], c->strut);
- } else {
- g_assert(c->desktop < screen_num_desktops);
- STRUT_ADD(strut[c->desktop], c->strut);
- }
- /* apply to the 'all desktops' strut */
- STRUT_ADD(strut[screen_num_desktops], c->strut);
- }
- screen_update_area();
-}
-
-static void screen_update_area()
-{
- guint i;
- gulong *dims;
-
- if (area != NULL)
- g_free(area);
- area = g_new0(Rect, screen_num_desktops + 1);
-
- dims = g_new(unsigned long, 4 * screen_num_desktops);
- for (i = 0; i < screen_num_desktops + 1; ++i) {
- Rect old_area = area[i];
-/*
- #ifdef XINERAMA
- // reset to the full areas
- if (isXineramaActive())
- xineramaUsableArea = getXineramaAreas();
- #endif // XINERAMA
-*/
-
- RECT_SET(area[i], strut[i].left, strut[i].top,
- screen_physical_size.width - (strut[i].left +
- strut[i].right),
- screen_physical_size.height - (strut[i].top +
- strut[i].bottom));
-
-/*
- #ifdef XINERAMA
- if (isXineramaActive()) {
- // keep each of the ximerama-defined areas inside the strut
- RectList::iterator xit, xend = xineramaUsableArea.end();
- for (xit = xineramaUsableArea.begin(); xit != xend; ++xit) {
- if (xit->x() < usableArea.x()) {
- xit->setX(usableArea.x());
- xit->setWidth(xit->width() - usableArea.x());
- }
- if (xit->y() < usableArea.y()) {
- xit->setY(usableArea.y());
- xit->setHeight(xit->height() - usableArea.y());
- }
- if (xit->x() + xit->width() > usableArea.width())
- xit->setWidth(usableArea.width() - xit->x());
- if (xit->y() + xit->height() > usableArea.height())
- xit->setHeight(usableArea.height() - xit->y());
- }
- }
- #endif // XINERAMA
-*/
- if (!RECT_EQUAL(old_area, area[i])) {
- /* the area has changed, adjust all the maximized windows */
- GSList *it;
- for (it = client_list; it; it = it->next) {
- Client *c = it->data;
- if (i < screen_num_desktops) {
- if (c->desktop == i)
- client_remaximize(c);
- } else {
- /* the 'all desktops' size */
- if (c->desktop == DESKTOP_ALL)
- client_remaximize(c);
- }
- }
- }
-
- /* don't set these for the 'all desktops' area */
- if (i < screen_num_desktops) {
- dims[(i * 4) + 0] = area[i].x;
- dims[(i * 4) + 1] = area[i].y;
- dims[(i * 4) + 2] = area[i].width;
- dims[(i * 4) + 3] = area[i].height;
- }
- }
- PROP_SET32A(ob_root, net_workarea, cardinal,
- dims, 4 * screen_num_desktops);
- g_free(dims);
-}
-
-Rect *screen_area(guint desktop)
-{
- if (desktop >= screen_num_desktops) {
- if (desktop == DESKTOP_ALL)
- return &area[screen_num_desktops];
- return NULL;
- }
- return &area[desktop];
-}
-
-Strut *screen_strut(guint desktop)
-{
- if (desktop >= screen_num_desktops) {
- if (desktop == DESKTOP_ALL)
- return &strut[screen_num_desktops];
- return NULL;
- }
- return &strut[desktop];
-}
+++ /dev/null
-#ifndef __screen_h
-#define __screen_h
-
-#include "geom.h"
-
-struct Client;
-
-#define DESKTOP_ALL (0xffffffff)
-
-/*! The number of available desktops */
-extern guint screen_num_desktops;
-/*! The current desktop */
-extern guint screen_desktop;
-/*! The size of the screen */
-extern Size screen_physical_size;
-/*! Are we in showing-desktop mode? */
-extern gboolean screen_showing_desktop;
-
-typedef struct DesktopLayout {
- guint orientation;
- guint start_corner;
- guint rows;
- guint columns;
-} DesktopLayout;
-extern DesktopLayout screen_desktop_layout;
-
-/*! An array of gchar*'s which are desktop names in UTF-8 format */
-extern GPtrArray *screen_desktop_names;
-
-/*! Take over the screen, set the basic hints on it claming it as ours */
-gboolean screen_annex();
-
-/*! Once the screen is ours, set up its initial state */
-void screen_startup();
-/*! Free resources */
-void screen_shutdown();
-
-/*! Figure out the new size of the screen and adjust stuff for it */
-void screen_resize();
-
-/*! Change the number of available desktops */
-void screen_set_num_desktops(guint num);
-/*! Change the current desktop */
-void screen_set_desktop(guint num);
-
-/*! Shows and focuses the desktop and hides all the client windows, or
- returns to the normal state, showing client windows. */
-void screen_show_desktop(gboolean show);
-
-/*! Updates the desktop layout from the root property if available */
-void screen_update_layout();
-
-/*! Get desktop names from the root window property */
-void screen_update_desktop_names();
-
-/*! Installs or uninstalls a colormap for a client. If client is NULL, then
- it handles the root colormap. */
-void screen_install_colormap(struct Client *client, gboolean install);
-
-void screen_update_struts();
-
-Rect *screen_area(guint desktop);
-
-Strut *screen_strut(guint desktop);
-
-#endif
+++ /dev/null
-#include "screenwrap.h"
-#include "openbox.h"
-#include "screen.h"
-#include "kbind.h"
-#include "mbind.h"
-
-ScreenWrap *screenwrap_instance;
-
-/***************************************************************************
-
- Define the type 'ScreenWrap'
-
- ***************************************************************************/
-
-#define IS_SWRAP(v) ((v)->ob_type == &ScreenWrapType)
-#define CHECK_SWRAP(self, funcname) { \
- if (!IS_SWRAP(self)) { \
- PyErr_SetString(PyExc_TypeError, \
- "descriptor '" funcname "' a 'Screen' object"); \
- return NULL; \
- } \
-}
-
-staticforward PyTypeObject ScreenWrapType;
-
-/***************************************************************************
-
- Attribute methods
-
- ***************************************************************************/
-
-static PyObject *swrap_number(ScreenWrap *self, PyObject *args)
-{
- CHECK_SWRAP(self, "number");
- if (!PyArg_ParseTuple(args, ":number"))
- return NULL;
- return PyInt_FromLong(ob_screen);
-}
-
-static PyObject *swrap_rootWindow(ScreenWrap *self, PyObject *args)
-{
- CHECK_SWRAP(self, "rootWindow");
- if (!PyArg_ParseTuple(args, ":rootWindow"))
- return NULL;
- return PyInt_FromLong(ob_root);
-}
-
-static PyObject *swrap_state(ScreenWrap *self, PyObject *args)
-{
- CHECK_SWRAP(self, "state");
- if (!PyArg_ParseTuple(args, ":state"))
- return NULL;
- return PyInt_FromLong(ob_state);
-}
-
-static PyObject *swrap_numDesktops(ScreenWrap *self, PyObject *args)
-{
- CHECK_SWRAP(self, "numDesktops");
- if (!PyArg_ParseTuple(args, ":numDesktops"))
- return NULL;
- return PyInt_FromLong(screen_num_desktops);
-}
-
-static PyObject *swrap_desktop(ScreenWrap *self, PyObject *args)
-{
- CHECK_SWRAP(self, "desktop");
- if (!PyArg_ParseTuple(args, ":desktop"))
- return NULL;
- return PyInt_FromLong(screen_desktop);
-}
-
-static PyObject *swrap_physicalSize(ScreenWrap *self, PyObject *args)
-{
- PyObject *tuple;
-
- CHECK_SWRAP(self, "physicalSize");
- if (!PyArg_ParseTuple(args, ":physicalSize"))
- return NULL;
- tuple = PyTuple_New(2);
- PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(screen_physical_size.width));
- PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(screen_physical_size.height));
- return tuple;
-}
-
-static PyObject *swrap_showingDesktop(ScreenWrap *self, PyObject *args)
-{
- CHECK_SWRAP(self, "showingDesktop");
- if (!PyArg_ParseTuple(args, ":showingDesktop"))
- return NULL;
- return PyInt_FromLong(screen_showing_desktop ? 1 : 0);
-}
-
-static PyObject *swrap_desktopLayout(ScreenWrap *self, PyObject *args)
-{
- PyObject *tuple;
-
- CHECK_SWRAP(self, "desktopLayout");
- if (!PyArg_ParseTuple(args, ":desktopLayout"))
- return NULL;
- tuple = PyTuple_New(4);
- PyTuple_SET_ITEM(tuple, 0,
- PyInt_FromLong(screen_desktop_layout.orientation));
- PyTuple_SET_ITEM(tuple, 1,
- PyInt_FromLong(screen_desktop_layout.start_corner));
- PyTuple_SET_ITEM(tuple, 2,
- PyInt_FromLong(screen_desktop_layout.rows));
- PyTuple_SET_ITEM(tuple, 3,
- PyInt_FromLong(screen_desktop_layout.columns));
- return tuple;
-}
-
-static PyObject *swrap_desktopNames(ScreenWrap *self, PyObject *args)
-{
- PyObject *list;
- guint s, i;
-
- CHECK_SWRAP(self, "desktopNames");
- if (!PyArg_ParseTuple(args, ":desktopNames"))
- return NULL;
- s = screen_desktop_names->len;
- list = PyList_New(s);
- for (i = 0; i < s; ++i)
- PyList_SET_ITEM(list, i, PyString_FromString
- (g_ptr_array_index(screen_desktop_names, i)));
- return list;
-}
-
-static PyObject *swrap_area(ScreenWrap *self, PyObject *args)
-{
- PyObject * tuple;
- Rect *r;
- guint i;
-
- CHECK_SWRAP(self, "area");
- if (!PyArg_ParseTuple(args, "i:area", &i))
- return NULL;
- r = screen_area(i);
- if (r == NULL) {
- PyErr_SetString(PyExc_IndexError,
- "the requested desktop was not valid");
- return NULL;
- }
- tuple = PyTuple_New(4);
- PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(r->x));
- PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(r->y));
- PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(r->width));
- PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(r->height));
- return tuple;
-}
-
-static PyObject *swrap_strut(ScreenWrap *self, PyObject *args)
-{
- PyObject *tuple;
- Strut *s;
- guint i;
-
- CHECK_SWRAP(self, "strut");
- if (!PyArg_ParseTuple(args, "i:strut", &i))
- return NULL;
- s = screen_strut(i);
- if (s == NULL) {
- PyErr_SetString(PyExc_IndexError,
- "the requested desktop was not valid");
- return NULL;
- }
- tuple = PyTuple_New(4);
- PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(s->left));
- PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(s->top));
- PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(s->right));
- PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(s->bottom));
- return tuple;
-}
-
-static PyObject *swrap_grabKey(ScreenWrap *self, PyObject *args)
-{
- PyObject *item, *tuple;
- GList *keylist = NULL, *it;
- int i, s;
- gboolean grab = FALSE;
-
- CHECK_SWRAP(self, "grabKey");
- if (!PyArg_ParseTuple(args, "O:grabKey", &tuple))
- return NULL;
-
- if (PyTuple_Check(tuple)) {
- s = PyTuple_GET_SIZE(tuple);
- if (s > 0) {
- for (i = 0; i < s; ++i) {
- item = PyTuple_GET_ITEM(tuple, i);
- if (!PyString_Check(item))
- break;
- keylist = g_list_append(keylist,
- g_strdup(PyString_AsString(item)));
- }
- if (i == s)
- grab = kbind_add(keylist);
-
- for (it = keylist; it != NULL; it = it->next)
- g_free(it->data);
- g_list_free(it);
-
- if (grab) {
- Py_INCREF(Py_None);
- return Py_None;
- } else {
- PyErr_SetString(PyExc_ValueError,
- "the key could not be grabbed");
- return NULL;
- }
- }
- }
-
- PyErr_SetString(PyExc_TypeError, "expected a tuple of strings");
- return NULL;
-}
-
-static PyObject *swrap_clearKeyGrabs(ScreenWrap *self, PyObject *args)
-{
- CHECK_SWRAP(self, "clearKeyGrabs");
- if (!PyArg_ParseTuple(args, ":clearKeyGrabs"))
- return NULL;
- kbind_clearall();
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-static PyObject *swrap_grabKeyboard(ScreenWrap *self, PyObject *args)
-{
- int grab;
-
- CHECK_SWRAP(self, "grabKeyboard");
- if (!PyArg_ParseTuple(args, "i:grabKeyboard", &grab))
- return NULL;
- if (!kbind_grab_keyboard(grab)) {
- PyErr_SetString(PyExc_RuntimeError, "failed to grab keyboard");
- return NULL;
- }
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-static PyObject *swrap_grabButton(ScreenWrap *self, PyObject *args)
-{
- char *name;
- char *context_str;
- GQuark context;
-
- CHECK_SWRAP(self, "grabButton");
- if (!PyArg_ParseTuple(args, "ss:grabKey", &name, &context_str))
- return NULL;
-
- context = g_quark_try_string(context_str);
-
- if (!context) {
- PyErr_SetString(PyExc_ValueError, "invalid context");
- return NULL;
- }
-
- if (mbind_add(name, context)) {
- Py_INCREF(Py_None);
- return Py_None;
- } else {
- PyErr_SetString(PyExc_ValueError,
- "the button could not be grabbed");
- return NULL;
- }
-}
-
-static PyObject *swrap_clearButtonGrabs(ScreenWrap *self, PyObject *args)
-{
- CHECK_SWRAP(self, "clearButtonGrabs");
- if (!PyArg_ParseTuple(args, ":clearButtonGrabs"))
- return NULL;
- mbind_clearall();
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-static PyObject *swrap_grabPointer(ScreenWrap *self, PyObject *args)
-{
- int grab;
-
- CHECK_SWRAP(self, "grabPointer");
- if (!PyArg_ParseTuple(args, "i:grabPointer", &grab))
- return NULL;
- if (!mbind_grab_pointer(grab)) {
- PyErr_SetString(PyExc_RuntimeError, "failed to grab pointer");
- return NULL;
- }
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-static PyMethodDef ScreenWrapAttributeMethods[] = {
- {"number", (PyCFunction)swrap_number, METH_VARARGS,
- "Screen.number() -- Returns the number of the screen on the X server on "
- "which this Openbox instance is running."},
- {"rootWindow", (PyCFunction)swrap_rootWindow, METH_VARARGS,
- "Screen.rootWindow() -- Returns the window id of the root window."},
- {"state", (PyCFunction)swrap_state, METH_VARARGS,
- "Screen.state() -- Returns the running state of Openbox. One of the "
- "ob.State_ constants."},
- {"numDesktops", (PyCFunction)swrap_numDesktops, METH_VARARGS,
- "Screen.numDesktops() -- Returns the number of desktops available."},
- {"desktop", (PyCFunction)swrap_desktop, METH_VARARGS,
- "Screen.desktop() -- Returns the currently visible desktop."},
- {"physicalSize", (PyCFunction)swrap_physicalSize, METH_VARARGS,
- "Screen.physicalSize() -- Returns the physical size (in pixels) of the "
- "display in a tuple. The tuple is formatted as (width, height)."},
- {"showingDesktop", (PyCFunction)swrap_showingDesktop, METH_VARARGS,
- "Screen.showingDesktop() -- Returns if in showing-the-desktop mode or "
- "not."},
- {"desktopNames", (PyCFunction)swrap_desktopNames, METH_VARARGS,
- "Screen.desktopNames() -- Returns a list of the names of all the "
- "desktops, and possibly for desktops beyond those. The names are encoded "
- "as UTF-8."},
- {"desktopLayout", (PyCFunction)swrap_desktopLayout, METH_VARARGS,
- "Screen.desktopLayout() -- Returns the layout of the desktops, as "
- "specified by a compliant pager, in a tuple. The format of the tuple is "
- "(orientation, corner, rows, columns). Where, orientation is one of the "
- "ob.Orientation_ constants, corner is one of the ob.Corner_ constants, "
- "and rows and columns specify the size of the layout. The rows and "
- "columns will always include all the desktops."},
- {"area", (PyCFunction)swrap_area, METH_VARARGS,
- "Screen.area(d) -- Returns the usuable area on the Screen for a desktop, "
- "in the form of a tuple. The tuples format is (x, y, width, height). The "
- "desktop must be in the range of desktops on the screen, or 0xffffffff "
- "to get a combined area for 'all desktops'."},
- {"strut", (PyCFunction)swrap_area, METH_VARARGS,
- "Screen.strut(d) -- Returns the combined strut of all clients on a "
- "desktop, in the form of a tuple. The tuples format is "
- "(left, top, right, bottom). The desktop must be in the range of "
- "desktops on the screen, or 0xffffffff to get a combined strut for "
- "'all desktops'."},
- {"grabKey", (PyCFunction)swrap_grabKey, METH_VARARGS,
- "Screen.grabKey(('Mod1-C-a', 'd')) -- Grabs a key chain so that key "
- "events for it will occur. The argument must be a tuple of one or "
- "more elements. Each key element is made up of "
- "Modifier-Modifier-...-Key, where Modifier is one of Mod1, Mod2, "
- "Mod3, Mod4, Mod5, S (for Shift), or C (for Control)."},
- {"clearKeyGrabs", (PyCFunction)swrap_clearKeyGrabs, METH_VARARGS,
- "Screen.clearKeyGrabs() -- Removes all key grabs that have been done "
- "with grabKey()."},
- {"grabKeyboard", (PyCFunction)swrap_grabKeyboard, METH_VARARGS,
- "Screen.grabKeyboard(grab) -- Grabs or ungrabs the entire keyboard. When "
- "the keyboard is grabbed, all key presses will be sent to the "
- "hooks.keyboard hook. (grabbed keys will go to the hooks.events hook "
- "too. "},
- {"grabButton", (PyCFunction)swrap_grabButton, METH_VARARGS,
- "Screen.grabButton('C-1', \"frame\") -- Grabs a pointer button "
- "for the given context. The context must be one of the ob.Context_* "
- "constants. The button definition is made up of "
- "Modifier-Modifier-...-Button, where Modifier is one of Mod1, Mod2, "
- "Mod3, Mod4, Mod5, S (for Shift), or C (for Control)."},
- {"clearButtonGrabs", (PyCFunction)swrap_clearButtonGrabs, METH_VARARGS,
- "Screen.clearButtonGrabs() -- Removes all button grabs that have been "
- "done with grabButton()."},
- {"grabPointer", (PyCFunction)swrap_grabPointer, METH_VARARGS,
- "grabPointer(grab) -- Grabs or ungrabs the pointer device. When the "
- "pointer is grabbed, all pointer events will be sent to the "
- "hooks.pointer hook. (grabbed buttons will NOT go to the hooks.events "
- "hook while the pointer is grabbed)."},
- {NULL, NULL, 0, NULL}
-};
-
-/***************************************************************************
-
- Type methods/struct
-
- ***************************************************************************/
-
-static PyObject *swrap_getattr(ScreenWrap *self, char *name)
-{
- CHECK_SWRAP(self, "getattr");
- return Py_FindMethod(ScreenWrapAttributeMethods, (PyObject*)self, name);
-}
-
-static void swrap_dealloc(ScreenWrap *self)
-{
- PyObject_Del((PyObject*) self);
-}
-
-static PyTypeObject ScreenWrapType = {
- PyObject_HEAD_INIT(NULL)
- 0,
- "Screen",
- sizeof(ScreenWrap),
- 0,
- (destructor) swrap_dealloc, /*tp_dealloc*/
- 0, /*tp_print*/
- (getattrfunc) swrap_getattr, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_compare*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash */
-};
-
-/***************************************************************************
-
- External methods
-
- ***************************************************************************/
-
-void screenwrap_startup()
-{
- PyObject *ob, *obdict;
- ScreenWrap *swrap;
-
- ScreenWrapType.ob_type = &PyType_Type;
- ScreenWrapType.tp_doc = "Wraps information and functionality global to an "
- "instance of Openbox.";
- PyType_Ready(&ScreenWrapType);
- swrap = PyObject_New(ScreenWrap, &ScreenWrapType);
-
- /* get the ob module/dict */
- ob = PyImport_ImportModule("ob"); /* new */
- g_assert(ob != NULL);
- obdict = PyModule_GetDict(ob); /* borrowed */
- g_assert(obdict != NULL);
-
- PyDict_SetItemString(obdict, "Screen", (PyObject*)swrap);
- Py_DECREF(swrap);
- Py_DECREF(ob);
-}
-
-void screenwrap_shutdown()
-{
-}
-
-
+++ /dev/null
-#ifndef __screenwrap_h
-#define __screenwrap_h
-
-#include <Python.h>
-
-/* ScreenWrap is a PyObject */
-typedef struct ScreenWrap {
- PyObject_HEAD
-} ScreenWrap;
-
-void screenwrap_startup();
-void screenwrap_shutdown();
-
-#endif
+++ /dev/null
-#include "openbox.h"
-#include "prop.h"
-#include "focus.h"
-#include "client.h"
-#include "frame.h"
-#include <glib.h>
-
-GList *stacking_list = NULL;
-
-void stacking_set_list()
-{
- Window *windows, *win_it;
- GList *it;
- guint size = g_list_length(stacking_list);
-
- /* create an array of the window ids (from bottom to top,
- reverse order!) */
- if (size > 0) {
- windows = g_new(Window, size);
- win_it = windows;
- for (it = g_list_last(stacking_list); it; it = it->prev, ++win_it)
- *win_it = ((Client*)it->data)->window;
- } else
- windows = NULL;
-
- PROP_SET32A(ob_root, net_client_list_stacking, window, windows, size);
-
- if (windows)
- g_free(windows);
-}
-
-void stacking_raise(Client *client)
-{
- Window wins[2]; /* only ever restack 2 windows. */
- GList *it;
- Client *m;
-
- g_assert(stacking_list != NULL); /* this would be bad */
-
- m = client_find_modal_child(client);
- /* if we have a modal child, raise it instead, we'll go along tho later */
- if (m) stacking_raise(m);
-
- /* remove the client before looking so we can't run into ourselves */
- stacking_list = g_list_remove(stacking_list, client);
-
- /* the stacking list is from highest to lowest */
- it = stacking_list;
- while (it) {
- Client *c = it->data;
- if (client->layer >= c->layer && m != c)
- break;
- it = it->next;
- }
-
- /*
- if our new position is the top, we want to stack under the focus_backup.
- otherwise, we want to stack under the previous window in the stack.
- */
- if (it == stacking_list)
- wins[0] = focus_backup;
- else if (it != NULL)
- wins[0] = ((Client*)it->prev->data)->frame->window;
- else
- wins[0] = ((Client*)g_list_last(stacking_list)->data)->frame->window;
- wins[1] = client->frame->window;
-
- stacking_list = g_list_insert_before(stacking_list, it, client);
-
- XRestackWindows(ob_display, wins, 2);
-
- stacking_set_list();
-}
-
-void stacking_lower(Client *client)
-{
- Window wins[2]; /* only ever restack 2 windows. */
- GList *it;
-
- g_assert(stacking_list != NULL); /* this would be bad */
-
- it = g_list_last(stacking_list);
-
- if (client->modal && client->transient_for) {
- /* don't let a modal window lower below its transient_for */
- it = g_list_find(stacking_list, client->transient_for);
- g_assert(it != NULL);
-
- wins[0] = (it == stacking_list ? focus_backup :
- ((Client*)it->prev->data)->frame->window);
- wins[1] = client->frame->window;
- if (wins[0] == wins[1]) return; /* already right above the window */
-
- stacking_list = g_list_remove(stacking_list, client);
- stacking_list = g_list_insert_before(stacking_list, it, client);
- } else {
- while (it != stacking_list) {
- Client *c = it->data;
- if (client->layer >= c->layer)
- break;
- it = it->prev;
- }
- if (it->data == client) return; /* already the bottom, return */
-
- wins[0] = ((Client*)it->data)->frame->window;
- wins[1] = client->frame->window;
-
- stacking_list = g_list_remove(stacking_list, client);
- stacking_list = g_list_insert_before(stacking_list,
- it->next, client);
- }
-
- XRestackWindows(ob_display, wins, 2);
- stacking_set_list();
-}
-
+++ /dev/null
-#ifndef __stacking_h
-#define __stacking_h
-
-#include <glib.h>
-
-struct Client;
-
-extern GList *stacking_list;
-
-/*! Sets the client stacking list on the root window from the
- stacking_clientlist */
-void stacking_set_list();
-
-/*! Raises a client window above all others in its stacking layer
- raiseWindow has a couple of constraints that lowerWindow does not.<br>
- 1) raiseWindow can be called after changing a Client's stack layer, and
- the list will be reorganized properly.<br>
- 2) raiseWindow guarantees that XRestackWindows() will <i>always</i> be
- called for the specified client.
-*/
-void stacking_raise(struct Client *client);
-
-/*! Lowers a client window below all others in its stacking layer */
-void stacking_lower(struct Client *client);
-
-#endif
+++ /dev/null
-#include "openbox.h"
-#include <glib.h>
-#include <X11/Xlib.h>
-
-static gboolean xerror_ignore = FALSE;
-
-int xerror_handler(Display *d, XErrorEvent *e)
-{
-#ifdef DEBUG
- if (!xerror_ignore) {
- char errtxt[128];
-
- /*if (e->error_code != BadWindow) */
- {
- XGetErrorText(d, e->error_code, errtxt, 127);
- if (e->error_code == BadWindow)
- g_warning("X Error: %s", errtxt);
- else
- g_error("X Error: %s", errtxt);
- }
- }
-#else
- (void)d; (void)e;
-#endif
- return 0;
-}
-
-void xerror_set_ignore(gboolean ignore)
-{
- XSync(ob_display, FALSE);
- xerror_ignore = ignore;
-}
+++ /dev/null
-#ifndef __xerror_h
-#define __xerror_h
-
-#include <X11/Xlib.h>
-#include <glib.h>
-
-int xerror_handler(Display *, XErrorEvent *);
-
-void xerror_set_ignore(gboolean ignore);
-
-#endif