openbox/actions/execute.c \
openbox/actions/exit.c \
openbox/actions/focus.c \
+ openbox/actions/focusfallback.c \
openbox/actions/focustobottom.c \
openbox/actions/fullscreen.c \
openbox/actions/growtoedge.c \
openbox/actions/if.c \
openbox/actions/kill.c \
openbox/actions/layer.c \
+ openbox/actions/lock.c \
openbox/actions/lower.c \
openbox/actions/maximize.c \
openbox/actions/move.c \
openbox/actions/omnipresent.c \
openbox/actions/raise.c \
openbox/actions/raiselower.c \
+ openbox/actions/raisetemp.c \
openbox/actions/reconfigure.c \
openbox/actions/resize.c \
openbox/actions/resizerelative.c \
openbox/actions/restart.c \
+ openbox/actions/sendkeyevent.c \
openbox/actions/shade.c \
openbox/actions/shadelowerraise.c \
openbox/actions/showdesktop.c \
openbox/debug.h \
openbox/dock.c \
openbox/dock.h \
+ openbox/edges.c \
+ openbox/edges.h \
openbox/event.c \
openbox/event.h \
openbox/focus.c \
pango_font_description_set_family(out->font_desc, name);
pango_font_description_set_weight(out->font_desc, pweight);
pango_font_description_set_style(out->font_desc, pstyle);
- pango_font_description_set_size(out->font_desc, size * PANGO_SCALE);
+ if (size < 0)
+ pango_font_description_set_absolute_size(out->font_desc, -size * PANGO_SCALE);
+ else
+ pango_font_description_set_size(out->font_desc, size * PANGO_SCALE);
/* setup the layout */
pango_layout_set_font_description(out->layout, out->font_desc);
rect.width = (rect.width + PANGO_SCALE - 1) / PANGO_SCALE;
rect.height = (rect.height + PANGO_SCALE - 1) / PANGO_SCALE;
#endif
- *x = rect.width + ABS(shadow_x) + 4 /* we put a 2 px edge on each side */;
- *y = rect.height + ABS(shadow_y);
+ *x = rect.width + /* ABS(shadow_x) +*/ 4 /* we put a 2 px edge on each side */;
+ *y = rect.height /*+ ABS(shadow_y) */;
}
RrSize *RrFontMeasureString(const RrFont *f, const gchar *str,
gint RrFontHeight(const RrFont *f, gint shadow_y)
{
- return (f->ascent + f->descent) / PANGO_SCALE + ABS(shadow_y);
+ return (f->ascent + f->descent) / PANGO_SCALE + 0-1;//ABS(shadow_y);
}
static inline int font_calculate_baseline(RrFont *f, gint height)
--- /dev/null
+/* GIMP RGBA C-Source image dump (icon-newmika.c) */
+
+#define OB_DEFAULT_ICON_WIDTH (48)
+#define OB_DEFAULT_ICON_HEIGHT (48)
+#define OB_DEFAULT_ICON_BYTES_PER_PIXEL (4) /* 3:RGB, 4:RGBA */
+#define OB_DEFAULT_ICON_COMMENT \
+ "To recreate this file, save an image as \"C-Source\" in The Gimp. Use \"ob_default_icon\" as the Prefixed Name. Enable Glib Types. Enable Save Alpha Channel. Enable Use Macros instead of Struct."
+#define OB_DEFAULT_ICON_PIXEL_DATA ((guint8*) OB_DEFAULT_ICON_pixel_data)
+static const guint8 OB_DEFAULT_ICON_pixel_data[48 * 48 * 4 + 1] =
+("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\40J\207\15\40J\207\23\40J\207"
+ "\23\40J\207\23\40J\207\23\40J\207\23\40J\207\23\40J\207\23\40J\207\23\40J"
+ "\207\23\40J\207\23\40J\207\23\40J\207\23\40J\207\23\40J\207\23\40J\207\23"
+ "\40J\207\23\40J\207\23\40J\207\23\40J\207\23\40J\207\23\40J\207\23\40J\207"
+ "\23\40J\207\23\40J\207\23\40J\207\23\40J\207\23\40J\207\23\40J\207\23\40J"
+ "\207\23\40J\207\23\40J\207\23\40J\207\23\40J\207\23\40J\207\23\40J\207\23"
+ "\40J\207\23\40J\207\23\40J\207\23\40J\207\23\40J\207\23\40J\207\23\40J\207"
+ "\23\40J\207\15\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0'P\213\267'Q\214\275'Q\214\275"
+ "'Q\214\275'Q\214\275'Q\214\275'Q\214\275'Q\214\275'Q\214\275'Q\214\275'Q\214"
+ "\275'Q\214\275'Q\214\275'Q\214\275'Q\214\275'Q\214\275'Q\214\275'Q\214\275"
+ "'Q\214\275'Q\214\275'Q\214\275'Q\214\275'Q\214\275(R\215\275'Q\214\275'Q\214"
+ "\275'Q\214\275'Q\214\275'Q\214\275'Q\214\275'Q\214\275'Q\214\275'Q\214\275"
+ "'Q\214\275'Q\214\275'Q\214\275'Q\214\275'Q\214\275'Q\214\275'Q\214\275(R\215"
+ "\275(R\215\275(R\215\275&P\213\267\40J\207\20\0\0\0\0\0\0\0\0\40J\207+Y{\252"
+ "\377\216\253\320\377\204\243\314\377\204\243\314\377\204\243\314\377\204\243"
+ "\314\377\204\243\314\377\204\243\314\377\204\243\314\377\204\243\314\377\204"
+ "\243\314\377\204\243\314\377\204\243\314\377\204\243\314\377\204\243\314\377"
+ "\204\243\314\377\204\243\314\377\204\243\314\377\204\243\314\377\204\243\314"
+ "\377\204\243\314\377\204\243\314\377\204\243\314\377\204\243\314\377\204\243"
+ "\314\377\204\243\314\377\203\243\314\377\203\243\313\377\203\243\313\377\203"
+ "\243\313\377\203\242\313\377\202\242\313\377\202\242\313\377\202\241\313\377"
+ "\201\241\312\377\201\241\312\377\201\240\312\377\201\240\312\377\200\240\312"
+ "\377\200\240\312\377\200\240\312\377\200\240\312\377\211\247\316\377Jn\241"
+ "\377\40J\207+\0\0\0\0\0\0\0\0\40J\207+Wy\251\377]\207\275\377>o\260\377>o"
+ "\260\377>o\260\377>o\260\377>o\260\377>o\260\377>o\260\377>o\260\377>o\260"
+ "\377>o\260\377>o\260\377>o\260\377>o\260\377>o\260\377>o\260\377>o\260\377"
+ ">o\260\377>o\260\377>o\260\377>o\260\377>o\260\377>o\260\377>o\260\377>o\260"
+ "\377>o\260\377>o\260\377>o\260\377>o\260\377=o\260\377=o\260\377=o\260\377"
+ "=o\260\377=o\260\377=o\260\377=o\260\377=o\260\377=o\260\377=o\260\377=o\260"
+ "\377=o\260\377_\210\275\377Hm\241\377\40J\207+\0\0\0\0\0\0\0\0\40J\207+Tw"
+ "\251\377]\207\276\377?r\263\377?r\263\377?r\263\377?r\263\377?r\263\377?r"
+ "\263\377?r\263\377?r\263\377?r\263\377?r\263\377?r\263\377?r\263\377?r\263"
+ "\377?r\263\377?r\263\377?r\263\377?r\263\377?r\263\377?r\263\377?r\263\377"
+ "?r\263\377?r\263\377?r\263\377?r\263\377?r\263\377?r\263\377?r\263\377?r\263"
+ "\377?r\263\377?r\263\377?r\263\377?r\263\377?r\263\377?r\263\377?r\263\377"
+ "?r\263\377?r\263\377?r\263\377?r\263\377?r\263\377]\210\277\377Fl\241\377"
+ "\40J\207+\0\0\0\0\0\0\0\0\40J\207+Rv\250\377\\\210\300\377At\265\377At\265"
+ "\377At\265\377At\265\377At\265\377At\265\377At\265\377At\265\377At\265\377"
+ "At\265\377At\265\377At\265\377At\265\377At\265\377At\265\377At\265\377At\265"
+ "\377At\265\377At\265\377At\265\377At\265\377At\265\377At\265\377At\265\377"
+ "At\265\377At\265\377At\265\377At\265\377At\265\377At\265\377At\265\377At\265"
+ "\377At\265\377At\265\377At\265\377At\265\377At\265\377At\265\377At\265\377"
+ "At\265\377\\\210\300\377Dj\240\377\40J\207+\0\0\0\0\0\0\0\0\40J\207+Ot\247"
+ "\377\\\211\302\377Dw\271\377Dw\271\377Dw\271\377Dw\271\377Dw\271\377Dw\271"
+ "\377Dw\271\377Dw\271\377Dw\271\377Dw\271\377Dw\271\377Dw\271\377Dw\271\377"
+ "Dw\271\377Dw\271\377Dw\271\377Dw\271\377Dw\271\377Dw\271\377Dw\271\377Dw\271"
+ "\377Dw\271\377Dw\271\377Dw\271\377Dw\271\377Dw\271\377Dw\271\377Dw\271\377"
+ "Dw\271\377Dw\271\377Dw\271\377Dw\271\377Dw\271\377Dw\271\377Dw\271\377Dw\271"
+ "\377Dw\271\377Dw\271\377Dw\271\377Dw\271\377[\211\302\377Bi\240\377\40J\207"
+ "+\0\0\0\0\0\0\0\0\40J\207+Ls\247\377\\\211\303\377Fy\273\377Fy\273\377Fy\273"
+ "\377Fy\273\377Fy\273\377Fy\273\377Fy\273\377Fy\273\377Fy\273\377Fy\273\377"
+ "Fy\273\377Fy\273\377Fy\273\377Fy\273\377Fy\273\377Fy\273\377Fy\273\377Fy\273"
+ "\377Fy\273\377Fy\273\377Fy\273\377Fy\273\377Fy\273\377Fy\273\377Fy\273\377"
+ "Fy\273\377Fy\273\377Fy\273\377Fy\273\377Fy\273\377Fy\273\377Fy\273\377Fy\273"
+ "\377Fy\273\377Fy\273\377Fy\273\377Fy\273\377Fy\273\377Fy\273\377Fy\273\377"
+ "\\\211\303\377Ah\240\377\40J\207+\0\0\0\0\0\0\0\0\40J\207+Jq\246\377\\\212"
+ "\305\377I}\277\377I}\277\377I}\277\377I}\277\377I}\277\377I}\277\377I}\277"
+ "\377I}\277\377I}\277\377I}\277\377I}\277\377I}\277\377I}\277\377I}\277\377"
+ "I}\277\377I}\277\377I}\277\377I}\277\377I}\277\377I}\277\377I}\277\377I}\277"
+ "\377I}\277\377I}\277\377I}\277\377I}\277\377I}\277\377I}\277\377I}\277\377"
+ "I}\277\377I}\277\377I}\277\377I}\277\377I}\277\377I}\277\377I}\277\377I}\277"
+ "\377I}\277\377I}\277\377I}\277\377[\212\305\377?g\237\377\40J\207+\0\0\0\0"
+ "\0\0\0\0\40J\207+Jq\246\377\\\212\305\377I}\277\377I}\277\377I}\277\377I}"
+ "\277\377I}\277\377I}\277\377I}\277\377I}\277\377I}\277\377I}\277\377I}\277"
+ "\377I}\277\377I}\277\377I}\277\377I}\277\377I}\277\377I}\277\377I}\277\377"
+ "I}\277\377I}\277\377I}\277\377J~\300\377K\177\301\377K\177\301\377K\177\301"
+ "\377K\177\301\377K\177\301\377K\177\301\377K\177\301\377K\177\301\377K\177"
+ "\301\377K\177\301\377K\177\301\377K\177\301\377K\177\301\377K\177\301\377"
+ "K\177\301\377K\177\301\377K\177\301\377K\177\301\377Z\212\307\377=f\237\377"
+ "\40J\207+\0\0\0\0\0\0\0\0\40J\207+Ip\247\377\\\213\307\377J\177\301\377J\177"
+ "\301\377J\177\301\377J\177\301\377J\177\301\377J\177\301\377J\177\301\377"
+ "J\177\301\377J\177\301\377J\177\301\377J\177\301\377J\177\301\377J\177\301"
+ "\377J\177\301\377J\177\301\377J\177\301\377J\177\301\377J\177\301\377J\177"
+ "\301\377J\177\301\377J\177\301\377K\200\302\377K\200\302\377K\200\302\377"
+ "K\200\302\377K\200\302\377K\200\302\377K\200\302\377K\200\302\377K\200\302"
+ "\377K\200\302\377K\200\302\377K\200\302\377K\200\302\377K\200\302\377K\200"
+ "\302\377K\200\302\377K\200\302\377K\200\302\377K\200\302\377Z\212\307\377"
+ "=f\237\377\40J\207+\0\0\0\0\0\0\0\0\40J\207+Ho\247\377e\223\314\377Z\213\310"
+ "\377Z\213\310\377Z\213\310\377Z\213\310\377Z\213\307\377Z\213\307\377Z\213"
+ "\307\377Z\213\307\377Z\213\307\377Y\212\307\377Y\212\307\377Y\212\307\377"
+ "Y\212\307\377Y\212\307\377X\212\307\377X\212\307\377X\212\307\377X\211\307"
+ "\377X\212\307\377X\212\307\377X\211\307\377X\211\307\377X\211\307\377X\211"
+ "\307\377X\211\307\377X\211\307\377X\211\307\377X\211\307\377X\211\307\377"
+ "X\211\307\377W\211\307\377W\211\307\377W\211\307\377W\211\307\377W\211\307"
+ "\377W\211\307\377V\211\307\377V\211\307\377V\210\307\377V\210\307\377`\217"
+ "\312\377<e\237\377\40J\207+\0\0\0\0\0\0\0\0\40J\207+<b\231\377i\212\267\377"
+ "i\211\266\377i\211\266\377i\211\266\377i\211\266\377i\211\266\377h\211\266"
+ "\377h\211\266\377h\211\266\377h\211\266\377h\211\266\377h\211\266\377h\211"
+ "\266\377g\211\266\377g\211\266\377g\211\266\377g\211\266\377g\210\266\377"
+ "g\210\266\377g\211\266\377g\211\266\377g\210\266\377g\210\266\377g\210\265"
+ "\377g\210\265\377g\210\265\377g\210\265\377g\210\265\377g\210\265\377g\210"
+ "\265\377g\210\265\377g\210\265\377f\210\265\377f\210\264\377f\210\264\377"
+ "f\210\264\377f\210\264\377f\210\264\377f\210\264\377f\210\264\377f\207\264"
+ "\377f\207\264\3778^\226\377\40J\207+\0\0\0\0\0\0\0\0\40J\207+b\177\251\377"
+ "\340\344\351\244\337\342\350\244\337\342\350\244\336\342\350\244\336\342\347"
+ "\244\336\342\347\244\336\342\347\244\336\342\347\244\335\341\347\244\335\341"
+ "\346\244\335\341\346\244\335\341\346\244\335\341\346\244\335\341\346\244\335"
+ "\341\346\244\335\341\346\244\335\341\346\244\334\340\346\244\334\340\346\244"
+ "\335\341\346\244\335\341\346\244\334\340\346\244\334\340\346\244\334\340\345"
+ "\244\334\340\345\244\334\340\345\244\333\337\345\244\333\337\345\244\333\337"
+ "\344\244\333\337\344\244\333\337\344\244\333\336\344\244\332\336\344\244\332"
+ "\336\344\244\332\336\344\244\332\336\343\244\332\336\343\244\332\336\343\244"
+ "\332\336\343\244\332\336\343\244\332\336\343\244\333\337\345\244a}\247\377"
+ "\40J\207+\0\0\0\0\0\0\0\0\40J\207+h\204\254\377\355\355\355\244\351\351\351"
+ "\244\351\351\352\244\351\351\351\244\351\351\351\244\351\351\351\244\351\351"
+ "\350\244\351\350\350\244\351\351\351\244\350\350\350\244\350\350\350\244\350"
+ "\350\350\244\350\350\350\244\350\350\350\244\350\350\350\244\350\350\350\244"
+ "\350\347\350\244\350\347\347\244\347\347\347\244\347\347\347\244\347\347\347"
+ "\244\347\347\347\244\347\347\347\244\347\347\347\244\346\347\347\244\347\346"
+ "\347\244\347\346\347\244\346\346\347\244\346\346\346\244\346\346\346\244\346"
+ "\346\346\244\346\346\346\244\346\346\346\244\346\346\346\244\346\346\346\244"
+ "\346\345\345\244\345\345\346\244\345\346\345\244\345\346\345\244\345\346\345"
+ "\244\345\345\345\244\351\351\351\244g\202\252\377\40J\207+\0\0\0\0\0\0\0\0"
+ "\40J\207+h\203\253\377\354\354\354\244\350\350\350\244\347\350\350\244\347"
+ "\347\350\244\347\347\350\244\347\347\347\244\347\347\347\244\347\347\347\244"
+ "\347\347\347\244\347\346\347\244\347\346\346\244\347\346\346\244\347\347\347"
+ "\244\346\346\346\244\346\346\346\244\346\346\346\244\346\346\346\244\346\346"
+ "\346\244\346\346\346\244\345\345\346\244\345\345\345\244\345\345\346\244\345"
+ "\346\346\244\345\345\345\244\345\345\345\244\345\345\345\244\345\345\345\244"
+ "\345\345\345\244\345\344\344\244\345\345\344\244\345\345\345\244\345\344\344"
+ "\244\344\344\344\244\344\344\344\244\344\344\344\244\344\344\344\244\343\344"
+ "\344\244\343\344\344\244\344\344\344\244\344\344\343\244\344\343\343\244\350"
+ "\350\350\244g\202\252\377\40J\207+\0\0\0\0\0\0\0\0\40J\207+h\203\253\377\353"
+ "\352\352\244\346\346\346\244\346\345\345\244\345\346\346\244\345\346\345\244"
+ "\345\345\345\244\345\345\345\244\345\345\345\244\345\345\346\244\345\345\345"
+ "\244\345\345\345\244\345\345\345\244\345\345\345\244\345\345\345\244\345\345"
+ "\345\244\344\345\345\244\344\344\344\244\344\345\344\244\344\344\344\244\344"
+ "\344\344\244\344\344\344\244\344\344\344\244\344\344\344\244\343\343\344\244"
+ "\343\343\343\244\344\343\343\244\343\343\343\244\343\343\343\244\343\343\343"
+ "\244\343\343\343\244\343\343\343\244\342\343\343\244\342\343\343\244\343\342"
+ "\343\244\343\342\342\244\342\342\342\244\342\342\342\244\342\342\342\244\342"
+ "\342\342\244\342\342\342\244\342\342\342\244\346\346\346\244g\202\252\377"
+ "\40J\207+\0\0\0\0\0\0\0\0\40J\207+h\203\253\377\351\351\351\244\345\344\344"
+ "\244\344\344\344\244\344\344\344\244\344\344\344\244\344\344\344\244\343\344"
+ "\344\244\343\344\344\244\343\343\344\244\343\343\343\244\343\343\343\244\343"
+ "\343\343\244\343\343\343\244\343\343\343\244\343\343\343\244\343\343\343\244"
+ "\343\343\343\244\343\343\343\244\343\342\342\244\342\342\342\244\342\342\342"
+ "\244\342\342\342\244\342\342\342\244\342\341\342\244\342\342\342\244\342\342"
+ "\341\244\342\341\342\244\341\341\342\244\341\341\341\244\341\341\341\244\341"
+ "\341\341\244\341\341\341\244\341\341\341\244\341\340\341\244\341\341\341\244"
+ "\340\341\341\244\341\341\341\244\340\340\340\244\340\340\340\244\340\340\340"
+ "\244\340\340\340\244\346\345\346\244g\202\252\377\40J\207+\0\0\0\0\0\0\0\0"
+ "\40J\207+h\203\253\377\350\350\350\244\342\342\343\244\342\342\342\244\342"
+ "\342\342\244\342\342\342\244\342\342\342\244\342\342\342\244\342\342\342\244"
+ "\342\342\342\244\342\342\341\244\342\341\342\244\341\341\341\244\341\341\341"
+ "\244\341\341\341\244\341\341\341\244\341\341\341\244\341\341\341\244\341\341"
+ "\341\244\340\341\341\244\341\340\340\244\341\340\340\244\340\340\340\244\340"
+ "\340\340\244\340\340\340\244\340\340\340\244\340\340\340\244\340\340\340\244"
+ "\340\340\337\244\340\340\340\244\337\337\337\244\340\340\337\244\337\337\337"
+ "\244\337\337\337\244\337\337\337\244\337\337\337\244\337\337\337\244\337\337"
+ "\337\244\337\337\337\244\337\337\336\244\336\337\336\244\336\336\336\244\344"
+ "\344\344\244g\202\252\377\40J\207+\0\0\0\0\0\0\0\0\40J\207+h\203\253\377\347"
+ "\347\347\244\341\341\341\244\341\341\341\244\341\341\341\244\341\341\341\244"
+ "\341\341\341\244\340\341\340\244\340\340\340\244\340\340\340\244\340\340\337"
+ "\244\340\340\340\244\340\340\340\244\340\340\337\244\337\340\337\244\337\340"
+ "\337\244\337\337\340\244\337\337\337\244\337\337\337\244\337\337\337\244\337"
+ "\337\337\244\337\337\337\244\337\337\337\244\336\337\337\244\336\337\336\244"
+ "\337\336\336\244\336\336\336\244\336\336\336\244\336\336\336\244\336\336\336"
+ "\244\336\336\336\244\336\336\336\244\336\336\335\244\336\335\335\244\336\335"
+ "\335\244\336\335\335\244\335\335\335\244\335\335\335\244\335\335\335\244\335"
+ "\335\335\244\335\335\335\244\335\335\335\244\343\343\343\244g\202\252\377"
+ "\40J\207+\0\0\0\0\0\0\0\0\40J\207+h\203\253\377\345\346\346\244\337\337\340"
+ "\244\340\337\337\244\337\337\337\244\337\337\337\244\337\337\337\244\337\337"
+ "\337\244\337\337\336\244\337\336\336\244\336\336\337\244\336\336\337\244\336"
+ "\336\336\244\336\336\336\244\336\336\336\244\336\336\335\244\336\336\336\244"
+ "\336\335\336\244\336\336\336\244\335\335\336\244\335\335\335\244\335\335\335"
+ "\244\335\335\335\244\335\335\335\244\335\335\335\244\335\335\335\244\335\335"
+ "\334\244\334\335\335\244\334\334\334\244\334\334\334\244\334\334\334\244\334"
+ "\334\334\244\334\334\334\244\334\334\334\244\334\334\334\244\334\334\334\244"
+ "\334\333\334\244\333\333\333\244\333\333\333\244\333\333\333\244\333\333\333"
+ "\244\333\333\333\244\341\341\342\244f\202\252\377\40J\207+\0\0\0\0\0\0\0\0"
+ "\40J\207+h\203\253\377\345\345\345\244\336\335\336\244\336\335\335\244\335"
+ "\335\335\244\336\335\335\244\335\335\335\244\335\335\335\244\335\335\335\244"
+ "\335\334\335\244\335\335\335\244\335\335\335\244\334\335\334\244\334\334\335"
+ "\244\334\335\334\244\334\334\334\244\334\334\334\244\334\334\334\244\334\334"
+ "\334\244\334\334\334\244\334\334\334\244\334\333\334\244\334\333\333\244\333"
+ "\333\333\244\333\333\333\244\333\333\333\244\333\333\333\244\333\333\333\244"
+ "\333\332\333\244\333\333\333\244\333\333\333\244\332\333\333\244\332\333\332"
+ "\244\332\332\332\244\332\332\332\244\332\332\332\244\332\332\332\244\332\332"
+ "\332\244\332\332\332\244\331\332\331\244\331\332\331\244\331\331\332\244\341"
+ "\341\341\244f\202\252\377\40J\207+\0\0\0\0\0\0\0\0\40J\207+g\203\253\377\343"
+ "\343\344\244\334\334\334\244\334\333\334\244\334\334\334\244\333\333\334\244"
+ "\333\333\333\244\333\334\333\244\333\333\333\244\333\333\333\244\333\333\333"
+ "\244\333\333\333\244\333\333\333\244\333\332\333\244\333\332\333\244\333\332"
+ "\332\244\332\332\333\244\332\332\333\244\332\332\332\244\333\332\332\244\332"
+ "\332\332\244\332\332\332\244\331\332\332\244\331\332\331\244\331\332\331\244"
+ "\331\332\331\244\331\331\331\244\331\331\331\244\332\331\331\244\331\331\331"
+ "\244\331\331\331\244\331\331\331\244\330\330\331\244\330\330\330\244\331\330"
+ "\330\244\330\330\330\244\330\330\330\244\331\330\330\244\330\330\330\244\330"
+ "\330\330\244\330\330\330\244\330\330\330\244\337\337\337\244f\202\252\377"
+ "\40J\207+\0\0\0\0\0\0\0\0\40J\207+g\203\253\377\342\342\343\244\332\332\332"
+ "\244\332\332\332\244\332\332\332\244\332\332\332\244\331\332\332\244\331\332"
+ "\332\244\332\332\331\244\332\331\331\244\331\331\331\244\331\331\331\244\331"
+ "\331\331\244\331\331\331\244\331\331\331\244\331\331\331\244\331\331\331\244"
+ "\331\331\331\244\330\330\330\244\331\330\331\244\330\331\330\244\330\330\330"
+ "\244\330\330\330\244\330\330\330\244\330\330\327\244\327\330\330\244\330\330"
+ "\327\244\327\330\330\244\330\330\327\244\327\327\327\244\327\327\327\244\327"
+ "\327\327\244\327\327\327\244\327\327\327\244\327\327\327\244\327\327\327\244"
+ "\326\327\327\244\327\326\326\244\326\327\326\244\326\326\326\244\326\326\326"
+ "\244\326\326\326\244\336\336\337\244f\202\252\377\40J\207+\0\0\0\0\0\0\0\0"
+ "\40J\207+g\203\253\377\341\341\341\244\331\331\331\244\330\331\331\244\330"
+ "\330\330\244\330\330\330\244\330\330\330\244\330\330\330\244\330\330\330\244"
+ "\327\330\330\244\330\330\327\244\330\330\330\244\330\327\330\244\327\327\327"
+ "\244\327\330\327\244\327\330\327\244\327\327\327\244\327\327\327\244\327\327"
+ "\327\244\327\327\327\244\326\327\326\244\326\327\326\244\326\326\326\244\326"
+ "\326\326\244\326\326\326\244\326\326\326\244\326\326\326\244\326\326\326\244"
+ "\326\326\326\244\325\325\326\244\325\326\326\244\326\325\325\244\325\325\325"
+ "\244\325\326\325\244\325\325\325\244\325\325\325\244\325\325\325\244\325\325"
+ "\325\244\325\325\325\244\325\324\325\244\324\324\324\244\324\324\324\244\335"
+ "\335\335\244f\202\252\377\40J\207+\0\0\0\0\0\0\0\0\40J\207+g\203\253\377\340"
+ "\340\340\244\327\327\327\244\327\327\327\244\326\327\327\244\327\326\327\244"
+ "\326\326\326\244\326\326\327\244\326\326\326\244\326\326\326\244\326\326\326"
+ "\244\326\326\326\244\326\326\326\244\326\326\325\244\325\326\325\244\325\326"
+ "\326\244\325\325\325\244\325\325\325\244\325\325\325\244\325\325\325\244\325"
+ "\325\325\244\325\325\325\244\324\325\325\244\325\325\325\244\324\325\325\244"
+ "\324\324\324\244\325\324\324\244\324\324\324\244\324\324\324\244\324\324\324"
+ "\244\323\324\324\244\324\323\324\244\323\324\324\244\323\324\324\244\323\324"
+ "\323\244\323\323\324\244\323\323\323\244\323\323\323\244\323\323\323\244\323"
+ "\323\323\244\323\323\323\244\323\323\323\244\334\334\334\244f\202\252\377"
+ "\40J\207+\0\0\0\0\0\0\0\0\40J\207+g\203\253\377\337\336\337\244\325\325\325"
+ "\244\325\325\325\244\325\325\325\244\325\325\325\244\325\325\325\244\325\325"
+ "\325\244\325\325\324\244\325\325\325\244\324\325\324\244\324\324\324\244\324"
+ "\324\324\244\324\324\324\244\324\324\324\244\324\324\324\244\324\324\324\244"
+ "\324\324\324\244\324\323\323\244\323\323\323\244\324\323\323\244\323\323\323"
+ "\244\323\323\323\244\324\323\323\244\323\323\323\244\323\323\323\244\323\322"
+ "\323\244\323\322\322\244\322\322\322\244\322\322\322\244\322\322\322\244\322"
+ "\322\322\244\322\322\322\244\322\322\322\244\322\322\322\244\321\322\321\244"
+ "\321\321\322\244\321\321\321\244\321\321\321\244\321\321\321\244\321\321\321"
+ "\244\321\321\321\244\334\333\334\244g\202\252\377\40J\207+\0\0\0\0\0\0\0\0"
+ "\40J\207+h\203\253\377\336\336\336\244\323\324\323\244\324\323\324\244\324"
+ "\323\323\244\323\324\323\244\323\323\323\244\323\323\323\244\323\323\323\244"
+ "\323\323\323\244\323\323\323\244\323\323\323\244\322\323\323\244\323\322\323"
+ "\244\322\322\323\244\322\322\322\244\322\322\322\244\322\322\322\244\322\322"
+ "\322\244\322\322\322\244\322\322\322\244\322\322\322\244\321\321\321\244\322"
+ "\321\321\244\321\321\321\244\321\321\321\244\321\321\321\244\321\321\321\244"
+ "\321\321\320\244\321\321\321\244\321\321\321\244\321\321\321\244\320\320\320"
+ "\244\320\320\320\244\320\320\320\244\320\320\320\244\320\317\320\244\317\320"
+ "\320\244\320\320\320\244\320\320\320\244\320\320\320\244\320\317\317\244\332"
+ "\332\332\244g\202\252\377\40J\207+\0\0\0\0\0\0\0\0\40J\207+h\203\253\377\335"
+ "\335\335\244\322\322\322\244\322\322\322\244\322\322\322\244\321\322\322\244"
+ "\321\321\321\244\321\321\321\244\322\321\321\244\321\321\321\244\321\321\321"
+ "\244\321\321\321\244\321\321\321\244\321\320\321\244\320\321\320\244\320\320"
+ "\320\244\320\320\320\244\320\320\320\244\320\320\320\244\320\320\320\244\320"
+ "\320\320\244\320\320\320\244\320\320\320\244\320\320\320\244\317\320\320\244"
+ "\317\320\317\244\317\317\317\244\317\317\317\244\317\317\317\244\317\317\317"
+ "\244\317\317\317\244\316\317\317\244\317\317\317\244\317\316\316\244\316\316"
+ "\316\244\317\316\316\244\316\316\316\244\316\316\316\244\316\316\316\244\316"
+ "\316\316\244\316\316\316\244\316\316\316\244\331\331\331\245f\202\252\377"
+ "\40J\207+\0\0\0\0\0\0\0\0\40J\207+h\203\253\377\334\334\334\244\320\320\320"
+ "\244\320\320\320\244\320\320\320\244\320\320\320\244\320\320\320\244\320\320"
+ "\320\244\320\320\317\244\317\317\320\244\320\317\317\244\317\317\317\244\317"
+ "\317\317\244\317\317\317\244\317\317\317\244\317\317\317\244\317\317\317\244"
+ "\317\316\317\244\317\317\316\244\316\317\317\244\316\316\316\244\316\316\316"
+ "\244\316\316\316\244\316\316\316\244\316\316\316\244\316\316\316\244\316\315"
+ "\315\244\316\316\315\244\315\316\315\244\315\316\316\244\315\315\315\244\315"
+ "\315\315\244\315\315\315\244\315\315\315\244\315\314\315\244\315\315\315\244"
+ "\315\315\314\244\314\314\314\244\314\314\314\244\314\314\314\244\314\314\314"
+ "\244\314\314\314\244\331\330\331\247f\202\252\377\40J\207+\0\0\0\0\0\0\0\0"
+ "\40J\207+h\203\253\377\333\333\333\244\317\317\316\244\316\317\316\244\317"
+ "\316\316\244\317\316\316\244\316\317\316\244\316\316\316\244\316\316\316\244"
+ "\316\316\316\244\316\316\316\244\316\315\316\244\315\315\315\244\315\315\316"
+ "\244\315\315\315\244\315\315\315\244\315\315\315\244\315\315\315\244\315\315"
+ "\315\244\315\315\315\244\315\315\314\244\315\314\314\244\314\314\314\244\314"
+ "\315\314\244\314\314\314\244\314\314\314\244\314\314\314\244\314\314\314\244"
+ "\314\314\314\244\314\314\313\244\313\313\313\244\314\314\313\244\313\313\313"
+ "\244\313\313\313\244\313\313\313\244\313\313\313\244\313\313\313\244\313\313"
+ "\313\244\312\313\313\244\312\312\313\244\312\312\313\244\312\312\313\244\327"
+ "\327\327\244g\203\253\377\40J\207+\0\0\0\0\0\0\0\0\40J\207+h\203\253\377\332"
+ "\332\332\244\315\315\315\244\314\315\315\244\315\315\315\244\315\315\315\244"
+ "\314\315\315\244\314\314\315\244\314\314\314\244\314\314\314\244\314\314\314"
+ "\244\314\314\314\244\314\314\314\244\314\314\314\244\313\314\314\244\313\314"
+ "\313\244\313\313\313\244\313\313\313\244\313\313\313\244\313\313\313\244\313"
+ "\313\313\244\313\313\313\244\313\312\313\244\313\313\313\244\312\313\313\244"
+ "\313\313\313\244\312\312\312\244\312\312\312\244\312\312\312\244\312\312\312"
+ "\244\312\312\312\244\312\312\312\244\312\312\311\244\312\311\311\244\312\312"
+ "\311\244\311\311\311\244\311\311\311\244\311\311\311\244\311\311\311\244\311"
+ "\311\311\244\311\311\311\244\311\311\311\244\327\326\327\244g\203\253\377"
+ "\40J\207+\0\0\0\0\0\0\0\0\40J\207+g\203\253\377\331\331\331\244\313\313\313"
+ "\244\313\313\313\244\313\313\313\244\313\313\313\244\313\313\313\244\313\313"
+ "\313\244\312\312\313\244\312\313\313\244\312\312\312\244\312\312\312\244\312"
+ "\312\312\244\312\312\312\244\312\312\312\244\312\312\312\244\311\311\311\244"
+ "\312\312\312\244\311\311\311\244\311\311\311\244\311\312\311\244\311\311\311"
+ "\244\311\311\311\244\311\311\311\244\311\311\311\244\311\311\311\244\311\310"
+ "\311\244\310\310\310\244\310\310\310\244\310\310\310\244\310\310\310\244\310"
+ "\310\310\244\310\310\310\244\310\310\310\244\310\310\310\244\310\310\310\244"
+ "\307\307\310\244\310\307\310\244\307\307\307\244\307\307\307\244\307\307\307"
+ "\244\307\307\307\244\325\325\325\244g\203\253\377\40J\207+\0\0\0\0\0\0\0\0"
+ "\40J\207+h\204\254\377\330\330\331\244\312\312\311\244\312\312\311\244\312"
+ "\311\311\244\311\311\311\244\311\311\311\244\311\311\311\244\310\311\311\244"
+ "\311\311\311\244\311\311\311\244\311\310\311\244\311\310\310\244\311\311\311"
+ "\244\310\310\311\244\310\310\310\244\310\310\310\244\310\310\310\244\310\310"
+ "\310\244\310\310\310\244\307\310\307\244\310\310\310\244\307\307\307\244\307"
+ "\307\310\244\307\307\307\244\307\307\307\244\307\307\307\244\307\307\307\244"
+ "\307\307\307\244\307\307\307\244\306\306\307\244\306\307\307\244\306\306\306"
+ "\244\306\306\306\244\306\306\306\244\306\306\306\244\306\306\306\244\306\306"
+ "\306\244\305\306\306\244\305\306\305\244\305\306\306\244\305\306\306\244\325"
+ "\325\325\244g\203\253\377\40J\207+\0\0\0\0\0\0\0\0\40J\207+h\204\254\377\327"
+ "\327\327\244\310\310\310\244\310\310\310\244\310\310\310\244\310\307\307\244"
+ "\307\307\310\244\307\307\307\244\307\307\307\244\307\307\307\244\307\307\307"
+ "\244\307\307\307\244\307\307\307\244\307\307\307\244\307\306\306\244\307\306"
+ "\306\244\306\307\306\244\307\306\306\244\306\306\306\244\306\306\306\244\306"
+ "\306\306\244\306\306\306\244\306\306\306\244\306\306\306\244\305\305\305\244"
+ "\305\305\306\244\306\305\305\244\305\305\305\244\305\305\306\244\305\305\305"
+ "\244\305\305\305\244\305\305\305\244\305\304\305\244\304\304\304\244\304\304"
+ "\305\244\304\304\305\244\304\304\304\244\304\304\304\244\304\304\304\244\304"
+ "\304\304\244\304\304\304\244\304\304\304\244\324\324\324\244g\203\253\377"
+ "\40J\207+\0\0\0\0\0\0\0\0\40J\207+h\204\254\377\326\326\326\244\307\306\306"
+ "\244\306\306\306\244\306\306\306\244\306\306\306\244\306\306\306\244\306\305"
+ "\306\244\306\306\305\244\305\305\306\244\305\306\306\244\305\305\305\244\305"
+ "\305\305\244\305\305\305\244\305\305\305\244\305\305\305\244\305\305\305\244"
+ "\305\304\305\244\305\305\305\244\304\304\305\244\304\304\304\244\304\304\304"
+ "\244\304\304\304\244\304\304\304\244\304\304\304\244\304\304\304\244\304\304"
+ "\303\244\304\303\304\244\303\303\304\244\303\303\304\244\303\303\303\244\303"
+ "\303\303\244\303\302\303\244\303\303\303\244\303\303\303\244\303\302\303\244"
+ "\303\302\303\244\303\302\303\244\302\302\302\244\302\302\302\244\302\302\302"
+ "\244\302\302\302\244\323\323\323\244h\204\254\377\40J\207+\0\0\0\0\0\0\0\0"
+ "\40J\206+h\204\254\377\325\325\325\244\304\305\305\244\305\305\305\244\305"
+ "\304\304\244\304\304\305\244\304\305\305\244\304\304\304\244\305\304\305\244"
+ "\304\305\304\244\304\304\304\244\304\304\304\244\304\304\303\244\304\304\304"
+ "\244\304\304\303\244\303\303\304\244\303\303\303\244\304\303\303\244\303\303"
+ "\303\244\303\303\303\244\303\303\303\244\303\302\303\244\303\302\303\244\302"
+ "\303\303\244\302\302\303\244\302\303\303\244\302\303\302\244\302\302\302\244"
+ "\302\302\302\244\301\301\301\244\301\301\301\244\301\301\301\244\301\301\301"
+ "\244\301\301\301\244\301\301\301\244\301\301\301\244\301\301\301\244\301\301"
+ "\301\244\301\301\301\244\301\301\301\244\301\301\301\244\301\301\301\244\322"
+ "\322\322\244g\203\253\377\37H\204,\0\0\0\0\0\0\0\1\35Cy0f\202\252\377\350"
+ "\350\350\244\344\344\344\244\344\344\344\244\344\344\344\244\344\344\344\244"
+ "\344\344\344\244\344\344\344\244\344\344\344\244\344\344\344\244\344\344\344"
+ "\244\344\344\344\244\344\344\344\244\344\344\344\244\344\344\344\244\344\344"
+ "\344\244\344\344\344\244\344\344\344\244\343\343\343\244\343\343\343\244\344"
+ "\344\344\244\344\343\344\244\343\343\343\244\343\343\343\244\343\343\343\244"
+ "\343\343\343\244\343\343\343\244\343\343\343\244\343\343\343\244\342\342\342"
+ "\244\342\342\342\244\342\342\342\244\342\342\342\244\342\342\342\244\342\342"
+ "\342\244\342\342\342\244\342\342\342\244\342\342\342\244\342\342\342\244\342"
+ "\342\342\244\342\342\342\244\342\342\342\244\347\347\347\244f\202\252\377"
+ "\33=p3\0\0\0\5\0\0\0\14\27""5`<+T\216\377<d\233\377<d\233\377<d\233\377<d"
+ "\233\377<d\233\377<d\233\377<c\233\377:b\232\377-U\217\377<c\233\377;c\233"
+ "\377:c\233\377:c\233\377:c\233\377:c\233\377:c\233\377:c\232\377:c\232\377"
+ ":b\232\377:c\232\377:c\232\377:b\232\377:b\232\377:b\232\3779b\232\3779b\232"
+ "\3779b\232\3779b\232\3779b\232\3779b\232\3779b\232\3779b\232\3778b\232\377"
+ "+U\217\3778a\231\3778a\232\3778a\232\3778a\232\3778a\232\3778a\232\3778a\232"
+ "\3777`\231\377)R\216\377\25""1YA\0\0\0\23\0\0\0\25\24.UD4_\234\377R\202\277"
+ "\377R\202\277\377R\202\277\377R\202\277\377R\202\277\377R\202\277\377R\202"
+ "\277\377N\177\273\3771^\232\377R\202\277\377Q\202\277\377Q\202\277\377Q\202"
+ "\277\377Q\202\277\377Q\202\277\377Q\202\277\377Q\201\276\377Q\201\276\377"
+ "P\201\276\377Q\201\276\377Q\201\276\377P\201\276\377P\201\276\377P\201\276"
+ "\377P\201\276\377P\201\276\377P\201\276\377P\201\276\377P\201\276\377P\201"
+ "\276\377O\200\276\377O\200\276\377O\200\276\3770]\232\377N\177\274\377O\200"
+ "\276\377O\200\276\377O\200\276\377N\200\276\377N\200\276\377N\200\276\377"
+ "N\177\275\3771]\233\377\22+OI\0\0\0\34\0\0\0\33\20%C@*S\214\377<b\227\377"
+ "<a\227\377<a\227\377<a\227\377<a\227\377<a\227\377<a\227\377;_\226\377-T\216"
+ "\377;`\226\377<a\227\377<a\227\377<a\227\377<a\227\377<a\227\377<a\227\377"
+ "<a\227\377<a\227\377<a\227\377;`\226\377;`\226\377;`\226\377;`\226\377;`\226"
+ "\377;`\226\377;`\226\377;`\226\377;`\226\377;`\226\377;`\226\377;`\226\377"
+ ";`\226\377;`\226\377-T\215\377;`\226\377;`\226\377;`\226\377;`\226\377;a\226"
+ "\377;a\226\377;a\226\377<a\227\377*R\214\377\17!=G\0\0\0#\0\0\0\33\3\7\14"
+ ")\31""6bw\30""4\\}\26""0W\205\25.S\214\25.R\215\25.R\215\25.R\215\25.R\215"
+ "\25.R\215\25.R\215\25.R\215\25.R\215\25.R\215\25.R\215\25.R\215\25.R\215\25"
+ ".R\215\25.R\215\25.R\215\25.R\215\25.R\215\25.R\215\25.R\215\25.R\215\25."
+ "R\215\25.R\215\25.R\215\25.R\215\25.R\215\25.R\215\25.R\215\25.R\215\25.R"
+ "\215\25.R\215\25.R\215\25.R\215\25.R\215\25.R\215\25.R\215\25.R\215\25-Q\217"
+ "\26/T\212\27""2Y\202\30""4^{\2\5\12""1\0\0\0#\0\0\0\25\0\0\0\37\0\0\0+\0\0"
+ "\0""4\0\0\0=\0\0\0C\0\0\0D\0\0\0C\0\0\0C\0\0\0C\0\0\0C\0\0\0C\0\0\0C\0\0\0"
+ "C\0\0\0C\0\0\0C\0\0\0C\0\0\0C\0\0\0C\0\0\0C\0\0\0C\0\0\0C\0\0\0C\0\0\0C\0"
+ "\0\0C\0\0\0C\0\0\0C\0\0\0C\0\0\0C\0\0\0C\0\0\0C\0\0\0C\0\0\0C\0\0\0C\0\0\0"
+ "C\0\0\0C\0\0\0C\0\0\0C\0\0\0C\0\0\0C\0\0\0C\0\0\0D\0\0\0F\0\0\0B\0\0\0:\0"
+ "\0\0""2\0\0\0&\0\0\0\35\0\0\0\15\0\0\0\26\0\0\0\40\0\0\0'\0\0\0/\0\0\0""3"
+ "\0\0\0""3\0\0\0""2\0\0\0""2\0\0\0""2\0\0\0""2\0\0\0""2\0\0\0""2\0\0\0""2\0"
+ "\0\0""2\0\0\0""2\0\0\0""2\0\0\0""2\0\0\0""2\0\0\0""2\0\0\0""2\0\0\0""2\0\0"
+ "\0""2\0\0\0""2\0\0\0""2\0\0\0""2\0\0\0""2\0\0\0""2\0\0\0""2\0\0\0""2\0\0\0"
+ """2\0\0\0""2\0\0\0""2\0\0\0""2\0\0\0""2\0\0\0""2\0\0\0""2\0\0\0""2\0\0\0""2"
+ "\0\0\0""2\0\0\0""2\0\0\0""3\0\0\0""5\0\0\0""2\0\0\0,\0\0\0%\0\0\0\34\0\0\0"
+ "\23\0\0\0\1\0\0\0\7\0\0\0\16\0\0\0\25\0\0\0\32\0\0\0\35\0\0\0\35\0\0\0\34"
+ "\0\0\0\34\0\0\0\34\0\0\0\34\0\0\0\34\0\0\0\34\0\0\0\34\0\0\0\34\0\0\0\34\0"
+ "\0\0\34\0\0\0\34\0\0\0\34\0\0\0\34\0\0\0\34\0\0\0\34\0\0\0\34\0\0\0\34\0\0"
+ "\0\34\0\0\0\34\0\0\0\34\0\0\0\34\0\0\0\34\0\0\0\34\0\0\0\34\0\0\0\34\0\0\0"
+ "\34\0\0\0\34\0\0\0\34\0\0\0\34\0\0\0\34\0\0\0\34\0\0\0\34\0\0\0\34\0\0\0\34"
+ "\0\0\0\35\0\0\0\36\0\0\0\35\0\0\0\30\0\0\0\23\0\0\0\12\0\0\0\3\0\0\0\0\0\0"
+ "\0\0\0\0\0\2\0\0\0\5\0\0\0\10\0\0\0\13\0\0\0\14\0\0\0\13\0\0\0\13\0\0\0\13"
+ "\0\0\0\13\0\0\0\13\0\0\0\13\0\0\0\13\0\0\0\13\0\0\0\13\0\0\0\13\0\0\0\13\0"
+ "\0\0\13\0\0\0\13\0\0\0\13\0\0\0\13\0\0\0\13\0\0\0\13\0\0\0\13\0\0\0\13\0\0"
+ "\0\13\0\0\0\13\0\0\0\13\0\0\0\13\0\0\0\13\0\0\0\13\0\0\0\13\0\0\0\13\0\0\0"
+ "\13\0\0\0\13\0\0\0\13\0\0\0\13\0\0\0\13\0\0\0\13\0\0\0\13\0\0\0\14\0\0\0\14"
+ "\0\0\0\12\0\0\0\6\0\0\0\3\0\0\0\0\0\0\0\0");
+
look = RrAppearanceNew(inst, 0);
look->surface.grad = RR_SURFACE_MIRROR_HORIZONTAL;
- look->surface.secondary = RrColorParse(inst, "Yellow");
look->surface.split_secondary = RrColorParse(inst, "Red");
look->surface.split_primary = RrColorParse(inst, "Green");
- look->surface.primary = RrColorParse(inst, "Blue");
+ look->surface.secondary = RrColorParse(inst, "Dark Orange");
+ look->surface.primary = RrColorParse(inst, "Dark Blue");
look->surface.interlaced = FALSE;
if (ob_display == NULL) {
fprintf(stderr, "couldn't connect to X server :0\n");
case Expose:
break;
case ConfigureNotify:
+ look->surface.grad += 1;
+ if (look->surface.grad > RR_SURFACE_MIRROR_HORIZONTAL)
+ look->surface.grad = RR_SURFACE_SPLIT_VERTICAL;
RrPaint(look, win,
report.xconfigure.width,
report.xconfigure.height);
#include "font.h"
#include "mask.h"
#include "theme.h"
-#include "icon.h"
+#ifdef MIKACHU
+# include "icon-mikamika.h"
+#else
+# include "icon.h"
+#endif
#include "obt/paths.h"
#include <X11/Xlib.h>
RrMargins(theme->a_focused_label, &fl, &ft, &fr, &fb);
RrMargins(theme->a_unfocused_label, &ul, &ut, &ur, &ub);
- theme->label_height = theme->win_font_height + MAX(ft + fb, ut + ub);
- theme->label_height += theme->label_height % 2;
+ theme->label_height = theme->win_font_height + MAX(ft + fb, ut + ub) + 1;
/* this would be nice I think, since padding.width can now be 0,
but it breaks frame.c horribly and I don't feel like fixing that
*/
CREATE_(OPENBOX_PID);
+ CREATE_(OB_FOCUS);
CREATE_(OB_THEME);
CREATE_(OB_CONFIG_FILE);
CREATE_(OB_WM_ACTION_UNDECORATE);
CREATE_(OB_WM_STATE_UNDECORATED);
+ CREATE_(OB_WM_STATE_LOCKED);
+ CREATE_(OB_LAST_DESKTOP);
CREATE_(OB_CONTROL);
CREATE_(OB_VERSION);
CREATE_(OB_APP_ROLE);
CREATE_(OB_APP_GROUP_NAME);
CREATE_(OB_APP_GROUP_CLASS);
CREATE_(OB_APP_TYPE);
+ CREATE_(OB_TARGET_WINDOW);
}
Atom obt_prop_atom(ObtPropAtom a)
const gchar *end; /* the first byte past the valid data */
g_utf8_validate(retlist[i], -1, &end);
- retlist[i] = g_strndup(retlist[i], end-retlist[i]);
+ retlist[i] = g_utf8_normalize(retlist[i], end-retlist[i], G_NORMALIZE_NFC);
}
else if (encoding == LOCALE) {
gsize nvalid; /* the number of valid bytes at the front of the
/* Openbox specific atoms */
+ OBT_PROP_OB_FOCUS,
OBT_PROP_OB_WM_ACTION_UNDECORATE,
OBT_PROP_OB_WM_STATE_UNDECORATED,
+ OBT_PROP_OB_WM_STATE_LOCKED,
OBT_PROP_OPENBOX_PID, /* this is depreecated in favour of ob_control */
OBT_PROP_OB_THEME,
OBT_PROP_OB_CONFIG_FILE,
+ OBT_PROP_OB_LAST_DESKTOP,
OBT_PROP_OB_CONTROL,
OBT_PROP_OB_VERSION,
OBT_PROP_OB_APP_ROLE,
OBT_PROP_OB_APP_GROUP_NAME,
OBT_PROP_OB_APP_GROUP_CLASS,
OBT_PROP_OB_APP_TYPE,
+ OBT_PROP_OB_TARGET_WINDOW,
OBT_PROP_NUM_ATOMS
} ObtPropAtom;
event_end_ignore_all_enters(ignore_start);
}
}
+
+gboolean actions_client_locked(ObActionsData *data)
+{
+ ObClient *c = data->client;
+
+ return !c || (c && c->locked);
+}
/*! Function for actions to call when they are moving a client around */
void actions_client_move(ObActionsData *data, gboolean start);
+/*! May we do something to this client? */
+gboolean actions_client_locked(ObActionsData *data);
action_move_startup();
action_focus_startup();
action_raise_startup();
+ action_raisetemp_startup();
action_lower_startup();
action_raiselower_startup();
action_unfocus_startup();
+ action_focusfallback_startup();
action_iconify_startup();
action_fullscreen_startup();
action_maximize_startup();
action_growtoedge_startup();
action_if_startup();
action_focustobottom_startup();
+ action_sendkeyevent_startup();
+ action_lock_startup();
/* 3.4-compatibility */
action_shadelowerraise_startup();
}
void action_move_startup(void);
void action_focus_startup(void);
void action_raise_startup(void);
+void action_raisetemp_startup(void);
void action_lower_startup(void);
void action_raiselower_startup(void);
void action_unfocus_startup(void);
+void action_focusfallback_startup(void);
void action_iconify_startup(void);
void action_fullscreen_startup(void);
void action_maximize_startup(void);
void action_growtoedge_startup(void);
void action_if_startup(void);
void action_focustobottom_startup(void);
+void action_sendkeyevent_startup(void);
+void action_lock_startup(void);
/* 3.4-compatibility */
void action_shadelowerraise_startup(void);
/* Always return FALSE because its not interactive */
static gboolean run_func(ObActionsData *data, gpointer options)
{
- if (data->client) client_close(data->client);
+ if (!actions_client_locked(data))
+ client_close(data->client);
return FALSE;
}
/* Always return FALSE because its not interactive */
static gboolean run_func_on(ObActionsData *data, gpointer options)
{
- if (data->client) {
+ if (!actions_client_locked(data)) {
actions_client_move(data, TRUE);
client_set_undecorated(data->client, FALSE);
actions_client_move(data, FALSE);
/* Always return FALSE because its not interactive */
static gboolean run_func_off(ObActionsData *data, gpointer options)
{
- if (data->client) {
+ if (!actions_client_locked(data)) {
actions_client_move(data, TRUE);
client_set_undecorated(data->client, TRUE);
actions_client_move(data, FALSE);
/* Always return FALSE because its not interactive */
static gboolean run_func_toggle(ObActionsData *data, gpointer options)
{
- if (data->client) {
+ if (!actions_client_locked(data)) {
actions_client_move(data, TRUE);
client_set_undecorated(data->client, !data->client->undecorated);
actions_client_move(data, FALSE);
Options *o = options;
guint d;
+
+
switch (o->type) {
case LAST:
d = screen_last_desktop;
/* If there is a keyboard grab going on then we need to cancel
it so the application can grab things */
- if (data->uact != OB_USER_ACTION_MENU_SELECTION)
+ if (data->uact != OB_USER_ACTION_MENU_SELECTION &&
+ data->uact != OB_USER_ACTION_KEYBOARD_KEY_NO_REPEAT)
event_cancel_all_key_grabs();
e = NULL;
(data->context != OB_FRAME_CONTEXT_CLIENT &&
data->context != OB_FRAME_CONTEXT_FRAME))
{
- if (o->stop_int)
- actions_interactive_cancel_act();
+ if (!(data->client->iconic && actions_client_locked(data))) {
+ if (o->stop_int)
+ actions_interactive_cancel_act();
- actions_client_move(data, TRUE);
- client_activate(data->client, TRUE, o->here, FALSE, FALSE, TRUE);
- actions_client_move(data, FALSE);
+ actions_client_move(data, TRUE);
+ client_activate(data->client, TRUE, o->here, FALSE, FALSE, TRUE);
+ actions_client_move(data, FALSE);
+ }
}
} else if (data->context == OB_FRAME_CONTEXT_DESKTOP) {
if (o->stop_int)
--- /dev/null
+#include "openbox/actions.h"
+#include "openbox/focus.h"
+
+static gboolean run_func(ObActionsData *data, gpointer options);
+
+void action_focusfallback_startup(void)
+{
+ actions_register("FocusFallback", NULL, NULL, run_func);
+}
+
+/* Always return FALSE because its not interactive */
+static gboolean run_func(ObActionsData *data, gpointer options)
+{
+ if (data->client && data->client == focus_client)
+ focus_fallback(FALSE, FALSE, TRUE, FALSE);
+ return FALSE;
+}
{
Options *o = options;
- if (!data->client)
+ if (!data->client ||
+ actions_client_locked(data))
return FALSE;
gboolean doing_vertical_resize =
#include "openbox/client.h"
static gboolean run_func(ObActionsData *data, gpointer options);
+static gpointer setup_func(xmlNodePtr node);
void action_iconify_startup(void)
{
actions_register("Iconify",
- NULL, NULL,
+ setup_func,
+ NULL,
run_func);
}
+static gpointer setup_func(xmlNodePtr node)
+{
+ xmlNodePtr n;
+
+ if ((n = obt_xml_find_node(node, "de")))
+ return GINT_TO_POINTER(obt_xml_node_bool(n));
+
+ return GINT_TO_POINTER(0);
+}
+
/* Always return FALSE because its not interactive */
static gboolean run_func(ObActionsData *data, gpointer options)
{
- if (data->client) {
+ if (!actions_client_locked(data)) {
actions_client_move(data, TRUE);
- client_iconify(data->client, TRUE, TRUE, FALSE);
+ client_iconify(data->client, !options, FALSE, FALSE);
actions_client_move(data, FALSE);
}
gboolean iconic_off;
gboolean fullscreen_on;
gboolean fullscreen_off;
+ gboolean locked_on;
+ gboolean locked_off;
gboolean focused;
gboolean unfocused;
gboolean urgent_on;
set_bool(node, "maximizedvertical", &q->maxvert_on, &q->maxvert_off);
set_bool(node, "iconified", &q->iconic_on, &q->iconic_off);
set_bool(node, "fullscreen", &q->fullscreen_on, &q->fullscreen_off);
+ set_bool(node, "locked", &q->locked_on, &q->locked_off);
set_bool(node, "focused", &q->focused, &q->unfocused);
set_bool(node, "urgent", &q->urgent_on, &q->urgent_off);
set_bool(node, "undecorated", &q->decor_off, &q->decor_on);
if (q->fullscreen_off)
is_true &= !query_target->fullscreen;
+ if (q->locked_on)
+ is_true &= query_target->locked;
+ if (q->locked_off)
+ is_true &= !query_target->locked;
+
if (q->maxhorz_on)
is_true &= query_target->max_horz;
if (q->maxhorz_off)
/* Always return FALSE because its not interactive */
static gboolean run_func(ObActionsData *data, gpointer options)
{
- if (data->client)
+ if (!actions_client_locked(data))
client_kill(data->client);
return FALSE;
--- /dev/null
+#include "openbox/actions.h"
+#include "openbox/client.h"
+
+static gboolean run_func(ObActionsData *data, gpointer options);
+
+void action_lock_startup(void)
+{
+ actions_register("Lock", NULL, NULL, run_func);
+}
+
+/* Always return FALSE because its not interactive */
+static gboolean run_func(ObActionsData *data, gpointer options)
+{
+ if (data->client)
+ client_set_locked(data->client, !data->client->locked);
+
+ return FALSE;
+}
static gboolean run_func_on(ObActionsData *data, gpointer options)
{
Options *o = options;
- if (data->client) {
+ if (!actions_client_locked(data)) {
actions_client_move(data, TRUE);
client_maximize(data->client, TRUE, o->dir);
actions_client_move(data, FALSE);
static gboolean run_func_off(ObActionsData *data, gpointer options)
{
Options *o = options;
- if (data->client) {
+ if (!actions_client_locked(data)) {
actions_client_move(data, TRUE);
client_maximize(data->client, FALSE, o->dir);
actions_client_move(data, FALSE);
static gboolean run_func_toggle(ObActionsData *data, gpointer options)
{
Options *o = options;
- if (data->client) {
+ if (!actions_client_locked(data)) {
gboolean toggle;
actions_client_move(data, TRUE);
toggle = ((o->dir == HORZ && !data->client->max_horz) ||
#include "openbox/actions.h"
+#include "openbox/client.h"
#include "openbox/moveresize.h"
#include "obt/prop.h"
/* Always return FALSE because its not interactive */
static gboolean run_func(ObActionsData *data, gpointer options)
{
- if (data->client) {
+ if (data->client && !data->client->locked) {
guint32 corner;
corner = data->button != 0 ?
{
Options *o = options;
- if (data->client) {
+ if (!actions_client_locked(data)) {
ObClient *c;
gint x, y, lw, lh, w, h;
{
Options *o = options;
- if (data->client) {
+ if (!actions_client_locked(data)) {
Rect *area, *carea;
ObClient *c;
guint mon, cmon;
{
Options *o = options;
- if (data->client) {
+ if (!actions_client_locked(data)) {
gint x, y;
client_find_move_directional(data->client, o->dir, &x, &y);
--- /dev/null
+#include "openbox/actions.h"
+#include "openbox/stacking.h"
+#include "openbox/window.h"
+#include "openbox/focus_cycle.h"
+
+static gboolean run_func(ObActionsData *data, gpointer options);
+
+void action_raisetemp_startup(void)
+{
+ actions_register("RaiseTemp",
+ NULL, NULL,
+ run_func);
+}
+
+/* Always return FALSE because its not interactive */
+static gboolean run_func(ObActionsData *data, gpointer options)
+{
+ if (focus_cycle_target) {
+ actions_client_move(data, TRUE);
+ stacking_temp_raise(CLIENT_AS_WINDOW(data->client));
+ actions_client_move(data, FALSE);
+ }
+
+ return FALSE;
+}
{
Options *o = options;
- if (data->client) {
+ if (!actions_client_locked(data)) {
ObClient *c = data->client;
guint32 corner;
{
Options *o = options;
- if (data->client) {
+ if (!actions_client_locked(data)) {
ObClient *c = data->client;
gint x, y, ow, xoff, nw, oh, yoff, nh, lw, lh;
gint left = o->left, right = o->right, top = o->top, bottom = o->bottom;
--- /dev/null
+#include "openbox/actions.h"
+#include "openbox/client.h"
+#include "openbox/window.h"
+#include "openbox/translate.h"
+#include "obt/display.h"
+#include "obt/prop.h"
+#include "openbox/openbox.h"
+#include "gettext.h"
+
+typedef struct {
+ guint key;
+ guint state;
+ gboolean target;
+} Options;
+
+static gpointer setup_sendkey_func(xmlNodePtr node);
+static gboolean sendkey(ObActionsData *data, gpointer options);
+static gboolean settarget(ObActionsData *data, gpointer options);
+
+static Window target;
+
+void action_sendkeyevent_startup(void)
+{
+ actions_register("SendKeyEvent",
+ setup_sendkey_func, g_free,
+ sendkey);
+ actions_register("SetKeyTarget",
+ NULL, NULL,
+ settarget);
+ OBT_PROP_GET32(obt_root(ob_screen), OB_TARGET_WINDOW, WINDOW, (guint32 *)&target);
+}
+
+static gpointer setup_sendkey_func(xmlNodePtr node)
+{
+ xmlNodePtr n;
+ Options *o;
+
+ o = g_new0(Options, 1);
+ o->target = TRUE;
+
+ if ((n = obt_xml_find_node(node, "key"))) {
+ gchar *s = obt_xml_node_string(n);
+ translate_key(s, &o->state, &o->key);
+ g_free(s);
+ } else
+ translate_key("space", &o->state, &o->key);
+ if ((n = obt_xml_find_node(node, "usetarget")))
+ o->target = obt_xml_node_bool(n);
+
+ return o;
+}
+
+/* Always return FALSE because its not interactive */
+static gboolean sendkey(ObActionsData *data, gpointer options)
+{
+ Options *o = options;
+ XEvent ev;
+ Window win;
+
+ if (!o->key) /* the key couldn't be parsed */
+ return FALSE;
+
+ if (o->target)
+ win = target;
+ else if (data->client)
+ win = data->client->window;
+ else
+ return FALSE;
+
+ ev.xkey.window = win;
+ ev.xkey.state = o->state;
+ ev.xkey.keycode = o->key;
+ obt_display_ignore_errors(TRUE);
+ ev.type = KeyPress;
+ XSendEvent(obt_display, win, False, 0, &ev);
+ ev.type = KeyRelease;
+ XSendEvent(obt_display, win, False, 0, &ev);
+ obt_display_ignore_errors(FALSE);
+
+ return FALSE;
+}
+
+/* Always return FALSE because its not interactive */
+static gboolean settarget(ObActionsData *data, gpointer options)
+{
+ if (data->client) {
+ target = data->client->window;
+ OBT_PROP_SET32(obt_root(ob_screen), OB_TARGET_WINDOW, WINDOW, target);
+ }
+
+ return FALSE;
+}
/* Always return FALSE because its not interactive */
static gboolean run_func_on(ObActionsData *data, gpointer options)
{
- if (data->client) {
+ if (!actions_client_locked(data)) {
actions_client_move(data, TRUE);
client_shade(data->client, TRUE);
actions_client_move(data, FALSE);
/* Always return FALSE because its not interactive */
static gboolean run_func_off(ObActionsData *data, gpointer options)
{
- if (data->client) {
+ if (!actions_client_locked(data)) {
actions_client_move(data, TRUE);
client_shade(data->client, FALSE);
actions_client_move(data, FALSE);
/* Always return FALSE because its not interactive */
static gboolean run_func_toggle(ObActionsData *data, gpointer options)
{
- if (data->client) {
+ if (!actions_client_locked(data)) {
actions_client_move(data, TRUE);
client_shade(data->client, !data->client->shaded);
actions_client_move(data, FALSE);
/* Always return FALSE because its not interactive */
static gboolean run_func(ObActionsData *data, gpointer options)
{
- if (data->client && data->client == focus_client)
- focus_fallback(FALSE, FALSE, TRUE, FALSE);
+ actions_interactive_cancel_act();
+ focus_nothing();
return FALSE;
}
only limiting the application.
*/
if (client_normal(self)) {
- if (!self->strut.right && *x + fw/10 >= a->x + a->width - 1)
- *x = a->x + a->width - fw/10;
- if (!self->strut.bottom && *y + fh/10 >= a->y + a->height - 1)
- *y = a->y + a->height - fh/10;
- if (!self->strut.left && *x + fw*9/10 - 1 < a->x)
- *x = a->x - fw*9/10;
- if (!self->strut.top && *y + fh*9/10 - 1 < a->y)
- *y = a->y - fh*9/10;
+ if (!self->strut.right && *x + fw/100 >= a->x + a->width - 1)
+ *x = a->x + a->width - fw/100;
+ if (!self->strut.bottom && *y + fh/100 >= a->y + a->height - 1)
+ *y = a->y + a->height - fh/100;
+ if (!self->strut.left && *x + fw*99/100 - 1 < a->x)
+ *x = a->x - fw*99/100;
+ if (!self->strut.top && *y + fh*99/100 - 1 < a->y)
+ *y = a->y - fh*99/100;
}
/* This here doesn't let windows even a pixel outside the
self->demands_attention = TRUE;
else if (state[i] == OBT_PROP_ATOM(OB_WM_STATE_UNDECORATED))
self->undecorated = TRUE;
+ else if (state[i] == OBT_PROP_ATOM(OB_WM_STATE_LOCKED))
+ self->locked = TRUE;
}
g_free(state);
gchar *data = NULL;
gchar *visible = NULL;
- g_free(self->title);
g_free(self->original_title);
/* try netwm */
g_free(data);
}
- OBT_PROP_SETS(self->window, NET_WM_VISIBLE_NAME, visible);
- self->title = visible;
+ if (!self->title || strcmp(self->title, visible)) {
+ OBT_PROP_SETS(self->window, NET_WM_VISIBLE_NAME, visible);
+ g_free(self->title);
+ self->title = visible;
+ } else
+ g_free(visible);
if (self->frame)
frame_adjust_title(self->frame);
/* update the icon title */
data = NULL;
- g_free(self->icon_title);
/* try netwm */
if (!OBT_PROP_GETS_UTF8(self->window, NET_WM_ICON_NAME, &data))
g_free(data);
}
- OBT_PROP_SETS(self->window, NET_WM_VISIBLE_ICON_NAME, visible);
- self->icon_title = visible;
+ if (!self->icon_title || strcmp(self->icon_title, visible)) {
+ OBT_PROP_SETS(self->window, NET_WM_VISIBLE_ICON_NAME, visible);
+ g_free(self->icon_title);
+ self->icon_title = visible;
+ } else
+ g_free(visible);
}
void client_update_strut(ObClient *self)
if (!self->icon_set && !self->parents) {
RrPixel32 *icon = ob_rr_theme->def_win_icon;
gulong *ldata; /* use a long here to satisfy OBT_PROP_SETA32 */
+ gint32 r,g,b;
+ r = g_random_int_range(0,255);
+ g = g_random_int_range(0,255);
+ b = g_random_int_range(0,255);
w = ob_rr_theme->def_win_icon_w;
h = ob_rr_theme->def_win_icon_h;
ldata[1] = h;
for (i = 0; i < w*h; ++i)
ldata[i+2] = (((icon[i] >> RrDefaultAlphaOffset) & 0xff) << 24) +
- (((icon[i] >> RrDefaultRedOffset) & 0xff) << 16) +
- (((icon[i] >> RrDefaultGreenOffset) & 0xff) << 8) +
- (((icon[i] >> RrDefaultBlueOffset) & 0xff) << 0);
+ ((((icon[i] >> RrDefaultRedOffset) & 0xff)*r/255) << 16) +
+ ((((icon[i] >> RrDefaultGreenOffset) & 0xff)*g/255) << 8) +
+ ((((icon[i] >> RrDefaultBlueOffset) & 0xff)*b/255) << 0);
OBT_PROP_SETA32(self->window, NET_WM_ICON, CARDINAL, ldata, w*h+2);
g_free(ldata);
} else if (self->frame)
static void client_change_state(ObClient *self)
{
- gulong netstate[12];
+ gulong netstate[13];
guint num;
num = 0;
netstate[num++] = OBT_PROP_ATOM(NET_WM_STATE_DEMANDS_ATTENTION);
if (self->undecorated)
netstate[num++] = OBT_PROP_ATOM(OB_WM_STATE_UNDECORATED);
+ if (self->locked)
+ netstate[num++] = OBT_PROP_ATOM(OB_WM_STATE_LOCKED);
OBT_PROP_SETA32(self->window, NET_WM_STATE, ATOM, netstate, num);
if (self->frame)
gboolean client_mouse_focusable(ObClient *self)
{
- return !(self->type == OB_CLIENT_TYPE_MENU ||
+ return !(/*self->type == OB_CLIENT_TYPE_MENU ||*/
self->type == OB_CLIENT_TYPE_TOOLBAR ||
self->type == OB_CLIENT_TYPE_SPLASH ||
self->type == OB_CLIENT_TYPE_DOCK);
frame_adjust_area(self->frame, FALSE, TRUE, TRUE);
/* cap any X windows at the size of an unsigned short */
+ /* actually make that a bit less, X shits itself on windows this large too */
*w = MIN(*w,
- (gint)G_MAXUSHORT
+ (gint)4096
- self->frame->size.left - self->frame->size.right);
*h = MIN(*h,
- (gint)G_MAXUSHORT
+ (gint)4096
- self->frame->size.top - self->frame->size.bottom);
/* gets the frame's position */
maxratio = self->fullscreen || (self->max_horz && self->max_vert) ?
0 : self->max_ratio;
+ /* XXX TODO FIXME these two fallbacks don't check that the fallback
+ * value itself is specified before using it */
/* base size is substituted with min size if not specified */
if (self->base_size.width >= 0 || self->base_size.height >= 0) {
basew = self->base_size.width;
gboolean shaded = self->shaded;
gboolean fullscreen = self->fullscreen;
gboolean undecorated = self->undecorated;
+ gboolean locked = self->locked;
gboolean max_horz = self->max_horz;
gboolean max_vert = self->max_vert;
gboolean modal = self->modal;
value = self->demands_attention;
else if (state == OBT_PROP_ATOM(OB_WM_STATE_UNDECORATED))
value = undecorated;
+ else if (state == OBT_PROP_ATOM(OB_WM_STATE_LOCKED))
+ value = locked;
else
g_assert_not_reached();
action = value ? OBT_PROP_ATOM(NET_WM_STATE_REMOVE) :
demands_attention = value;
} else if (state == OBT_PROP_ATOM(OB_WM_STATE_UNDECORATED)) {
undecorated = value;
+ } else if (state == OBT_PROP_ATOM(OB_WM_STATE_LOCKED)) {
+ locked = value;
}
}
client_shade(self, shaded);
if (undecorated != self->undecorated)
client_set_undecorated(self, undecorated);
+ if (locked != self->locked)
+ client_set_locked(self, locked);
if (above != self->above || below != self->below) {
self->above = above;
self->below = below;
{
if (!client_validate(self)) return FALSE;
+ {
+ XkbStateRec state;
+ XkbGetState(obt_display, XkbUseCoreKbd, &state);
+ if (state.locked_mods & 128)
+ return FALSE;
+ }
+
/* we might not focus this window, so if we have modal children which would
be focused instead, bring them to this desktop */
client_bring_modal_windows(self);
{
self = client_focus_target(self);
+ if (self->iconic && self->locked)
+ return;
+
if (client_can_steal_focus(self, desktop, user, event_time(), CurrentTime))
client_present(self, here, raise, unshade);
else
client_change_state(self); /* reflect this in the state hints */
}
+void client_set_locked(ObClient *self, gboolean locked)
+{
+ if (self->locked != locked) {
+ self->locked = locked;
+ client_change_state(self);
+ }
+}
+
void client_set_undecorated(ObClient *self, gboolean undecorated)
{
if (self->undecorated != undecorated &&
*/
guint functions;
+ /*! Prevent window from being accidentally acted upon */
+ gboolean locked;
+
/* The window's icon, in a variety of shapes and sizes */
RrImage *icon_set;
*/
void client_shade(ObClient *self, gboolean shade);
+/*! Set a client window to be locked or not */
+void client_set_locked(ObClient *self, gboolean locked);
+
/*! Set a client window to have decorations or not */
void client_set_undecorated(ObClient *self, gboolean undecorated);
ObMenu *menu = frame->menu;
ObMenuEntry *e;
GList *it;
- guint desktop;
+ guint desktop, desktop_it;
menu_clear_entries(menu);
- for (desktop = 0; desktop < screen_num_desktops; desktop++) {
+ for (desktop_it = 0; desktop_it < screen_num_desktops; desktop_it++) {
gboolean empty = TRUE;
gboolean onlyiconic = TRUE;
+ gboolean noicons = TRUE;
+
+ desktop = desktop_it;
+ if (desktop == 0)
+ desktop = screen_desktop;
+ else if (desktop <= screen_desktop)
+ desktop -= 1;
menu_add_separator(menu, SEPARATOR, screen_desktop_names[desktop]);
for (it = focus_order; it; it = g_list_next(it)) {
empty = FALSE;
if (c->iconic) {
- gchar *title = g_strdup_printf("(%s)", c->icon_title);
- e = menu_add_normal(menu, desktop, title, NULL, FALSE);
- g_free(title);
+ if (noicons) {
+ menu_add_separator(menu, -1, NULL);
+ noicons = FALSE;
+ }
+ e = menu_add_normal(menu, desktop, c->icon_title, NULL, FALSE);
} else {
onlyiconic = FALSE;
e = menu_add_normal(menu, desktop, c->title, NULL, FALSE);
}
else {
ObClient *t = self->data.normal.data;
- if (t) { /* it's set to NULL if its destroyed */
+ if (t && !t->locked) { /* it's set to NULL if its destroyed */
gboolean here = state & ShiftMask;
client_activate(t, TRUE, here, TRUE, TRUE, TRUE);
menu_set_update_func(combined_menu, self_update);
menu_set_cleanup_func(combined_menu, self_cleanup);
menu_set_execute_func(combined_menu, menu_execute);
+ combined_menu->warp = TRUE;
}
void client_list_combined_menu_shutdown(gboolean reconfig)
GList *it;
gboolean empty = TRUE;
gboolean onlyiconic = TRUE;
+ gboolean noicons = TRUE;
menu_clear_entries(menu);
empty = FALSE;
if (c->iconic) {
- gchar *title = g_strdup_printf("(%s)", c->icon_title);
- e = menu_add_normal(menu, d->desktop, title, NULL, FALSE);
- g_free(title);
+ if (noicons) {
+ menu_add_separator(menu, -1, NULL);
+ noicons = FALSE;
+ }
+ e = menu_add_normal(menu, d->desktop, c->icon_title, NULL, FALSE);
} else {
onlyiconic = FALSE;
e = menu_add_normal(menu, d->desktop, c->title, NULL, FALSE);
ObClient *c, guint state, gpointer data)
{
ObClient *t = self->data.normal.data;
- if (t) { /* it's set to NULL if its destroyed */
+ if (t && !t->locked) { /* it's set to NULL if its destroyed */
gboolean here = state & ShiftMask;
client_activate(t, TRUE, here, TRUE, TRUE, TRUE);
ObClient *c = frame->client;
if (e->type == OB_MENU_ENTRY_TYPE_NORMAL) {
+ if (c->locked) {
+ *en = FALSE;
+ continue;
+ }
switch (e->id) {
case CLIENT_ICONIFY:
*en = c->functions & OB_CLIENT_FUNC_ICONIFY;
menu_add_normal(menu, CLIENT_DECORATE, _("Un/_Decorate"), NULL, TRUE);
menu_add_separator(menu, -1, NULL);
+ menu_add_submenu(menu, 0, "client-list-menu");
+ menu_add_separator(menu, -1, NULL);
e = menu_add_normal(menu, CLIENT_CLOSE, _("_Close"), NULL, TRUE);
e->data.normal.mask = ob_rr_theme->btn_close->unpressed_mask;
GSList *config_desktops_names;
guint config_screen_firstdesk;
guint config_desktop_popup_time;
+gint config_emulate_xinerama;
gboolean config_resize_redraw;
gint config_resize_popup_show;
xmlNodePtr n;
gboolean is_chroot = FALSE;
gboolean grab = TRUE;
+ gboolean repeat = FALSE;
if (!obt_xml_attr_string(node, "key", &keystring))
return;
obt_xml_attr_bool(node, "chroot", &is_chroot);
obt_xml_attr_bool(node, "grab", &grab);
+ obt_xml_attr_bool(node, "repeat", &repeat);
keys = g_strsplit(keystring, " ", 0);
for (key = keys; *key; ++key) {
action = actions_parse(n);
if (action)
- keyboard_bind(keylist, action, grab);
+ keyboard_bind(keylist, action, grab, !repeat);
n = obt_xml_find_node(n->next, "action");
}
}
if ((n = obt_xml_find_node(node, "policy"))) {
if (obt_xml_node_contains(n, "UnderMouse"))
config_place_policy = OB_PLACE_POLICY_MOUSE;
+ if (obt_xml_node_contains(n, "Random"))
+ config_place_policy = OB_PLACE_POLICY_RANDOM;
}
if ((n = obt_xml_find_node(node, "center"))) {
config_place_center = obt_xml_node_bool(n);
}
if ((fnode = obt_xml_find_node(n->children, "size"))) {
int s = obt_xml_node_int(fnode);
- if (s > 0) size = s;
+ if (s > 0) {
+ size = s;
+ if (obt_xml_attr_contains(fnode, "type", "absolute"))
+ size = -size;
+ }
}
if ((fnode = obt_xml_find_node(n->children, "weight"))) {
gchar *w = obt_xml_node_string(fnode);
if (d > 0)
config_screen_firstdesk = (unsigned) d;
}
+ if ((n = obt_xml_find_node(node, "emulatexinerama")))
+ config_emulate_xinerama = obt_xml_node_bool(n);
if ((n = obt_xml_find_node(node, "names"))) {
GSList *it;
xmlNodePtr nname;
};
for (it = binds; it->key; ++it) {
GList *l = g_list_append(NULL, g_strdup(it->key));
- keyboard_bind(l, actions_parse_string(it->actname), TRUE);
+ keyboard_bind(l, actions_parse_string(it->actname), TRUE, TRUE);
}
}
config_desktops_num = 4;
config_screen_firstdesk = 1;
+ config_emulate_xinerama = FALSE;
config_desktops_names = NULL;
config_desktop_popup_time = 875;
extern guint config_desktops_num;
/*! Desktop to start on, put 5 to start in the center of a 3x3 grid */
extern guint config_screen_firstdesk;
+/*! Emulate xinerama by dividing screen in two halves, left and right. */
+extern gboolean config_emulate_xinerama;
/*! Names for the desktops */
extern GSList *config_desktops_names;
/*! Amount of time to show the desktop switch dialog */
--- /dev/null
+#include "openbox.h"
+#include "config.h"
+#include "screen.h"
+#include "edges.h"
+#include "frame.h"
+
+#include <X11/Xlib.h>
+#include <glib.h>
+
+/* Array of array of monitors of edges: edge[monitor 2][top edge] */
+ObEdge ***edge = NULL;
+#warning put in config.c and parse configs of course
+gboolean config_edge_enabled[OB_NUM_EDGES] = {1, 1, 1, 1, 1, 1, 1, 1};
+/* this could change at runtime, we should hook into that, but for now
+ * don't crash on reconfigure/shutdown */
+static guint edge_monitors;
+
+#ifdef DEBUG
+#define EDGE_WIDTH 10
+#define CORNER_SIZE 20
+#else
+#define EDGE_WIDTH 1
+#define CORNER_SIZE 2
+#endif
+static void get_position(ObEdgeLocation edge, Rect screen, Rect *rect)
+{
+ switch (edge) {
+ case OB_EDGE_TOP:
+ RECT_SET(*rect, CORNER_SIZE, 0,
+ screen.width - 2 * CORNER_SIZE, EDGE_WIDTH);
+ break;
+ case OB_EDGE_TOPRIGHT:
+ RECT_SET(*rect, screen.width - CORNER_SIZE, 0,
+ CORNER_SIZE, CORNER_SIZE);
+ break;
+ case OB_EDGE_RIGHT:
+ RECT_SET(*rect, screen.width - EDGE_WIDTH, CORNER_SIZE,
+ EDGE_WIDTH, screen.height - 2 * CORNER_SIZE);
+ break;
+ case OB_EDGE_BOTTOMRIGHT:
+ RECT_SET(*rect, screen.width - CORNER_SIZE,
+ screen.height - CORNER_SIZE,
+ CORNER_SIZE, CORNER_SIZE);
+ break;
+ case OB_EDGE_BOTTOM:
+ RECT_SET(*rect, CORNER_SIZE, screen.height - EDGE_WIDTH,
+ screen.width - 2 * CORNER_SIZE, EDGE_WIDTH);
+ break;
+ case OB_EDGE_BOTTOMLEFT:
+ RECT_SET(*rect, 0, screen.height - CORNER_SIZE,
+ CORNER_SIZE, CORNER_SIZE);
+ break;
+ case OB_EDGE_LEFT:
+ RECT_SET(*rect, 0, CORNER_SIZE,
+ EDGE_WIDTH, screen.height - 2 * CORNER_SIZE);
+ break;
+ case OB_EDGE_TOPLEFT:
+ RECT_SET(*rect, 0, 0, CORNER_SIZE, CORNER_SIZE);
+ break;
+ }
+ rect->x += screen.x;
+ rect->y += screen.y;
+}
+
+void edges_startup(gboolean reconfigure)
+{
+ ObEdgeLocation i;
+ gint m;
+ Rect r;
+ XSetWindowAttributes xswa;
+
+ xswa.override_redirect = True;
+
+ edge_monitors = screen_num_monitors;
+
+ edge = g_slice_alloc(sizeof(ObEdge**) * edge_monitors);
+ for (m = 0; m < edge_monitors; m++) {
+ const Rect *monitor = screen_physical_area_monitor(m);
+ edge[m] = g_slice_alloc(sizeof(ObEdge*) * OB_NUM_EDGES);
+ for (i=0; i < OB_NUM_EDGES; i++) {
+ if (!config_edge_enabled[i])
+ continue;
+
+ edge[m][i] = g_slice_new(ObEdge);
+ edge[m][i]->obwin.type = OB_WINDOW_CLASS_EDGE;
+ edge[m][i]->location = i;
+
+ get_position(i, *monitor, &r);
+ edge[m][i]->win = XCreateWindow(obt_display, obt_root(ob_screen),
+ r.x, r.y, r.width, r.height, 0, 0, InputOnly,
+ CopyFromParent, CWOverrideRedirect, &xswa);
+ XSelectInput(obt_display, edge[m][i]->win, ButtonPressMask | ButtonReleaseMask
+ | EnterWindowMask | LeaveWindowMask);
+ XMapWindow(obt_display, edge[m][i]->win);
+
+ stacking_add(EDGE_AS_WINDOW(edge[m][i]));
+ window_add(&edge[m][i]->win, EDGE_AS_WINDOW(edge[m][i]));
+
+#ifdef DEBUG
+ ob_debug("mapped edge window %i at %03i %03i %02i %02i", i, r.x, r.y, r.width, r.height);
+#endif
+ }
+ }
+
+ XFlush(obt_display);
+}
+
+void edges_shutdown(gboolean reconfigure)
+{
+ gint i, m;
+
+ /* This is in case we get called before startup by screen_resize() */
+ if (!edge)
+ return;
+
+ for (m = 0; m < edge_monitors; m++) {
+ for (i = 0; i < OB_NUM_EDGES; i++) {
+ if (!config_edge_enabled[i])
+ continue;
+
+ window_remove(edge[m][i]->win);
+ stacking_remove(EDGE_AS_WINDOW(edge[m][i]));
+ XDestroyWindow(obt_display, edge[m][i]->win);
+ g_slice_free(ObEdge, edge[m][i]);
+ }
+ g_slice_free1(sizeof(ObEdge*) * OB_NUM_EDGES, edge[m]);
+ }
+ g_slice_free1(sizeof(ObEdge**) * edge_monitors, edge);
+}
+
+void edges_configure()
+{
+ edges_shutdown(TRUE);
+ edges_startup(TRUE);
+}
--- /dev/null
+#ifndef __edges_h
+#define __edges_h
+
+#include "window.h"
+
+typedef enum
+{
+ OB_EDGE_TOP,
+ OB_EDGE_TOPRIGHT,
+ OB_EDGE_RIGHT,
+ OB_EDGE_BOTTOMRIGHT,
+ OB_EDGE_BOTTOM,
+ OB_EDGE_BOTTOMLEFT,
+ OB_EDGE_LEFT,
+ OB_EDGE_TOPLEFT,
+ OB_NUM_EDGES
+} ObEdgeLocation;
+
+typedef struct _ObEdge ObEdge;
+
+struct _ObEdge
+{
+ ObWindow obwin;
+ Window win;
+ ObEdgeLocation location;
+};
+
+void edges_startup(gboolean reconfigure);
+void edges_shutdown(gboolean reconfigure);
+void edges_configure(void);
+
+#endif
#include "grab.h"
#include "menu.h"
#include "prompt.h"
+#include "edges.h"
#include "menuframe.h"
#include "keyboard.h"
#include "mouse.h"
/*! The source time that started the current X event (user-provided, so not
to be trusted) */
static Time event_sourcetime = CurrentTime;
+/*! Last time the cursor moved out of the focused window */
+static Time client_left_focused = CurrentTime;
/*! The serial of the current X event */
static gulong event_curserial;
static guint unfocus_delay_timeout_id = 0;
static ObClient *unfocus_delay_timeout_client = NULL;
+extern guint button;
+
#ifdef USE_SM
static gboolean ice_handler(GIOChannel *source, GIOCondition cond,
gpointer conn)
IceAddConnectionWatch(ice_watch, NULL);
#endif
+#ifdef XKB
+ XkbSetDetectableAutoRepeat(obt_display, True, NULL);
+#endif
+
client_add_destroy_notify(focus_delay_client_dest, NULL);
}
case OB_WINDOW_CLASS_MENUFRAME:
menu = WINDOW_AS_MENUFRAME(obwin);
break;
- case OB_WINDOW_CLASS_INTERNAL:
- /* we don't do anything with events directly on these windows */
- break;
case OB_WINDOW_CLASS_PROMPT:
prompt = WINDOW_AS_PROMPT(obwin);
break;
/* ...or it if it was physically on an openbox
internal window... */
((w = window_find(e->xbutton.subwindow)) &&
- (WINDOW_IS_INTERNAL(w) || WINDOW_IS_DOCK(w))))
+ (WINDOW_IS_INTERNAL(w) || WINDOW_IS_DOCK(w) || WINDOW_IS_EDGE(w))))
/* ...then process the event, otherwise ignore it */
{
used = event_handle_user_input(client, e);
if (e->type == ButtonPress)
pressed = e->xbutton.button;
+ /* We ignored the release event so make sure we don't think
+ the button is still pressed */
+ else if (e->type == ButtonRelease)
+ button = 0;
}
}
else if (e->type == KeyPress || e->type == KeyRelease ||
ob_debug_type(OB_DEBUG_FOCUS, "using enter event with serial %lu "
"on client 0x%x", event_curserial, client->window);
- if (client_enter_focusable(client) && client_can_focus(client)) {
+ if (client_enter_focusable(client) && client_can_focus(client) && (!config_focus_delay || (!client_left_focused || event_time_after(client_left_focused, event_curtime - config_focus_delay /*milliseconds here, so not *1000 */)))) {
if (config_focus_delay) {
ObFocusDelayData *data;
g_source_remove(focus_delay_timeout_id);
if (config_unfocus_leave)
event_leave_client(client);
+ else if (client == focus_client)
+ client_left_focused = e->xcrossing.time;
}
break;
default:
}
case ConfigureRequest:
{
+ if (client->locked)
+ break;
+
/* dont compress these unless you're going to watch for property
notifies in between (these can change what the configure would
do to the window).
msgtype = e->xclient.message_type;
if (msgtype == OBT_PROP_ATOM(WM_CHANGE_STATE)) {
if (!more_client_message_event(client->window, msgtype))
- client_set_wm_state(client, e->xclient.data.l[0]);
+ if (!client->locked)
+ client_set_wm_state(client, e->xclient.data.l[0]);
} else if (msgtype == OBT_PROP_ATOM(NET_WM_DESKTOP)) {
if (!more_client_message_event(client->window, msgtype) &&
((unsigned)e->xclient.data.l[0] < screen_num_desktops ||
e->xclient.data.l[1], e->xclient.data.l[2],
client->window);
- /* ignore enter events caused by these like ob actions do */
- if (!config_focus_under_mouse)
- ignore_start = event_start_ignore_all_enters();
- client_set_state(client, e->xclient.data.l[0],
- e->xclient.data.l[1], e->xclient.data.l[2]);
- if (!config_focus_under_mouse)
- event_end_ignore_all_enters(ignore_start);
+ if (!client->locked) {
+ /* ignore enter events caused by these like ob actions do */
+ if (!config_focus_under_mouse)
+ ignore_start = event_start_ignore_all_enters();
+ client_set_state(client, e->xclient.data.l[0],
+ e->xclient.data.l[1], e->xclient.data.l[2]);
+ if (!config_focus_under_mouse)
+ event_end_ignore_all_enters(ignore_start);
+ }
} else if (msgtype == OBT_PROP_ATOM(NET_CLOSE_WINDOW)) {
ob_debug("net_close_window for 0x%lx", client->window);
- client_close(client);
+ if (!client->locked)
+ client_close(client);
} else if (msgtype == OBT_PROP_ATOM(NET_ACTIVE_WINDOW)) {
ob_debug("net_active_window for 0x%lx source=%s",
client->window,
So we are left just assuming all activations are from the user.
*/
client_activate(client, FALSE, FALSE, TRUE, TRUE, TRUE);
+ } else if (msgtype == OBT_PROP_ATOM(OB_FOCUS)) {
+ client_focus(client);
} else if (msgtype == OBT_PROP_ATOM(NET_WM_MOVERESIZE)) {
ob_debug("net_wm_moveresize for 0x%lx direction %d",
client->window, e->xclient.data.l[2]);
(Atom)e->xclient.data.l[2] ==
OBT_PROP_ATOM(NET_WM_MOVERESIZE_MOVE_KEYBOARD))
{
- moveresize_start(client, e->xclient.data.l[0],
- e->xclient.data.l[1], e->xclient.data.l[3],
- e->xclient.data.l[2]);
+ if (!client->locked)
+ moveresize_start(client, e->xclient.data.l[0],
+ e->xclient.data.l[1], e->xclient.data.l[3],
+ e->xclient.data.l[2]);
}
else if ((Atom)e->xclient.data.l[2] ==
OBT_PROP_ATOM(NET_WM_MOVERESIZE_CANCEL))
if (moveresize_client)
moveresize_end(TRUE);
} else if (msgtype == OBT_PROP_ATOM(NET_MOVERESIZE_WINDOW)) {
+ if (client->locked)
+ break;
+
gint ograv, x, y, w, h;
ograv = client->gravity;
window_add(&focus_indicator.bottom.window,
INTERNAL_AS_WINDOW(&focus_indicator.bottom));
- color_white = RrColorNew(ob_rr_inst, 0xff, 0xff, 0xff);
+ color_white = RrColorNew(ob_rr_inst, 0x00, 0x00, 0xff);
a_focus_indicator = RrAppearanceNew(ob_rr_inst, 4);
a_focus_indicator->surface.grad = RR_SURFACE_SOLID;
a_focus_indicator->surface.relief = RR_RELIEF_FLAT;
a_focus_indicator->surface.primary = RrColorNew(ob_rr_inst,
- 0, 0, 0);
+ 0xA6, 0xCA, 0xF4);
a_focus_indicator->texture[0].type = RR_TEXTURE_LINE_ART;
a_focus_indicator->texture[0].data.lineart.color = color_white;
a_focus_indicator->texture[1].type = RR_TEXTURE_LINE_ART;
#include "focus_cycle_indicator.h"
#include "moveresize.h"
#include "screen.h"
+#include "edges.h"
#include "obrender/theme.h"
#include "obt/display.h"
#include "obt/xqueue.h"
return OB_FRAME_CONTEXT_MOVE_RESIZE;
else if (!g_ascii_strcasecmp("Dock", name))
return OB_FRAME_CONTEXT_DOCK;
+ else if (!g_ascii_strcasecmp("ScreenTop", name))
+ return OB_FRAME_CONTEXT_EDGE_TOP;
+ else if (!g_ascii_strcasecmp("ScreenTopRight", name))
+ return OB_FRAME_CONTEXT_EDGE_TOPRIGHT;
+ else if (!g_ascii_strcasecmp("ScreenRight", name))
+ return OB_FRAME_CONTEXT_EDGE_RIGHT;
+ else if (!g_ascii_strcasecmp("ScreenBottomRight", name))
+ return OB_FRAME_CONTEXT_EDGE_BOTTOMRIGHT;
+ else if (!g_ascii_strcasecmp("ScreenBottom", name))
+ return OB_FRAME_CONTEXT_EDGE_BOTTOM;
+ else if (!g_ascii_strcasecmp("ScreenBottomLeft", name))
+ return OB_FRAME_CONTEXT_EDGE_BOTTOMLEFT;
+ else if (!g_ascii_strcasecmp("ScreenLeft", name))
+ return OB_FRAME_CONTEXT_EDGE_LEFT;
+ else if (!g_ascii_strcasecmp("ScreenTopLeft", name))
+ return OB_FRAME_CONTEXT_EDGE_TOPLEFT;
return OB_FRAME_CONTEXT_NONE;
}
if (moveresize_in_progress)
return OB_FRAME_CONTEXT_MOVE_RESIZE;
-
if (win == obt_root(ob_screen))
return OB_FRAME_CONTEXT_ROOT;
if ((obwin = window_find(win))) {
if (WINDOW_IS_DOCK(obwin)) {
return OB_FRAME_CONTEXT_DOCK;
+ } else if (WINDOW_IS_EDGE(obwin)) {
+ ObEdge *edge = (ObEdge *)obwin;
+ return OB_FRAME_CONTEXT_EDGE_TOP + edge->location;
}
}
if (client == NULL) return OB_FRAME_CONTEXT_NONE;
a move/resize */
OB_FRAME_CONTEXT_MOVE_RESIZE,
OB_FRAME_CONTEXT_DOCK,
+ OB_FRAME_CONTEXT_EDGE_TOP,
+ OB_FRAME_CONTEXT_EDGE_TOPRIGHT,
+ OB_FRAME_CONTEXT_EDGE_RIGHT,
+ OB_FRAME_CONTEXT_EDGE_BOTTOMRIGHT,
+ OB_FRAME_CONTEXT_EDGE_BOTTOM,
+ OB_FRAME_CONTEXT_EDGE_BOTTOMLEFT,
+ OB_FRAME_CONTEXT_EDGE_LEFT,
+ OB_FRAME_CONTEXT_EDGE_TOPLEFT,
OB_FRAME_NUM_CONTEXTS
} ObFrameContext;
static ObPopup *popup = NULL;
static KeyBindingTree *curpos;
static guint chain_timer = 0;
+static guint repeat_key = 0;
static void grab_keys(gboolean grab)
{
chroot binding. so add it to the tree then. */
if (!tree_chroot(keyboard_firstnode, keylist)) {
KeyBindingTree *tree;
- if (!(tree = tree_build(keylist, TRUE)))
+ if (!(tree = tree_build(keylist, TRUE, TRUE)))
return;
tree_chroot(tree, keylist);
tree_assimilate(tree);
}
}
-gboolean keyboard_bind(GList *keylist, ObActionsAct *action, gboolean grab)
+gboolean keyboard_bind(GList *keylist, ObActionsAct *action, gboolean grab, gboolean no_repeat)
{
KeyBindingTree *tree, *t;
gboolean conflict;
g_assert(keylist != NULL);
g_assert(action != NULL);
- if (!(tree = tree_build(keylist, grab)))
+ if (!(tree = tree_build(keylist, grab, no_repeat)))
return FALSE;
if ((t = tree_find(tree, &conflict)) != NULL) {
KeyBindingTree *p;
gboolean used;
guint mods;
+ gboolean repeating = FALSE;
+
+ ob_debug("Saved key: %d, %sed key: %d", repeat_key, e->type == KeyPress ? "press" : "releas", e->xkey.keycode);
if (e->type == KeyRelease) {
grab_key_passive_count(-1);
+ repeat_key = 0;
return FALSE;
}
g_assert(e->type == KeyPress);
grab_key_passive_count(1);
+ if (repeat_key == e->xkey.keycode)
+ repeating = TRUE;
+ else
+ repeat_key = e->xkey.keycode;
+
mods = obt_keyboard_only_modmasks(e->xkey.state);
if (e->xkey.keycode == config_keyboard_reset_keycode &&
else
p = curpos->first_child;
while (p) {
- if (p->key == e->xkey.keycode && p->state == mods) {
+ if (p->key == e->xkey.keycode && p->state == mods && !(p->no_repeat && repeating)) {
/* if we hit a key binding, then close any open menus and run it */
if (menu_frame_visible)
menu_frame_hide_all();
if (it == NULL) /* reset if the actions are not interactive */
keyboard_reset_chains(0);
- actions_run_acts(p->actions, OB_USER_ACTION_KEYBOARD_KEY,
+ actions_run_acts(p->actions,
+ p->no_repeat ? OB_USER_ACTION_KEYBOARD_KEY_NO_REPEAT
+ : OB_USER_ACTION_KEYBOARD_KEY,
e->xkey.state, e->xkey.x_root, e->xkey.y_root,
0, OB_FRAME_CONTEXT_NONE, client);
}
while (node->actions) {
/* add each action, and remove them from the original tree so
they don't get free'd on us */
- keyboard_bind(node->keylist, node->actions->data, node->grab);
+ keyboard_bind(node->keylist, node->actions->data, node->grab, node->no_repeat);
node->actions = g_slist_delete_link(node->actions, node->actions);
}
grab_keys(TRUE);
popup = popup_new();
popup_set_text_align(popup, RR_JUSTIFY_CENTER);
+ repeat_key = 0;
}
void keyboard_shutdown(gboolean reconfig)
void keyboard_rebind(void);
void keyboard_chroot(GList *keylist);
-gboolean keyboard_bind(GList *keylist, struct _ObActionsAct *action, gboolean grab);
+gboolean keyboard_bind(GList *keylist, struct _ObActionsAct *action, gboolean grab, gboolean no_repeat);
void keyboard_unbind_all(void);
gboolean keyboard_event(struct _ObClient *client, const XEvent *e);
}
}
-KeyBindingTree *tree_build(GList *keylist, gboolean grab)
+KeyBindingTree *tree_build(GList *keylist, gboolean grab, gboolean no_repeat)
{
GList *it;
KeyBindingTree *ret = NULL, *p;
g_strdup(kit->data)); /* deep copy */
ret->first_child = p;
ret->grab = grab;
+ ret->no_repeat = no_repeat;
if (p != NULL) p->parent = ret;
translate_key(it->data, &ret->state, &ret->key);
}
typedef struct KeyBindingTree {
guint state;
guint key;
+ gboolean no_repeat;
gboolean grab;
GList *keylist;
GSList *actions; /* list of Action pointers */
} KeyBindingTree;
void tree_destroy(KeyBindingTree *tree);
-KeyBindingTree *tree_build(GList *keylist, gboolean grab);
+KeyBindingTree *tree_build(GList *keylist, gboolean grab, gboolean no_repeat);
void tree_assimilate(KeyBindingTree *node);
KeyBindingTree *tree_find(KeyBindingTree *search, gboolean *conflict);
gboolean tree_chroot(KeyBindingTree *tree, GList *keylist);
ObMenuDestroyFunc destroy_func;
ObMenuPlaceFunc place_func;
+ gboolean warp;
+
/* Pipe-menu parent, we get destroyed when it is destroyed */
ObMenu *pipe_creator;
#include "obt/keyboard.h"
#include "obrender/theme.h"
-#define PADDING 2
+#define PADDING 0
#define MAX_MENU_WIDTH 400
#define ITEM_HEIGHT (ob_rr_theme->menu_font_height + 2*PADDING)
return;
if (config_menu_middle) {
- gint myx;
- myx = *x;
- *y -= self->area.height / 2;
+ *x -= self->area.width / 2;
- /* try to the right of the cursor */
- menu_frame_move_on_screen(self, myx, *y, &dx, &dy);
+ /* try below the cursor */
+ menu_frame_move_on_screen(self, *x, *y, &dx, &dy);
self->direction_right = TRUE;
- if (dx != 0) {
- /* try to the left of the cursor */
- myx = *x - self->area.width;
- menu_frame_move_on_screen(self, myx, *y, &dx, &dy);
- self->direction_right = FALSE;
- }
- if (dx != 0) {
- /* if didnt fit on either side so just use what it says */
- myx = *x;
- menu_frame_move_on_screen(self, myx, *y, &dx, &dy);
- self->direction_right = TRUE;
- }
- *x = myx + dx;
- *y += dy;
+ *x += dx;
+ *y += dy+1;
} else {
gint myx, myy;
h += th;
}
+ w += 20;
+
/* if the last entry is a labeled separator, then make its border
overlap with the menu's outside border */
it = g_list_last(self->entries);
}
menu_frame_move(self, x, y);
-
XMapWindow(obt_display, self->window);
if (screen_pointer_pos(&px, &py)) {
- ObMenuEntryFrame *e = menu_entry_frame_under(px, py);
- if (e && e->frame == self)
- e->ignore_enters++;
+
+ if (self->menu->warp) {
+ x += self->area.width / 2;
+ y += 67;
+ XWarpPointer(obt_display, None, obt_root(ob_screen), 0, 0, 0, 0, x, y);
+ self->ox = px;
+ self->oy = py;
+ } else {
+ ObMenuEntryFrame *e = menu_entry_frame_under(px, py);
+ if (e && e->frame == self)
+ e->ignore_enters++;
+ }
}
+
return TRUE;
}
if (self->child)
menu_frame_hide(self->child);
+ if (!self->parent && self->menu->warp)
+ XWarpPointer(obt_display, None, obt_root(ob_screen), 0, 0, 0, 0, self->ox, self->oy);
+
if (self->parent) {
remove_submenu_hide_timeout(self);
/* The client that the visual instance of the menu is associated with for
its actions */
struct _ObClient *client;
+ gint ox, oy;
ObMenuFrame *parent;
ObMenuEntryFrame *parent_entry;
typedef enum {
OB_USER_ACTION_NONE, /* being fired from inside another action and such */
OB_USER_ACTION_KEYBOARD_KEY,
+ OB_USER_ACTION_KEYBOARD_KEY_NO_REPEAT,
OB_USER_ACTION_MOUSE_PRESS,
OB_USER_ACTION_MOUSE_RELEASE,
OB_USER_ACTION_MOUSE_CLICK,
to send it to other applications */
static gboolean replay_pointer_needed;
+guint button;
+
ObFrameContext mouse_button_frame_context(ObFrameContext context,
guint button,
guint state)
gboolean mouse_event(ObClient *client, XEvent *e)
{
static Time ltime;
- static guint button = 0, state = 0, lbutton = 0;
+ static guint state = 0, lbutton = 0;
static Window lwindow = None;
static gint px, py, pwx = -1, pwy = -1, lx = -10, ly = -10;
gboolean used = FALSE;
if (ABS(e->xmotion.x_root - px) >= config_mouse_threshold ||
ABS(e->xmotion.y_root - py) >= config_mouse_threshold) {
- /* You can't drag on buttons */
- if (context == OB_FRAME_CONTEXT_MAXIMIZE ||
- context == OB_FRAME_CONTEXT_ALLDESKTOPS ||
- context == OB_FRAME_CONTEXT_SHADE ||
- context == OB_FRAME_CONTEXT_ICONIFY ||
- context == OB_FRAME_CONTEXT_ICON ||
- context == OB_FRAME_CONTEXT_CLOSE)
- break;
-
used = fire_binding(OB_MOUSE_ACTION_MOTION, context,
client, state, button, px, py);
button = 0;
moveresize_in_progress = TRUE;
waiting_for_sync = 0;
+ if (moving)
+ do_move(FALSE, 0);
+ else
+ do_resize();
+
#ifdef SYNC
if (config_resize_redraw && !moving && obt_display_extension_sync &&
moveresize_client->sync_request && moveresize_client->sync_counter &&
#include "openbox.h"
#include "session.h"
#include "dock.h"
+#include "edges.h"
#include "event.h"
#include "menu.h"
#include "client.h"
static Cursor load_cursor(const gchar *name, guint fontval);
static void run_startup_cmd(void);
+#if 0
+gboolean haxxor_func(gpointer data)
+{
+ int *foo = data;
+ static int dir = 1;
+ *foo += dir;
+ if (*foo >= 200 || *foo <= 0)
+ dir = -dir;
+
+ Colormap cm = RrColormap(ob_rr_inst);
+ static XColor xcb, xcg;
+ xcg.red = *foo << 8;
+ xcg.blue = (*foo / 4) << 8;
+ xcg.green = *foo / 2 << 8;
+
+ xcb.red = 0;
+ xcb.blue = (196 - *foo / 4) << 8;
+ xcb.green = 0;
+ XAllocColor(ob_display, cm, &xcg);
+ XAllocColor(ob_display, cm, &xcb);
+// XAllocNamedColor(ob_display, cm, "dark blue", &xcb, &xcb);
+ static int i;
+ for (i = 1; i <= OB_CURSOR_NORTHWEST; i++)
+ XRecolorCursor(ob_display, cursors[i], &xcb, &xcg);
+
+ return TRUE;
+}
+#endif
+
gint main(gint argc, gchar **argv)
{
gchar *program_name;
cursors[OB_CURSOR_WEST] = load_cursor("left_side", XC_left_side);
cursors[OB_CURSOR_NORTHWEST] = load_cursor("top_left_corner",
XC_top_left_corner);
+#if 0
+ int color = 0;
+ ob_main_loop_timeout_add(ob_main_loop,
+ 25000,
+ haxxor_func,
+ &color, NULL);
+#endif
if (screen_annex()) { /* it will be ours! */
mouse_startup(reconfigure);
menu_frame_startup(reconfigure);
menu_startup(reconfigure);
+ edges_startup(reconfigure);
prompt_startup(reconfigure);
if (!reconfigure) {
window_unmanage_all();
prompt_shutdown(reconfigure);
+ edges_shutdown(reconfigure);
menu_shutdown(reconfigure);
menu_frame_shutdown(reconfigure);
mouse_shutdown(reconfigure);
typedef enum
{
OB_PLACE_POLICY_SMART,
+ OB_PLACE_POLICY_RANDOM,
OB_PLACE_POLICY_MOUSE
} ObPlacePolicy;
/* don't snap to self or non-visibles */
if (!target->frame->visible || target == c)
continue;
- /* don't snap to windows set to below and skip_taskbar (desklets) */
- if (target->below && !c->below && target->skip_taskbar)
- continue;
if (resist_move_window(c->frame->area, target->frame->area,
resist, x, y))
/* don't snap to invisibles or ourself */
if (!target->frame->visible || target == c)
continue;
- /* don't snap to windows set to below and skip_taskbar (desklets) */
- if (target->below && !c->below && target->skip_taskbar)
- continue;
if (resist_size_window(c->frame->area, target->frame->area,
resist, w, h, dir))
#include "debug.h"
#include "openbox.h"
#include "dock.h"
+#include "edges.h"
#include "grab.h"
#include "startupnotify.h"
#include "moveresize.h"
static gboolean screen_validate_layout(ObDesktopLayout *l);
static gboolean replace_wm(void);
-static void screen_tell_ksplash(void);
+//static void screen_tell_ksplash(void);
static void screen_fallback_focus(void);
guint screen_num_desktops;
/* create the netwm support window */
attrib.override_redirect = TRUE;
- attrib.event_mask = PropertyChangeMask;
+ attrib.event_mask = PropertyChangeMask | KeyPressMask | KeyReleaseMask;
screen_support_win = XCreateWindow(obt_display, obt_root(ob_screen),
-100, -100, 1, 1, 0,
CopyFromParent, InputOutput,
supported[i++] = OBT_PROP_ATOM(KDE_NET_WM_FRAME_STRUT);
supported[i++] = OBT_PROP_ATOM(KDE_NET_WM_WINDOW_TYPE_OVERRIDE);
+ supported[i++] = OBT_PROP_ATOM(OB_FOCUS);
supported[i++] = OBT_PROP_ATOM(OB_WM_ACTION_UNDECORATE);
supported[i++] = OBT_PROP_ATOM(OB_WM_STATE_UNDECORATED);
+ supported[i++] = OBT_PROP_ATOM(OB_WM_STATE_LOCKED);
supported[i++] = OBT_PROP_ATOM(OPENBOX_PID);
supported[i++] = OBT_PROP_ATOM(OB_THEME);
supported[i++] = OBT_PROP_ATOM(OB_CONFIG_FILE);
+ supported[i++] = OBT_PROP_ATOM(OB_LAST_DESKTOP);
supported[i++] = OBT_PROP_ATOM(OB_CONTROL);
supported[i++] = OBT_PROP_ATOM(OB_VERSION);
supported[i++] = OBT_PROP_ATOM(OB_APP_ROLE);
supported[i++] = OBT_PROP_ATOM(OB_APP_GROUP_NAME);
supported[i++] = OBT_PROP_ATOM(OB_APP_GROUP_CLASS);
supported[i++] = OBT_PROP_ATOM(OB_APP_TYPE);
+ supported[i++] = OBT_PROP_ATOM(OB_TARGET_WINDOW);
g_assert(i == num_support);
OBT_PROP_SETA32(obt_root(ob_screen),
OBT_PROP_SETS(RootWindow(obt_display, ob_screen), OB_VERSION,
OPENBOX_VERSION);
- screen_tell_ksplash();
+ //screen_tell_ksplash();
return TRUE;
}
-
+#if 0
static void screen_tell_ksplash(void)
{
XEvent e;
XSendEvent(obt_display, obt_root(ob_screen),
False, SubstructureNotifyMask, &e);
}
-
+#endif
void screen_startup(gboolean reconfig)
{
gchar **names = NULL;
gboolean namesexist = FALSE;
desktop_popup = pager_popup_new();
+ desktop_popup->popup->a_text->texture[0].data.text.font = ob_rr_theme->menu_title_font;
desktop_popup_perm = FALSE;
pager_popup_height(desktop_popup, POPUP_HEIGHT);
else
screen_set_desktop(MIN(config_screen_firstdesk,
screen_num_desktops) - 1, FALSE);
- screen_last_desktop = screen_desktop;
+ OBT_PROP_GET32(obt_root(ob_screen), OB_LAST_DESKTOP, CARDINAL, &screen_last_desktop);
+ if (screen_last_desktop < 0 || screen_last_desktop >= screen_num_desktops) {
+ screen_last_desktop = screen_desktop;
+ OBT_PROP_SET32(obt_root(ob_screen), OB_LAST_DESKTOP, CARDINAL, screen_last_desktop);
+ }
/* don't start in showing-desktop mode */
screen_show_desktop_mode = SCREEN_SHOW_DESKTOP_NO;
/* this calls screen_update_areas(), which we need ! */
dock_configure();
+ edges_configure();
- for (it = client_list; it; it = g_list_next(it)) {
- client_move_onscreen(it->data, FALSE);
- client_reconfigure(it->data, FALSE);
- }
+ // bug: this is done in screen_update_areas() already
+// for (it = client_list; it; it = g_list_next(it)) {
+// client_move_onscreen(it->data, FALSE);
+// client_reconfigure(it->data, FALSE);
+// }
}
void screen_set_num_desktops(guint num)
static gboolean last_desktop_func(gpointer data)
{
screen_desktop_timeout = TRUE;
+ OBT_PROP_SET32(obt_root(ob_screen), OB_LAST_DESKTOP, CARDINAL, screen_last_desktop);
screen_desktop_timer = 0;
return FALSE; /* don't repeat */
}
*xin_areas = g_new(Rect, *nxin + 1);
RECT_SET((*xin_areas)[0], 0, 0, w/2, h);
RECT_SET((*xin_areas)[1], w/2, 0, w-(w/2), h);
+ } else if (config_emulate_xinerama) {
+ *nxin = 2;
+ *xin_areas = g_new(Rect, *nxin + 1);
+ RECT_SET((*xin_areas)[0], 0, 0,
+ WidthOfScreen(ScreenOfDisplay(obt_display, ob_screen)) / 2,
+ HeightOfScreen(ScreenOfDisplay(obt_display, ob_screen)));
+ RECT_SET((*xin_areas)[1],
+ WidthOfScreen(ScreenOfDisplay(obt_display, ob_screen)) / 2,
+ 0,
+ WidthOfScreen(ScreenOfDisplay(obt_display, ob_screen)) / 2,
+ HeightOfScreen(ScreenOfDisplay(obt_display, ob_screen)));
+ RECT_SET((*xin_areas)[*nxin], 0, 0,
+ WidthOfScreen(ScreenOfDisplay(obt_display, ob_screen)),
+ HeightOfScreen(ScreenOfDisplay(obt_display, ob_screen)));
}
#ifdef XINERAMA
else if (obt_display_extension_xinerama &&
{
if (sn_app_starting())
XDefineCursor(obt_display, obt_root(ob_screen),
- ob_cursor(OB_CURSOR_BUSYPOINTER));
+ ob_cursor(OB_CURSOR_BUSY));
else
XDefineCursor(obt_display, obt_root(ob_screen),
ob_cursor(OB_CURSOR_POINTER));
#include "frame.h"
#include "openbox.h"
#include "prompt.h"
+#include "edges.h"
#include "debug.h"
#include "grab.h"
#include "obt/prop.h"
return WINDOW_AS_INTERNAL(self)->window;
case OB_WINDOW_CLASS_PROMPT:
return WINDOW_AS_PROMPT(self)->super.window;
+ case OB_WINDOW_CLASS_EDGE:
+ return WINDOW_AS_EDGE(self)->win;
}
g_assert_not_reached();
return None;
return config_dock_layer;
case OB_WINDOW_CLASS_CLIENT:
return ((ObClient*)self)->layer;
+ case OB_WINDOW_CLASS_EDGE:
case OB_WINDOW_CLASS_MENUFRAME:
case OB_WINDOW_CLASS_INTERNAL:
return OB_STACKING_LAYER_INTERNAL;
OB_WINDOW_CLASS_DOCK,
OB_WINDOW_CLASS_CLIENT,
OB_WINDOW_CLASS_INTERNAL,
- OB_WINDOW_CLASS_PROMPT
+ OB_WINDOW_CLASS_PROMPT,
+ OB_WINDOW_CLASS_EDGE
} ObWindowClass;
/* In order to be an ObWindow, you need to make this struct the top of your
(((ObWindow*)win)->type == OB_WINDOW_CLASS_INTERNAL)
#define WINDOW_IS_PROMPT(win) \
(((ObWindow*)win)->type == OB_WINDOW_CLASS_PROMPT)
+#define WINDOW_IS_EDGE(win) \
+ (((ObWindow*)win)->type == OB_WINDOW_CLASS_EDGE)
struct _ObMenu;
struct _ObDock;
#define WINDOW_AS_CLIENT(win) ((struct _ObClient*)win)
#define WINDOW_AS_INTERNAL(win) ((struct _ObInternalWindow*)win)
#define WINDOW_AS_PROMPT(win) ((struct _ObPrompt*)win)
+#define WINDOW_AS_EDGE(win) ((struct _ObEdge*)win)
#define MENUFRAME_AS_WINDOW(menu) ((ObWindow*)menu)
#define DOCK_AS_WINDOW(dock) ((ObWindow*)dock)
#define CLIENT_AS_WINDOW(client) ((ObWindow*)client)
#define INTERNAL_AS_WINDOW(intern) ((ObWindow*)intern)
#define PROMPT_AS_WINDOW(prompt) ((ObWindow*)prompt)
+#define EDGE_AS_WINDOW(edge) ((ObWindow*)edge)
void window_startup (gboolean reconfig);
void window_shutdown(gboolean reconfig);
openbox/actions.c
openbox/actions/execute.c
openbox/actions/exit.c
+openbox/actions/sendkeyevent.c
openbox/client.c
openbox/client_list_combined_menu.c
openbox/client_list_menu.c
#include <stdio.h>
#include <assert.h>
#include <glib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
Window findClient(Display *d, Window win)
{
XPutImage(d, p, DefaultGC(d, s), i[j], 0, 0, x, 0,
i[j]->width, i[j]->height);
x += i[j]->width;
+ char *filename;
+ asprintf(&filename, "icon%i.raw", j);
+ int fd = open(filename, O_CREAT | O_RDWR);
+ write(fd, i[j]->data, i[j]->width * i[j]->height * i[j]->depth);
XDestroyImage(i[j]);
}
XDestroyWindow(display, win);
XSync(display, False);
- break;
- sleep(2);
+ //break;
+ usleep(200000);
}
return 1;
Display *display;
Window win;
XEvent report;
- Atom _net_fs, _net_state;
XEvent msg;
int x=50,y=50,h=100,w=400;
XWMHints hint;
return 0;
}
- _net_state = XInternAtom(display, "_NET_WM_STATE", False);
- _net_fs = XInternAtom(display, "_NET_WM_STATE_FULLSCREEN", False);
-
win = XCreateWindow(display, RootWindow(display, 0),
x, y, w, h, 10, CopyFromParent, CopyFromParent,
CopyFromParent, 0, NULL);