all repos — openbox @ a648c05a7a2608e7e909317f5afe8427a0ea0d68

openbox fork - make it a bit more like ryudo

kill the c dir
Dana Jansens danakj@orodu.net
commit

a648c05a7a2608e7e909317f5afe8427a0ea0d68

parent

474f689132d906a553bdc695d3c179652cbe8c53

40 files changed, 0 insertions(+), 8241 deletions(-)

jump to
D c/.cvsignore

@@ -1,5 +0,0 @@

-ob3 -Makefile.in -.libs -.deps -Makefile
D c/Makefile.am

@@ -1,34 +0,0 @@

-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 .\#*
D c/client.c

@@ -1,1869 +0,0 @@

-#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); -}
D c/client.h

@@ -1,401 +0,0 @@

-#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
D c/clientwrap.c

@@ -1,792 +0,0 @@

-#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; -}
D c/clientwrap.h

@@ -1,19 +0,0 @@

-#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
D c/event.c

@@ -1,593 +0,0 @@

-#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); - } -}
D c/event.h

@@ -1,12 +0,0 @@

-#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
D c/eventdata.c

@@ -1,433 +0,0 @@

-#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; -}
D c/eventdata.h

@@ -1,74 +0,0 @@

-#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
D c/extensions.c

@@ -1,34 +0,0 @@

-#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 -}
D c/extensions.h

@@ -1,33 +0,0 @@

-#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
D c/focus.c

@@ -1,56 +0,0 @@

-#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); -}
D c/focus.h

@@ -1,20 +0,0 @@

-#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
D c/frame.c

@@ -1,533 +0,0 @@

-#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"); -}
D c/frame.h

@@ -1,101 +0,0 @@

-#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
D c/geom.h

@@ -1,53 +0,0 @@

-#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
D c/gettext.h

@@ -1,73 +0,0 @@

-/* 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 */
D c/hooks.c

@@ -1,285 +0,0 @@

-#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(); -}
D c/hooks.h

@@ -1,23 +0,0 @@

-#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
D c/kbind.c

@@ -1,354 +0,0 @@

-#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; -}
D c/kbind.h

@@ -1,23 +0,0 @@

-#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
D c/mbind.c

@@ -1,220 +0,0 @@

-#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; -}
D c/mbind.h

@@ -1,21 +0,0 @@

-#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
D c/obexport.c

@@ -1,116 +0,0 @@

-#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() -{ -}
D c/obexport.h

@@ -1,74 +0,0 @@

-#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
D c/openbox.c

@@ -1,203 +0,0 @@

-#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); - } -}
D c/openbox.h

@@ -1,35 +0,0 @@

-#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
D c/prop.c

@@ -1,271 +0,0 @@

-#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); -}
D c/prop.h

@@ -1,202 +0,0 @@

-#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
D c/python.c

@@ -1,55 +0,0 @@

-#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; -}
D c/python.h

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

-#ifndef __python_h -#define __python_h - -void python_startup(); -void python_shutdown(); - -/*! Import a python module */ -gboolean python_import(char *module); - -#endif
D c/screen.c

@@ -1,516 +0,0 @@

-#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]; -}
D c/screen.h

@@ -1,66 +0,0 @@

-#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
D c/screenwrap.c

@@ -1,433 +0,0 @@

-#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() -{ -} - -
D c/screenwrap.h

@@ -1,14 +0,0 @@

-#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
D c/stacking.c

@@ -1,116 +0,0 @@

-#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(); -} -
D c/stacking.h

@@ -1,26 +0,0 @@

-#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
D c/xerror.c

@@ -1,32 +0,0 @@

-#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; -}
D c/xerror.h

@@ -1,11 +0,0 @@

-#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