You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

5453 lines
135 KiB

Index: b/Makefile.am
===================================================================
--- a/Makefile.am 2013-08-04 15:22:35.000000000 +0200
+++ b/Makefile.am 2013-08-04 15:28:01.000000000 +0200
@@ -1,4 +1,4 @@
-SUBDIRS = include src libdecoration plugins images gtk kde po metadata
+SUBDIRS = include src libdecoration plugins images gtk kde tde po metadata
EXTRA_DIST = \
COPYING \
Index: b/configure.ac
===================================================================
--- a/configure.ac 2013-08-04 14:34:02.000000000 +0200
+++ b/configure.ac 2013-08-04 17:53:01.000000000 +0200
@@ -565,6 +565,114 @@
kcfgdir=$KDE_KCFG_DIR
AC_SUBST(kcfgdir)
+AC_ARG_ENABLE(tde,
+ [ --disable-tde Disable TDE window decorator],
+ [use_tde=$enableval], [use_tde=yes])
+
+if test "x$use_tde" = "xyes"; then
+ tqt_incdirs="$QTINC /usr/local/qt/include /usr/include/qt /usr/include /usr/X11R6/include/X11/qt /usr/X11R6/include/qt /usr/lib/tqt3/include /usr/lib/qt/include /usr/share/tqt3/include"
+ tqt_libdirs="$QTLIB /usr/local/qt/lib /usr/lib/qt /usr/lib /usr/X11R6/lib/X11/qt /usr/X11R6/lib/qt /usr/lib/tqt3/lib /usr/lib/qt/lib /usr/share/tqt3/lib"
+
+ if test -n "$QTDIR" ; then
+ tqt_incdirs="$QTDIR/include $tqt_incdirs"
+ tqt_libdirs="$QTDIR/lib $tqt_libdirs"
+ fi
+
+ tqt_test_include="ntqstyle.h"
+ tqt_test_library="libtqt-mt.so"
+
+ dnl Check for TQt headers
+ AC_MSG_CHECKING([for TQt headers])
+ tqt_incdir="no"
+ for it in $tqt_incdirs ; do
+ if test -r "$it/$tqt_test_include" ; then
+ tqt_incdir="$it"
+ break
+ fi
+ done
+ AC_MSG_RESULT([$tqt_incdir])
+
+ dnl Check for TQt libraries
+ AC_MSG_CHECKING([for TQt libraries])
+ tqt_libdir="no"
+ for tqt_check in $tqt_libdirs ; do
+ if test -r "$tqt_check/$tqt_test_library" ; then
+ tqt_libdir="$tqt_check"
+ break
+ fi
+ done
+ AC_MSG_RESULT([$tqt_libdir])
+
+ use_tde=no;
+ if test "x$tqt_libdir" != "xno" ; then
+ if test "x$tqt_incdir" != "xno" ; then
+ use_tde=yes;
+ fi
+ fi
+
+ TQT_CXXFLAGS="-I$tqt_incdir"
+ TQT_LIBS="-L$tqt_libdir"
+
+ if test "x$use_tde" = xyes; then
+ tdedir=`tde-config --prefix --expandvars 2>/dev/null`
+ tdelibs=`tde-config --install lib --expandvars 2>/dev/null`
+ tdeincs=`tde-config --install include --expandvars 2>/dev/null`
+ if test -d "$tdelibs"; then
+ PKG_CHECK_MODULES(TDE_WINDOW_DECORATOR,
+ dbus-1 xdamage xcomposite,
+ [use_tde=yes], [use_tde=no])
+
+ TDE_CFLAGS="$TQT_CXXFLAGS -I$tdeincs -I/usr/include/tqt -include tqt.h"
+ TDE_LIBS="$TQT_LIBS -L$tdelibs -ltdecore -ltdecorations -ldbus-tqt-1 -lDCOP -ltqt -ltqt-mt"
+
+ TQT_MOC=$QTDIR/bin/tmoc
+ TDCOPIDL=$tdedir/bin/dcopidl
+ TDCOPIDL2CPP=$tdedir/bin/dcopidl2cpp
+ else
+ use_tde=no;
+ fi
+ fi
+fi
+
+AM_CONDITIONAL(USE_TDE, test "x$use_tde" = "xyes")
+if test "$use_tde" = yes; then
+ AC_DEFINE(USE_TDE, 1, [Build TDE window decorator])
+fi
+
+AC_SUBST(TDE_CFLAGS)
+AC_SUBST(TDE_LIBS)
+AC_SUBST(TQT_MOC)
+AC_SUBST(TDCOPIDL)
+AC_SUBST(TDCOPIDL2CPP)
+
+AC_ARG_ENABLE(tdeconfig,
+ [ --disable-tdeconfig Disable TDE config plugin],
+ [use_tdeconfig=$enableval], [use_tdeconfig=yes])
+
+if test "x$use_tde" != "xyes"; then
+ use_tdeconfig=no;
+fi
+
+if test "x$use_tdeconfig" = "xyes"; then
+ TDECONFIG_CFLAGS=$TDE_CFLAGS
+ TDECONFIG_LIBS=$TDE_LIBS
+ TDE_KCFG_DIR=`tde-config --install kcfg --expandvars 2>/dev/null`
+ TDE_CONFIG_DIR=`tde-config --install config --expandvars 2>/dev/null`
+fi
+
+AM_CONDITIONAL(USE_TDECONFIG, test "x$use_tdeconfig" = "xyes")
+if test "$use_tdeconfig" = yes; then
+ AC_DEFINE(USE_TDECONFIG, 1, [Build TDE config plugin])
+fi
+
+AC_SUBST(TDECONFIG_CFLAGS)
+AC_SUBST(TDECONFIG_LIBS)
+AC_SUBST(TDE_KCFG_DIR)
+AC_SUBST(TDE_CONFIG_DIR)
+
+tdecfgdir=$TDE_KCFG_DIR
+AC_SUBST(tdecfgdir)
+
AC_ARG_WITH(max-desktops,
[ --with-max-desktops Max reasonable desktops],
[MAX_DESKTOPS=$withval],
@@ -633,6 +741,8 @@
kde/window-decorator-kde4/Makefile
po/Makefile.in
metadata/Makefile
+tde/Makefile
+tde/window-decorator/Makefile
])
echo ""
@@ -640,6 +750,7 @@
echo " glib: $use_glib"
echo " gconf: $use_gconf"
echo " kconfig: $use_kconfig"
+echo " tdeconfig:$use_tdeconfig"
echo " dbus: $use_dbus"
echo " annotate: $use_annotate"
echo " svg: $use_librsvg"
@@ -652,4 +763,5 @@
echo " gnome: $use_gnome"
echo " kde: $use_kde"
echo " kde4: $use_kde4"
+echo " tde: $use_tde"
echo ""
Index: b/plugins/Makefile.am
===================================================================
--- a/plugins/Makefile.am 2013-08-04 14:48:44.000000000 +0200
+++ b/plugins/Makefile.am 2013-08-04 14:51:09.000000000 +0200
@@ -112,6 +112,13 @@
libkconfig_module = libkconfig.la
endif
+if USE_TDECONFIG
+libtdeconfig_la_LDFLAGS = -module -avoid-version -no-undefined
+libtdeconfig_la_LIBADD = @TDECONFIG_LIBS@
+libtdeconfig_la_SOURCES = tdeconfig.cpp
+libtdeconfig_module = libtdeconfig.la
+endif
+
if DBUS_PLUGIN
libdbus_la_LDFLAGS = -module -avoid-version -no-undefined
libdbus_la_LIBADD = @DBUS_LIBS@
@@ -139,6 +146,7 @@
@ANNOTATE_CFLAGS@ \
@GCONF_CFLAGS@ \
@KCONFIG_CFLAGS@ \
+ @TDECONFIG_CFLAGS@ \
@DBUS_CFLAGS@ \
@GLIB_CFLAGS@ \
@FUSE_CFLAGS@ \
@@ -157,6 +165,7 @@
$(libglib_module) \
$(libgconf_module) \
$(libkconfig_module) \
+ $(libtdeconfig_module) \
libdecoration.la \
libwobbly.la \
libfade.la \
Index: b/plugins/tdeconfig.cpp
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ b/plugins/tdeconfig.cpp 2013-08-04 14:49:47.000000000 +0200
@@ -0,0 +1,752 @@
+/*
+ * Copyright © 2007 Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU 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.
+ */
+
+#include <tdeglobal.h>
+#include <kstandarddirs.h>
+#include <tdeapplication.h>
+#include <ksimpleconfig.h>
+#include <ntqfile.h>
+
+#include <compiz-core.h>
+
+#define COMPIZ_KCONFIG_RC "compizrc"
+
+static TDEInstance *kInstance;
+
+static CompMetadata tdeconfigMetadata;
+
+static int corePrivateIndex;
+
+typedef struct _KconfigCore {
+ TDEConfig *config;
+
+ CompTimeoutHandle syncHandle;
+ CompTimeoutHandle reloadHandle;
+ CompFileWatchHandle fileWatch;
+
+ InitPluginForObjectProc initPluginForObject;
+ SetOptionForPluginProc setOptionForPlugin;
+} KconfigCore;
+
+#define GET_KCONFIG_CORE(c) \
+ ((KconfigCore *) (c)->base.privates[corePrivateIndex].ptr)
+
+#define KCONFIG_CORE(c) \
+ KconfigCore *kc = GET_KCONFIG_CORE (c)
+
+
+static void
+tdeconfigRcChanged (const char *name,
+ void *closure);
+
+static Bool
+tdeconfigRcSync (void *closure)
+{
+ KCONFIG_CORE (&core);
+
+ kc->config->sync ();
+
+ kc->syncHandle = 0;
+
+ return FALSE;
+}
+
+static bool
+tdeconfigValueToBool (CompOptionType type,
+ CompOptionValue *value)
+{
+ switch (type) {
+ case CompOptionTypeBool:
+ return (value->b) ? true : false;
+ case CompOptionTypeBell:
+ return (value->action.bell) ? true : false;
+ default:
+ break;
+ }
+
+ return false;
+}
+
+static TQString
+tdeconfigValueToString (CompObject *object,
+ CompOptionType type,
+ CompOptionValue *value)
+{
+ TQString str;
+
+ switch (type) {
+ case CompOptionTypeBool:
+ str = TQString::number (value->b ? TRUE : FALSE);
+ break;
+ case CompOptionTypeFloat:
+ str = TQString::number (value->f);
+ break;
+ case CompOptionTypeString:
+ str = TQString (value->s);
+ break;
+ case CompOptionTypeColor: {
+ char *color;
+
+ color = colorToString (value->c);
+ if (color)
+ {
+ str = TQString (color);
+ free (color);
+ }
+ } break;
+ case CompOptionTypeKey: {
+ char *action = NULL;
+
+ while (object && object->type != COMP_OBJECT_TYPE_DISPLAY)
+ object = object->parent;
+
+ if (object)
+ action = keyActionToString (GET_CORE_DISPLAY (object),
+ &value->action);
+ if (action)
+ {
+ str = TQString (action);
+ free (action);
+ }
+ } break;
+ case CompOptionTypeButton: {
+ char *action = NULL;
+
+ while (object && object->type != COMP_OBJECT_TYPE_DISPLAY)
+ object = object->parent;
+
+ if (object)
+ action = buttonActionToString (GET_CORE_DISPLAY (object),
+ &value->action);
+ if (action)
+ {
+ str = TQString (action);
+ free (action);
+ }
+ } break;
+ case CompOptionTypeEdge: {
+ char *edge;
+
+ edge = edgeMaskToString (value->action.edgeMask);
+ if (edge)
+ {
+ str = TQString (edge);
+ free (edge);
+ }
+ } break;
+ case CompOptionTypeBell:
+ str = TQString::number (value->action.bell ? TRUE : FALSE);
+ break;
+ case CompOptionTypeMatch: {
+ char *match;
+
+ match = matchToString (&value->match);
+ if (match)
+ {
+ str = TQString (match);
+ free (match);
+ }
+ }
+ default:
+ break;
+ }
+
+ return str;
+}
+
+static TQString
+tdeconfigObjectString (CompObject *object)
+{
+ TQString objectName (TQString (compObjectTypeName (object->type)));
+ char *name;
+
+ name = compObjectName (object);
+ if (name)
+ {
+ objectName += name;
+ free (name);
+ }
+
+ return objectName;
+}
+
+static void
+tdeconfigSetOption (CompObject *object,
+ CompOption *o,
+ const char *plugin)
+{
+ TQString group (TQString (plugin) + "_" + tdeconfigObjectString (object));
+
+ KCONFIG_CORE (&core);
+
+ kc->config->setGroup (group);
+
+ switch (o->type) {
+ case CompOptionTypeBool:
+ case CompOptionTypeBell:
+ kc->config->writeEntry (o->name,
+ tdeconfigValueToBool (o->type, &o->value));
+ break;
+ case CompOptionTypeInt:
+ kc->config->writeEntry (o->name, o->value.i);
+ break;
+ case CompOptionTypeFloat:
+ kc->config->writeEntry (o->name, (double) o->value.f);
+ break;
+ case CompOptionTypeString:
+ case CompOptionTypeColor:
+ case CompOptionTypeKey:
+ case CompOptionTypeButton:
+ case CompOptionTypeEdge:
+ case CompOptionTypeMatch:
+ kc->config->writeEntry (o->name,
+ tdeconfigValueToString (object, o->type,
+ &o->value));
+ break;
+ case CompOptionTypeList: {
+ int i;
+
+ switch (o->value.list.type) {
+ case CompOptionTypeInt: {
+ TQValueList< int > list;
+
+ for (i = 0; i < o->value.list.nValue; i++)
+ list += o->value.list.value[i].i;
+
+ kc->config->writeEntry (o->name, list);
+ } break;
+ case CompOptionTypeBool:
+ case CompOptionTypeFloat:
+ case CompOptionTypeString:
+ case CompOptionTypeColor:
+ case CompOptionTypeKey:
+ case CompOptionTypeButton:
+ case CompOptionTypeEdge:
+ case CompOptionTypeBell:
+ case CompOptionTypeMatch: {
+ TQStringList list;
+
+ for (i = 0; i < o->value.list.nValue; i++)
+ list += tdeconfigValueToString (object,
+ o->value.list.type,
+ &o->value.list.value[i]);
+
+ kc->config->writeEntry (o->name, list);
+ } break;
+ case CompOptionTypeAction:
+ case CompOptionTypeList:
+ break;
+ }
+ } break;
+ case CompOptionTypeAction:
+ return;
+ }
+
+ if (!kc->syncHandle)
+ kc->syncHandle = compAddTimeout (0, 0, tdeconfigRcSync, 0);
+}
+
+static Bool
+tdeconfigStringToValue (CompObject *object,
+ TQString str,
+ CompOptionType type,
+ CompOptionValue *value)
+{
+ switch (type) {
+ case CompOptionTypeBool:
+ value->b = str.toInt () ? TRUE : FALSE;
+ break;
+ case CompOptionTypeFloat:
+ value->f = str.toFloat ();
+ break;
+ case CompOptionTypeString:
+ value->s = strdup (str.ascii ());
+ if (!value->s)
+ return FALSE;
+ break;
+ case CompOptionTypeColor:
+ if (!stringToColor (str.ascii (), value->c))
+ return FALSE;
+ break;
+ case CompOptionTypeKey:
+ while (object && object->type != COMP_OBJECT_TYPE_DISPLAY)
+ object = object->parent;
+
+ if (!object)
+ return FALSE;
+
+ stringToKeyAction (GET_CORE_DISPLAY (object), str.ascii (),
+ &value->action);
+ break;
+ case CompOptionTypeButton:
+ while (object && object->type != COMP_OBJECT_TYPE_DISPLAY)
+ object = object->parent;
+
+ if (!object)
+ return FALSE;
+
+ stringToButtonAction (GET_CORE_DISPLAY (object), str.ascii (),
+ &value->action);
+ break;
+ case CompOptionTypeEdge:
+ value->action.edgeMask = stringToEdgeMask (str.ascii ());
+ break;
+ case CompOptionTypeBell:
+ value->action.bell = str.toInt () ? TRUE : FALSE;
+ break;
+ case CompOptionTypeMatch:
+ matchInit (&value->match);
+ matchAddFromString (&value->match, str.ascii ());
+ break;
+ default:
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+tdeconfigBoolToValue (bool b,
+ CompOptionType type,
+ CompOptionValue *value)
+{
+ switch (type) {
+ case CompOptionTypeBool:
+ value->b = (b) ? TRUE : FALSE;
+ break;
+ case CompOptionTypeBell:
+ value->action.bell = (b) ? TRUE : FALSE;
+ default:
+ break;
+ }
+}
+
+static Bool
+tdeconfigReadOptionValue (CompObject *object,
+ TDEConfig *config,
+ CompOption *o,
+ CompOptionValue *value)
+{
+ compInitOptionValue (value);
+
+ switch (o->type) {
+ case CompOptionTypeBool:
+ case CompOptionTypeBell:
+ tdeconfigBoolToValue (config->readBoolEntry (o->name), o->type, value);
+ break;
+ case CompOptionTypeInt:
+ value->i = config->readNumEntry (o->name);
+ break;
+ case CompOptionTypeFloat:
+ value->f = config->readDoubleNumEntry (o->name);
+ break;
+ case CompOptionTypeString:
+ case CompOptionTypeColor:
+ case CompOptionTypeKey:
+ case CompOptionTypeButton:
+ case CompOptionTypeEdge:
+ case CompOptionTypeMatch:
+ if (!tdeconfigStringToValue (object,
+ config->readEntry (o->name), o->type,
+ value))
+ return FALSE;
+ break;
+ case CompOptionTypeList: {
+ int n, i;
+
+ value->list.value = NULL;
+ value->list.nValue = 0;
+ value->list.type = o->value.list.type;
+
+ switch (o->value.list.type) {
+ case CompOptionTypeInt: {
+ TQValueList< int > list;
+
+ list = config->readIntListEntry (o->name);
+
+ n = list.size ();
+ if (n)
+ {
+ value->list.value = (CompOptionValue *)
+ malloc (sizeof (CompOptionValue) * n);
+ if (value->list.value)
+ {
+ for (i = 0; i < n; i++)
+ value->list.value[i].i = list[i];
+
+ value->list.nValue = n;
+ }
+ }
+ } break;
+ case CompOptionTypeBool:
+ case CompOptionTypeFloat:
+ case CompOptionTypeString:
+ case CompOptionTypeColor:
+ case CompOptionTypeKey:
+ case CompOptionTypeButton:
+ case CompOptionTypeEdge:
+ case CompOptionTypeBell:
+ case CompOptionTypeMatch: {
+ TQStringList list;
+
+ list = config->readListEntry (o->name);
+
+ n = list.size ();
+ if (n)
+ {
+ value->list.value = (CompOptionValue *)
+ malloc (sizeof (CompOptionValue) * n);
+ if (value->list.value)
+ {
+ for (i = 0; i < n; i++)
+ {
+ if (!tdeconfigStringToValue (object,
+ list[i],
+ value->list.type,
+ &value->list.value[i]))
+ break;
+
+ value->list.nValue++;
+ }
+
+ if (value->list.nValue != n)
+ {
+ compFiniOptionValue (value, o->type);
+ return FALSE;
+ }
+ }
+ }
+ } break;
+ case CompOptionTypeList:
+ case CompOptionTypeAction:
+ return FALSE;
+ }
+ } break;
+ case CompOptionTypeAction:
+ return FALSE;
+ break;
+ }
+
+ return TRUE;
+}
+
+static void
+tdeconfigGetOption (CompObject *object,
+ CompOption *o,
+ const char *plugin)
+{
+ TQString group (TQString (plugin) + "_" +
+ tdeconfigObjectString (object));
+ const TQString name (o->name);
+
+ KCONFIG_CORE (&core);
+
+ kc->config->setGroup (group);
+
+ if (kc->config->hasKey (name))
+ {
+ CompOptionValue value;
+
+ if (tdeconfigReadOptionValue (object, kc->config, o, &value))
+ {
+ (*core.setOptionForPlugin) (object, plugin, o->name, &value);
+ compFiniOptionValue (&value, o->type);
+ }
+ }
+ else
+ {
+ tdeconfigSetOption (object, o, plugin);
+ }
+}
+
+static CompBool
+tdeconfigReloadObjectTree (CompObject *object,
+ void *closure);
+
+static CompBool
+tdeconfigReloadObjectsWithType (CompObjectType type,
+ CompObject *parent,
+ void *closure)
+{
+ compObjectForEach (parent, type, tdeconfigReloadObjectTree, closure);
+
+ return TRUE;
+}
+
+static CompBool
+tdeconfigReloadObjectTree (CompObject *object,
+ void *closure)
+{
+ CompPlugin *p = (CompPlugin *) closure;
+ CompOption *option;
+ int nOption;
+
+ option = (*p->vTable->getObjectOptions) (p, object, &nOption);
+ while (nOption--)
+ tdeconfigGetOption (object, option++, p->vTable->name);
+
+ compObjectForEachType (object, tdeconfigReloadObjectsWithType, closure);
+
+ return TRUE;
+}
+
+static Bool
+tdeconfigRcReload (void *closure)
+{
+ CompPlugin *p;
+
+ KCONFIG_CORE (&core);
+
+ kc->config->reparseConfiguration ();
+
+ for (p = getPlugins (); p; p = p->next)
+ {
+ if (!p->vTable->getObjectOptions)
+ continue;
+
+ tdeconfigReloadObjectTree (&core.base, (void *) p);
+ }
+
+ kc->reloadHandle = 0;
+
+ return FALSE;
+}
+
+static void
+tdeconfigRcChanged (const char *name,
+ void *closure)
+{
+ if (strcmp (name, COMPIZ_KCONFIG_RC) == 0)
+ {
+ KCONFIG_CORE (&core);
+
+ if (!kc->reloadHandle)
+ kc->reloadHandle = compAddTimeout (0, 0, tdeconfigRcReload, closure);
+ }
+}
+
+static CompBool
+tdeconfigSetOptionForPlugin (CompObject *object,
+ const char *plugin,
+ const char *name,
+ CompOptionValue *value)
+{
+ CompBool status;
+
+ KCONFIG_CORE (&core);
+
+ UNWRAP (kc, &core, setOptionForPlugin);
+ status = (*core.setOptionForPlugin) (object, plugin, name, value);
+ WRAP (kc, &core, setOptionForPlugin, tdeconfigSetOptionForPlugin);
+
+ if (status && !kc->reloadHandle)
+ {
+ CompPlugin *p;
+
+ p = findActivePlugin (plugin);
+ if (p && p->vTable->getObjectOptions)
+ {
+ CompOption *option;
+ int nOption;
+
+ option = (*p->vTable->getObjectOptions) (p, object, &nOption);
+ option = compFindOption (option, nOption, name, 0);
+ if (option)
+ tdeconfigSetOption (object, option, p->vTable->name);
+ }
+ }
+
+ return status;
+}
+
+static CompBool
+tdeconfigInitPluginForObject (CompPlugin *p,
+ CompObject *o)
+{
+ CompBool status;
+
+ KCONFIG_CORE (&core);
+
+ UNWRAP (kc, &core, initPluginForObject);
+ status = (*core.initPluginForObject) (p, o);
+ WRAP (kc, &core, initPluginForObject, tdeconfigInitPluginForObject);
+
+ if (status && p->vTable->getObjectOptions)
+ {
+ CompOption *option;
+ int nOption;
+
+ option = (*p->vTable->getObjectOptions) (p, o, &nOption);
+ while (nOption--)
+ tdeconfigGetOption (o, option++, p->vTable->name);
+ }
+
+ return status;
+}
+
+static Bool
+tdeconfigInitCore (CompPlugin *p,
+ CompCore *c)
+{
+ KconfigCore *kc;
+ TQString dir;
+
+ if (!checkPluginABI ("core", CORE_ABIVERSION))
+ return FALSE;
+
+ kc = new KconfigCore;
+ if (!kc)
+ return FALSE;
+
+ kc->config = new TDEConfig (COMPIZ_KCONFIG_RC);
+ if (!kc->config)
+ {
+ delete kc;
+ return FALSE;
+ }
+
+ kc->reloadHandle = compAddTimeout (0, 0, tdeconfigRcReload, 0);
+ kc->syncHandle = 0;
+ kc->fileWatch = 0;
+
+ dir = TDEGlobal::dirs ()->saveLocation ("config", TQString::null, false);
+
+ if (TQFile::exists (dir))
+ {
+ kc->fileWatch = addFileWatch (dir.ascii (), ~0, tdeconfigRcChanged, 0);
+ }
+ else
+ {
+ compLogMessage ("tdeconfig", CompLogLevelWarn, "Bad access \"%s\"",
+ dir.ascii ());
+ }
+
+ WRAP (kc, c, initPluginForObject, tdeconfigInitPluginForObject);
+ WRAP (kc, c, setOptionForPlugin, tdeconfigSetOptionForPlugin);
+
+ c->base.privates[corePrivateIndex].ptr = kc;
+
+ return TRUE;
+}
+
+static void
+tdeconfigFiniCore (CompPlugin *p,
+ CompCore *c)
+{
+ KCONFIG_CORE (c);
+
+ UNWRAP (kc, c, initPluginForObject);
+ UNWRAP (kc, c, setOptionForPlugin);
+
+ if (kc->reloadHandle)
+ compRemoveTimeout (kc->reloadHandle);
+
+ if (kc->syncHandle)
+ {
+ compRemoveTimeout (kc->syncHandle);
+ tdeconfigRcSync (0);
+ }
+
+ if (kc->fileWatch)
+ removeFileWatch (kc->fileWatch);
+
+ delete kc->config;
+ delete kc;
+}
+
+static CompBool
+tdeconfigInitObject (CompPlugin *p,
+ CompObject *o)
+{
+ static InitPluginObjectProc dispTab[] = {
+ (InitPluginObjectProc) tdeconfigInitCore
+ };
+
+ RETURN_DISPATCH (o, dispTab, ARRAY_SIZE (dispTab), TRUE, (p, o));
+}
+
+static void
+tdeconfigFiniObject (CompPlugin *p,
+ CompObject *o)
+{
+ static FiniPluginObjectProc dispTab[] = {
+ (FiniPluginObjectProc) tdeconfigFiniCore
+ };
+
+ DISPATCH (o, dispTab, ARRAY_SIZE (dispTab), (p, o));
+}
+
+static Bool
+tdeconfigInit (CompPlugin *p)
+{
+ if (!compInitPluginMetadataFromInfo (&tdeconfigMetadata, p->vTable->name,
+ 0, 0, 0, 0))
+ return FALSE;
+
+ corePrivateIndex = allocateCorePrivateIndex ();
+ if (corePrivateIndex < 0)
+ {
+ compFiniMetadata (&tdeconfigMetadata);
+ return FALSE;
+ }
+
+ kInstance = new TDEInstance ("compiz-tdeconfig");
+ if (!kInstance)
+ {
+ freeCorePrivateIndex (corePrivateIndex);
+ compFiniMetadata (&tdeconfigMetadata);
+ return FALSE;
+ }
+
+ compAddMetadataFromFile (&tdeconfigMetadata, p->vTable->name);
+
+ return TRUE;
+}
+
+static void
+tdeconfigFini (CompPlugin *p)
+{
+ delete kInstance;
+
+ freeCorePrivateIndex (corePrivateIndex);
+ compFiniMetadata (&tdeconfigMetadata);
+}
+
+static CompMetadata *
+tdeconfigGetMetadata (CompPlugin *plugin)
+{
+ return &tdeconfigMetadata;
+}
+
+CompPluginVTable tdeconfigVTable = {
+ "tdeconfig",
+ tdeconfigGetMetadata,
+ tdeconfigInit,
+ tdeconfigFini,
+ tdeconfigInitObject,
+ tdeconfigFiniObject,
+ 0, /* GetObjectOptions */
+ 0 /* SetObjectOption */
+};
+
+CompPluginVTable *
+getCompPluginInfo20070830 (void)
+{
+ return &tdeconfigVTable;
+}
Index: b/tde/Makefile.am
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ b/tde/Makefile.am 2013-08-04 11:39:18.000000000 +0200
@@ -0,0 +1 @@
+SUBDIRS = window-decorator
Index: b/tde/window-decorator/KWinInterface.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ b/tde/window-decorator/KWinInterface.h 2013-08-04 15:16:08.000000000 +0200
@@ -0,0 +1,17 @@
+// taken from TWin
+
+#ifndef KWIN_INTERFACE_H
+#define KWIN_INTERFACE_H
+
+#include <dcopobject.h>
+
+class KWinInterface:virtual public DCOPObject
+{
+ K_DCOP
+
+ k_dcop:
+
+ virtual ASYNC reconfigure () = 0;
+};
+
+#endif
Index: b/tde/window-decorator/Makefile.am
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ b/tde/window-decorator/Makefile.am 2013-08-04 17:52:26.000000000 +0200
@@ -0,0 +1,44 @@
+if USE_TDE
+
+BUILDSOURCES = \
+ decorator.moc.cpp \
+ window.moc.cpp \
+ KWinInterface_skel.cpp
+
+tde_window_decorator_DEPENDENCIES = \
+ $(top_builddir)/libdecoration/libdecoration.la
+tde_window_decorator_LDADD = \
+ $(top_builddir)/libdecoration/libdecoration.la \
+ @TDE_WINDOW_DECORATOR_LIBS@ @TDE_LIBS@ -lX11 -lXext -lXrender
+dist_tde_window_decorator_SOURCES = \
+ main.cpp \
+ utils.cpp \
+ utils.h \
+ decorator.cpp \
+ decorator.h \
+ window.cpp \
+ window.h \
+ options.cpp \
+ options.h \
+ KWinInterface.h
+
+nodist_tde_window_decorator_SOURCES = $(BUILDSOURCES)
+
+tde_window_decorator_program = tde-window-decorator
+
+INCLUDES = -I$(top_srcdir)/include @TDE_WINDOW_DECORATOR_CFLAGS@ @TDE_CFLAGS@
+
+bin_PROGRAMS = $(tde_window_decorator_program)
+
+%.moc.cpp: %.h
+ $(TQT_MOC) $< -o $@
+
+%.kidl: %.h
+ $(TDCOPIDL) $< > $@
+
+%_skel.cpp: %.kidl
+ $(TDCOPIDL2CPP) $< > $@
+
+CLEANFILES = $(BUILDSOURCES) KWinInterface_skel.* KWinInterface_stub.*
+
+endif
Index: b/tde/window-decorator/decorator.cpp
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ b/tde/window-decorator/decorator.cpp 2013-08-04 15:44:07.000000000 +0200
@@ -0,0 +1,1055 @@
+/*
+ * Copyright © 2006 Novell, Inc.
+ * Copyright © 2006 Dennis Kasprzyk <onestone@beryl-project.org>
+ * Copyright © 2006 Volker Krause <vkrause@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * Author: David Reveman <davidr@novell.com>
+ */
+
+#include <ntqglobal.h>
+
+#include <dcopclient.h>
+#include <tdecmdlineargs.h>
+#include <tdeconfig.h>
+#include <kdebug.h>
+#include <tdeglobal.h>
+#include <twinmodule.h>
+#include <tdelocale.h>
+#include <kcommondecoration.h>
+#include <twin.h>
+#include <ntqwidgetlist.h>
+#include <ntqpoint.h>
+
+#include <X11/Xlib.h>
+#include <X11/extensions/Xcomposite.h>
+
+#include "decorator.h"
+#include "options.h"
+#include "utils.h"
+
+#include <stdio.h>
+
+#define SHADOW_RADIUS 8.0
+#define SHADOW_OPACITY 0.5
+#define SHADOW_OFFSET_X 1
+#define SHADOW_OFFSET_Y 1
+#define SHADOW_COLOR_RED 0x0000
+#define SHADOW_COLOR_GREEN 0x0000
+#define SHADOW_COLOR_BLUE 0x0000
+
+#define DBUS_DEST "org.freedesktop.compiz"
+#define DBUS_PATH "/org/freedesktop/compiz/decoration/display"
+#define DBUS_INTERFACE "org.freedesktop.compiz"
+#define DBUS_METHOD_GET "get"
+
+double decorationOpacity = 0.75;
+bool decorationOpacityShade = false;
+double activeDecorationOpacity = 1.0;
+bool activeDecorationOpacityShade = false;
+int blurType = BLUR_TYPE_NONE;
+
+decor_context_t KWD::Decorator::mDefaultContext;
+decor_extents_t KWD::Decorator::mDefaultBorder;
+decor_shadow_t *KWD::Decorator::mNoBorderShadow = 0;
+decor_shadow_t *KWD::Decorator::mDefaultShadow = 0;
+KWD::PluginManager *KWD::Decorator::mPlugins = 0;
+KWD::Options *KWD::Decorator::mOptions = 0;
+NETRootInfo *KWD::Decorator::mRootInfo;
+WId KWD::Decorator::mActiveId;
+decor_shadow_options_t KWD::Decorator::mShadowOptions;
+
+extern Time tqt_x_time;
+
+struct _cursor cursors[3][3] = {
+ { C (top_left_corner), C (top_side), C (top_right_corner) },
+ { C (left_side), C (left_ptr), C (right_side) },
+ { C (bottom_left_corner), C (bottom_side), C (bottom_right_corner) }
+};
+
+KWD::PluginManager::PluginManager (TDEConfig *config): KDecorationPlugins (config)
+{
+ defaultPlugin = "twin3_plastik";
+}
+
+static DBusHandlerResult
+dbusHandleMessage (DBusConnection *connection,
+ DBusMessage *message,
+ void *userData)
+{
+ KWD::Decorator *d = (KWD::Decorator *) userData;
+ char **path;
+ const char *interface, *member;
+ DBusHandlerResult result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+ interface = dbus_message_get_interface (message);
+ member = dbus_message_get_member (message);
+
+ (void) connection;
+
+ if (!interface || !member)
+ return result;
+
+ if (!dbus_message_is_signal (message, interface, member))
+ return result;
+
+ if (strcmp (member, "changed"))
+ return result;
+
+ if (!dbus_message_get_path_decomposed (message, &path))
+ return result;
+
+ if (!path[0] || !path[1] || !path[2] || !path[3] || !path[4] || !path[5])
+ {
+ dbus_free_string_array (path);
+ return result;
+ }
+
+ if (!strcmp (path[0], "org") &&
+ !strcmp (path[1], "freedesktop") &&
+ !strcmp (path[2], "compiz") &&
+ !strcmp (path[3], "decoration") &&
+ !strcmp (path[4], "display"))
+ {
+ decor_shadow_options_t opt = *d->shadowOptions ();
+
+ result = DBUS_HANDLER_RESULT_HANDLED;
+
+ if (strcmp (path[5], "shadow_radius") == 0)
+ {
+ dbus_message_get_args (message, NULL,
+ DBUS_TYPE_DOUBLE, &opt.shadow_radius,
+ DBUS_TYPE_INVALID);
+ }
+ else if (strcmp (path[5], "shadow_opacity") == 0)
+ {
+ dbus_message_get_args (message, NULL,
+ DBUS_TYPE_DOUBLE, &opt.shadow_opacity,
+ DBUS_TYPE_INVALID);
+ }
+ else if (strcmp (path[5], "shadow_color") == 0)
+ {
+ DBusError error;
+ char *str;
+
+ dbus_error_init (&error);
+
+ dbus_message_get_args (message, &error,
+ DBUS_TYPE_STRING, &str,
+ DBUS_TYPE_INVALID);
+
+ if (!dbus_error_is_set (&error))
+ {
+ int c[4];
+
+ if (sscanf (str, "#%2x%2x%2x%2x",
+ &c[0], &c[1], &c[2], &c[3]) == 4)
+ {
+ opt.shadow_color[0] = c[0] << 8 | c[0];
+ opt.shadow_color[1] = c[1] << 8 | c[1];
+ opt.shadow_color[2] = c[2] << 8 | c[2];
+ }
+ }
+
+ dbus_error_free (&error);
+ }
+ else if (strcmp (path[5], "shadow_x_offset") == 0)
+ {
+ dbus_message_get_args (message, NULL,
+ DBUS_TYPE_INT32, &opt.shadow_offset_x,
+ DBUS_TYPE_INVALID);
+ }
+ else if (strcmp (path[5], "shadow_y_offset") == 0)
+ {
+ dbus_message_get_args (message, NULL,
+ DBUS_TYPE_INT32, &opt.shadow_offset_y,
+ DBUS_TYPE_INVALID);
+ }
+
+ d->changeShadowOptions (&opt);
+ }
+
+ dbus_free_string_array (path);
+
+ return result;
+}
+
+KWD::Decorator::Decorator (void) : DCOPObject ("KWinInterface"),
+ TDEApplication (),
+ mConfig (0),
+ mKWinModule (new KWinModule (this, KWinModule::INFO_ALL)),
+ mDBusQtConnection (this),
+ mCompositeWindow (0)
+{
+ XSetWindowAttributes attr;
+ DCOPClient *client;
+ int i, j;
+
+ mRootInfo = new NETRootInfo (tqt_xdisplay (), 0);
+
+ mActiveId = 0;
+
+ Atoms::init ();
+
+ mConfig = new TDEConfig ("twinrc");
+ mConfig->setGroup ("Style");
+
+ mOptions = new KWD::Options (mConfig);
+ mPlugins = new PluginManager (mConfig);
+
+ for (i = 0; i < 3; i++)
+ {
+ for (j = 0; j < 3; j++)
+ {
+ if (cursors[i][j].shape != XC_left_ptr)
+ cursors[i][j].cursor =
+ XCreateFontCursor (tqt_xdisplay (), cursors[i][j].shape);
+ }
+ }
+
+ client = dcopClient ();
+ client->registerAs ("twin", false);
+ client->setDefaultObject ("KWinInterface");
+
+ mShadowOptions.shadow_radius = SHADOW_RADIUS;
+ mShadowOptions.shadow_opacity = SHADOW_OPACITY;
+ mShadowOptions.shadow_offset_x = SHADOW_OFFSET_X;
+ mShadowOptions.shadow_offset_y = SHADOW_OFFSET_Y;
+ mShadowOptions.shadow_color[0] = SHADOW_COLOR_RED;
+ mShadowOptions.shadow_color[1] = SHADOW_COLOR_GREEN;
+ mShadowOptions.shadow_color[2] = SHADOW_COLOR_BLUE;
+
+ attr.override_redirect = True;
+
+ mCompositeWindow = XCreateWindow (tqt_xdisplay (), tqt_xrootwin (),
+ -ROOT_OFF_X, -ROOT_OFF_Y, 1, 1, 0,
+ CopyFromParent,
+ CopyFromParent,
+ CopyFromParent,
+ CWOverrideRedirect, &attr);
+
+ XCompositeRedirectSubwindows (tqt_xdisplay (), mCompositeWindow,
+ CompositeRedirectManual);
+
+ XMapWindow (tqt_xdisplay (), mCompositeWindow);
+}
+
+KWD::Decorator::~Decorator (void)
+{
+ TQMap <WId, KWD::Window *>::ConstIterator it;
+
+ for (it = mClients.begin (); it != mClients.end (); it++)
+ delete (*it);
+
+ if (mDecorNormal)
+ delete mDecorNormal;
+
+ if (mDecorActive)
+ delete mDecorActive;
+
+ XDestroyWindow (tqt_xdisplay (), mCompositeWindow);
+
+ delete mOptions;
+ delete mPlugins;
+ delete mConfig;
+ delete mKWinModule;
+ delete mRootInfo;
+}
+
+bool
+KWD::Decorator::enableDecorations (Time timestamp,
+ int damageEvent)
+{
+ TQValueList <WId>::ConstIterator it;
+ DBusError error;
+
+ mDmSnTimestamp = timestamp;
+ mDamageEvent = damageEvent;
+
+ if (!pluginManager ()->loadPlugin (""))
+ return false;
+
+ dbus_error_init (&error);
+
+ mDBusConnection = dbus_bus_get (DBUS_BUS_SESSION, &error);
+ if (!dbus_error_is_set (&error))
+ {
+ dbus_bus_add_match (mDBusConnection, "type='signal'", &error);
+
+ dbus_connection_add_filter (mDBusConnection,
+ dbusHandleMessage,
+ this, NULL);
+
+ mDBusQtConnection.dbus_connection_setup_with_qt_main (mDBusConnection);
+
+ updateAllShadowOptions ();
+ }
+
+ dbus_error_free (&error);
+
+ updateShadow ();
+
+ mDecorNormal = new KWD::Window (mCompositeWindow, tqt_xrootwin (),
+ 0, Window::Default);
+ mDecorActive = new KWD::Window (mCompositeWindow, tqt_xrootwin (),
+ 0, Window::DefaultActive);
+
+ connect (mKWinModule, SIGNAL (windowAdded (WId)),
+ SLOT (handleWindowAdded (WId)));
+ connect (mKWinModule, SIGNAL (windowRemoved (WId)),
+ SLOT (handleWindowRemoved (WId)));
+ connect (mKWinModule, SIGNAL (activeWindowChanged (WId)),
+ SLOT (handleActiveWindowChanged (WId)));
+ connect (mKWinModule,
+ SIGNAL (windowChanged (WId, const unsigned long *)),
+ SLOT (handleWindowChanged (WId, const unsigned long *)));
+
+ connect (&mIdleTimer, SIGNAL (timeout ()), SLOT (processDamage ()));
+
+ mActiveId = mKWinModule->activeWindow ();
+
+ it = mKWinModule->windows ().begin ();
+ for (; it != mKWinModule->windows ().end (); it++)
+ handleWindowAdded ((*it));
+
+ connect (this, SIGNAL (appearanceChanged ()), SLOT (reconfigure ()));
+
+ (void) TQApplication::desktop (); // trigger creation of desktop widget
+
+ // select for client messages
+ XSelectInput (tqt_xdisplay(), tqt_xrootwin (),
+ StructureNotifyMask | PropertyChangeMask);
+
+ return true;
+}
+
+void
+KWD::Decorator::updateDefaultShadow (KWD::Window *w)
+{
+ bool uniqueHorzShape, uniqueVertShape;
+
+ if (mDefaultShadow)
+ {
+ decor_shadow_destroy (tqt_xdisplay (), mDefaultShadow);
+ mDefaultShadow = NULL;
+ }
+
+ w->getShapeInfo (&uniqueHorzShape, &uniqueVertShape);
+
+ /* only return shadow if decoration doesn't use a unique shape */
+ if (uniqueHorzShape || uniqueVertShape)
+ return;
+
+ mDefaultContext = *w->context ();
+ mDefaultBorder = *w->border ();
+ mDefaultShadow = w->shadow ();
+
+ if (mDefaultShadow)
+ decor_shadow_reference (mDefaultShadow);
+}
+
+DBusMessage *
+KWD::Decorator::sendAndBlockForShadowOptionReply (const char *path)
+{
+ DBusMessage *message;
+
+ message = dbus_message_new_method_call (NULL,
+ path,
+ DBUS_INTERFACE,
+ DBUS_METHOD_GET);
+ if (message)
+ {
+ DBusMessage *reply;
+ DBusError error;
+
+ dbus_message_set_destination (message, DBUS_DEST);
+
+ dbus_error_init (&error);
+ reply = dbus_connection_send_with_reply_and_block (mDBusConnection,
+ message, -1,
+ &error);
+ dbus_message_unref (message);
+
+ if (!dbus_error_is_set (&error))
+ return reply;
+ }
+
+ return NULL;
+}
+
+void
+KWD::Decorator::updateAllShadowOptions (void)
+{
+ DBusMessage *reply;
+
+ reply = sendAndBlockForShadowOptionReply (DBUS_PATH "/shadow_radius");
+ if (reply)
+ {
+ dbus_message_get_args (reply, NULL,
+ DBUS_TYPE_DOUBLE, &mShadowOptions.shadow_radius,
+ DBUS_TYPE_INVALID);
+
+ dbus_message_unref (reply);
+ }
+
+ reply = sendAndBlockForShadowOptionReply (DBUS_PATH "/shadow_opacity");
+ if (reply)
+ {
+ dbus_message_get_args (reply, NULL,
+ DBUS_TYPE_DOUBLE, &mShadowOptions.shadow_opacity,
+ DBUS_TYPE_INVALID);
+ dbus_message_unref (reply);
+ }
+
+ reply = sendAndBlockForShadowOptionReply (DBUS_PATH "/shadow_color");
+ if (reply)
+ {
+ DBusError error;
+ char *str;
+
+ dbus_error_init (&error);
+
+ dbus_message_get_args (reply, &error,
+ DBUS_TYPE_STRING, &str,
+ DBUS_TYPE_INVALID);
+
+ if (!dbus_error_is_set (&error))
+ {
+ int c[4];
+
+ if (sscanf (str, "#%2x%2x%2x%2x", &c[0], &c[1], &c[2], &c[3]) == 4)
+ {
+ mShadowOptions.shadow_color[0] = c[0] << 8 | c[0];
+ mShadowOptions.shadow_color[1] = c[1] << 8 | c[1];
+ mShadowOptions.shadow_color[2] = c[2] << 8 | c[2];
+ }
+ }
+
+ dbus_error_free (&error);
+
+ dbus_message_unref (reply);
+ }
+
+ reply = sendAndBlockForShadowOptionReply (DBUS_PATH "/shadow_x_offset");
+ if (reply)
+ {
+ dbus_message_get_args (reply, NULL,
+ DBUS_TYPE_INT32, &mShadowOptions.shadow_offset_x,
+ DBUS_TYPE_INVALID);
+ dbus_message_unref (reply);
+ }
+
+ reply = sendAndBlockForShadowOptionReply (DBUS_PATH "/shadow_y_offset");
+ if (reply)
+ {
+ dbus_message_get_args (reply, NULL,
+ DBUS_TYPE_INT32, &mShadowOptions.shadow_offset_y,
+ DBUS_TYPE_INVALID);
+ dbus_message_unref (reply);
+ }
+}
+
+void
+KWD::Decorator::changeShadowOptions (decor_shadow_options_t *opt)
+{
+ TQMap <WId, KWD::Window *>::ConstIterator it;
+
+ if (!memcmp (opt, &mShadowOptions, sizeof (decor_shadow_options_t)))
+ return;
+
+ mShadowOptions = *opt;
+
+ updateShadow ();
+
+ mDecorNormal->reloadDecoration ();
+ mDecorActive->reloadDecoration ();
+
+ for (it = mClients.constBegin (); it != mClients.constEnd (); it++)
+ it.data ()->reloadDecoration ();
+}
+
+void
+KWD::Decorator::updateShadow (void)
+{
+ Display *xdisplay = tqt_xdisplay ();
+ Screen *xscreen = ScreenOfDisplay (xdisplay, tqt_xscreen ());
+ decor_context_t context;
+
+ if (mDefaultShadow)
+ {
+ decor_shadow_destroy (xdisplay, mDefaultShadow);
+ mDefaultShadow = NULL;
+ }
+
+ if (mNoBorderShadow)
+ decor_shadow_destroy (xdisplay, mNoBorderShadow);
+
+ mNoBorderShadow = decor_shadow_create (xdisplay,
+ xscreen,
+ 1, 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0, 0, 0, 0,
+ &mShadowOptions,
+ &context,
+ decor_draw_simple,
+ 0);
+
+ if (mNoBorderShadow)
+ {
+ decor_extents_t extents = { 0, 0, 0, 0 };
+ long data[256];
+ decor_quad_t quads[N_QUADS_MAX];
+ int nQuad;
+ decor_layout_t layout;
+
+ decor_get_default_layout (&context, 1, 1, &layout);
+
+ nQuad = decor_set_lSrStSbS_window_quads (quads, &context, &layout);
+
+ decor_quads_to_property (data, mNoBorderShadow->pixmap,
+ &extents, &extents,
+ 0, 0, quads, nQuad);
+
+ KWD::trapXError ();
+ XChangeProperty (tqt_xdisplay (), tqt_xrootwin (),
+ Atoms::netWindowDecorBare,
+ XA_INTEGER,
+ 32, PropModeReplace, (unsigned char *) data,
+ BASE_PROP_SIZE + QUAD_PROP_SIZE * nQuad);
+ KWD::popXError ();
+ }
+}
+
+void
+KWD::Decorator::processDamage (void)
+{
+ TQMap <WId, KWD::Window *>::ConstIterator it;
+
+ mDecorNormal->processDamage ();
+ mDecorActive->processDamage ();
+
+ for (it = mClients.constBegin (); it != mClients.constEnd (); it++)
+ it.data ()->processDamage ();
+}
+
+bool
+KWD::Decorator::x11EventFilter (XEvent *xevent)
+{
+ KWD::Window *client;
+ int status;
+
+ switch (xevent->type) {
+ case MapNotify: {
+ XMapEvent *xme = reinterpret_cast <XMapEvent *> (xevent);
+
+ if (mWindows.contains (xme->window))
+ client = mWindows[xme->window];
+ else if (mDecorNormal->winId () == xme->window)
+ client = mDecorNormal;
+ else if (mDecorActive->winId () == xme->window)
+ client = mDecorActive;
+ else
+ break;
+
+ if (client->handleMap ())
+ {
+ if (!mIdleTimer.isActive ())
+ mIdleTimer.start (0, TRUE);
+ }
+ } break;
+ case ConfigureNotify: {
+ XConfigureEvent *xce = reinterpret_cast <XConfigureEvent *> (xevent);
+
+ if (mFrames.contains (xce->window))
+ mFrames[xce->window]->updateFrame (xce->window);
+
+ if (mWindows.contains (xce->window))
+ client = mWindows[xce->window];
+ else if (mDecorNormal->winId () == xce->window)
+ client = mDecorNormal;
+ else if (mDecorActive->winId () == xce->window)
+ client = mDecorActive;
+ else
+ break;
+
+ if (client->handleConfigure (TQSize (xce->width, xce->height)))
+ {
+ if (!mIdleTimer.isActive ())
+ mIdleTimer.start (0, TRUE);
+ }
+ } break;
+ case SelectionRequest:
+ decor_handle_selection_request (tqt_xdisplay (), xevent, mDmSnTimestamp);
+ break;
+ case SelectionClear:
+ status = decor_handle_selection_clear (tqt_xdisplay (),
+ xevent, 0);
+ if (status == DECOR_SELECTION_GIVE_UP)
+ TDEApplication::exit (0);
+
+ break;
+ case PropertyNotify:
+ if (xevent->xproperty.atom == Atoms::netFrameWindow)
+ {
+ handleWindowAdded (xevent->xproperty.window);
+ }
+ else if (xevent->xproperty.atom == Atoms::switchSelectWindow)
+ {
+ if (!mClients.contains (xevent->xproperty.window))
+ {
+ handleWindowAdded (xevent->xproperty.window);
+ }
+ else
+ {
+ WId id;
+
+ if (KWD::readWindowProperty (xevent->xproperty.window,
+ Atoms::switchSelectWindow,
+ (long *) &id))
+ mClients[xevent->xproperty.window]->updateSelected (id);
+ }
+ }
+ else if (xevent->xproperty.atom == Atoms::netWmWindowOpacity)
+ {
+ if (mClients.contains (xevent->xproperty.window))
+ mClients[xevent->xproperty.window]->updateOpacity ();
+ }
+ break;
+ case EnterNotify:
+ {
+ XCrossingEvent *xce = reinterpret_cast <XCrossingEvent *> (xevent);
+ TQWidget *widget, *child;
+
+ if (!mFrames.contains (xce->window))
+ break;
+
+ client = mFrames[xce->window];
+
+ widget = client->decoration ()->widget ();
+ child = widget->childAt (xce->x, xce->y, true);
+ if (child)
+ {
+ TQEvent qe (TQEvent::Enter);
+
+ TQApplication::sendEvent (child, &qe);
+
+ client->setActiveChild (child);
+ client->updateCursor (TQPoint (xce->x, xce->y));
+ }
+ } break;
+ case LeaveNotify:
+ {
+ XCrossingEvent *xce = reinterpret_cast <XCrossingEvent *> (xevent);
+
+ if (mFrames.contains (xce->window))
+ {
+ TQEvent qe (TQEvent::Leave);
+
+ client = mFrames[xce->window];
+
+ TQApplication::sendEvent (client->activeChild (), &qe);
+
+ XUndefineCursor (tqt_xdisplay (), client->frameId ());
+ }
+ } break;
+ case MotionNotify:
+ {
+ XMotionEvent *xme = reinterpret_cast < XMotionEvent * >(xevent);
+ TQWidget *widget, *child;
+
+ if (!mFrames.contains (xme->window))
+ break;
+
+ client = mFrames[xme->window];
+
+ widget = client->decoration ()->widget ();
+ child = widget->childAt (xme->x, xme->y, true);
+ if (child)
+ {
+ TQPoint qp (xme->x, xme->y);
+
+ if (child != client->activeChild ())
+ {
+ TQEvent qee (TQEvent::Enter);
+ TQEvent qle (TQEvent::Leave);
+
+ if (client->activeChild ())
+ TQApplication::sendEvent (client->activeChild (), &qle);
+
+ TQApplication::sendEvent (child, &qee);
+
+ client->setActiveChild (child);
+ }
+
+ if (widget != child)
+ qp -= TQPoint (child->pos ().x (), child->pos ().y ());
+
+ TQMouseEvent qme (TQEvent::MouseMove, qp, TQt::NoButton, TQt::NoButton);
+
+ TQApplication::sendEvent (child, &qme);
+
+ client->updateCursor (TQPoint (xme->x, xme->y));
+ }
+ } break;
+ case ButtonPress:
+ case ButtonRelease:
+ {
+ XButtonEvent *xbe = reinterpret_cast <XButtonEvent *>(xevent);
+ TQWidget *widget, *child;
+
+ if (!mFrames.contains (xbe->window))
+ break;
+
+ client = mFrames[xbe->window];
+
+ widget = client->decoration ()->widget ();
+ child = widget->childAt (xbe->x, xbe->y, true);
+
+ if (child)
+ {
+ XButtonEvent xbe2 = *xbe;
+
+ xbe2.window = child->winId ();
+ if (widget != child)
+ {
+ xbe2.x = xbe->x - child->pos ().x ();
+ xbe2.y = xbe->y - child->pos ().y ();
+ }
+
+ TQApplication::x11ProcessEvent ((XEvent *) &xbe2);
+
+ return true;
+ }
+ } break;
+ case ClientMessage:
+ if (xevent->xclient.message_type == Atoms::toolkitActionAtom)
+ {
+ unsigned long action;
+
+ action = xevent->xclient.data.l[0];
+ if (action == Atoms::toolkitActionWindowMenuAtom)
+ {
+ if (mClients.contains (xevent->xclient.window))
+ {
+ TQPoint pos;
+
+ client = mClients[xevent->xclient.window];
+
+ if (xevent->xclient.data.l[2])
+ {
+ pos = TQPoint (xevent->xclient.data.l[3],
+ xevent->xclient.data.l[4]);
+ }
+ else
+ {
+ pos = client->clientGeometry ().topLeft ();
+ }
+
+ client->showWindowMenu (pos);
+ }
+ }
+ else if (action == Atoms::toolkitActionForceQuitDialogAtom)
+ {
+ if (mClients.contains (xevent->xclient.window))
+ {
+ Time timestamp = xevent->xclient.data.l[1];
+
+ client = mClients[xevent->xclient.window];
+
+ if (xevent->xclient.data.l[2])
+ client->showKillProcessDialog (timestamp);
+ else
+ client->hideKillProcessDialog ();
+ }
+ }
+ }
+ break;
+ default:
+ if (xevent->type == mDamageEvent + XDamageNotify)
+ {
+ XDamageNotifyEvent *xde =
+ reinterpret_cast <XDamageNotifyEvent *>(xevent);
+
+ if (mWindows.contains (xde->drawable))
+ client = mWindows[xde->drawable];
+ else if (mDecorNormal->winId () == xde->drawable)
+ client = mDecorNormal;
+ else if (mDecorActive->winId () == xde->drawable)
+ client = mDecorActive;
+ else
+ break;
+
+ client->addDamageRect (xde->area.x,
+ xde->area.y,
+ xde->area.width,
+ xde->area.height);
+
+ if (client->pixmapId ())
+ {
+ if (!mIdleTimer.isActive ())
+ mIdleTimer.start (0, TRUE);
+ }
+
+ return true;
+ }
+ break;
+ }
+
+ return TDEApplication::x11EventFilter (xevent);
+}
+
+void
+KWD::Decorator::reconfigure (void)
+{
+ unsigned long changed;
+
+ mConfig->reparseConfiguration ();
+
+ changed = mOptions->updateSettings ();
+ if (mPlugins->reset (changed))
+ {
+ TQMap < WId, KWD::Window * >::ConstIterator it;
+
+ updateShadow ();
+
+ mDecorNormal->reloadDecoration ();
+ mDecorActive->reloadDecoration ();
+
+ for (it = mClients.constBegin (); it != mClients.constEnd (); it++)
+ it.data ()->reloadDecoration ();
+
+ mPlugins->destroyPreviousPlugin ();
+ }
+}
+
+void
+KWD::Decorator::handleWindowAdded (WId id)
+{
+ TQMap <WId, KWD::Window *>::ConstIterator it;
+ KWD::Window *client = 0;
+ WId select, frame = 0;
+ KWD::Window::Type type;
+ unsigned int width, height, border, depth;
+ int x, y;
+ XID root;
+ TQWidgetList *widgets;
+
+ /* avoid adding any of our own top level windows */
+ widgets = TQApplication::topLevelWidgets ();
+ if (widgets)
+ {
+ for (TQWidgetListIt it (*widgets); it.current (); ++it)
+ {
+ if (it.current ()->winId () == id)
+ {
+ delete widgets;
+ return;
+ }
+ }
+
+ delete widgets;
+ }
+
+ KWD::trapXError ();
+ XGetGeometry (tqt_xdisplay (), id, &root, &x, &y, &width, &height,
+ &border, &depth);
+ if (KWD::popXError ())
+ return;
+
+ KWD::readWindowProperty (id, Atoms::netFrameWindow, (long *) &frame);
+ if (KWD::readWindowProperty (id, Atoms::switchSelectWindow,
+ (long *) &select))
+ {
+ type = KWD::Window::Switcher;
+ }
+ else
+ {
+ KWin::WindowInfo wInfo = KWin::windowInfo (id, NET::WMWindowType, 0);
+
+ switch (wInfo.windowType (~0)) {
+ case NET::Normal:
+ case NET::Dialog:
+ case NET::Toolbar:
+ case NET::Menu:
+ case NET::Utility:
+ case NET::Splash:
+ case NET::Unknown:
+ /* decorate these window types */
+ break;
+ default:
+ return;
+ }
+
+ type = KWD::Window::Normal;
+ }
+
+ KWD::trapXError ();
+ XSelectInput (tqt_xdisplay (), id, StructureNotifyMask | PropertyChangeMask);
+ KWD::popXError ();
+
+ if (frame)
+ {
+ if (!mClients.contains (id))
+ {
+ client = new KWD::Window (mCompositeWindow, id, frame, type,
+ x, y,
+ width + border * 2,
+ height + border * 2);
+
+ mClients.insert (id, client);
+ mWindows.insert (client->winId (), client);
+ mFrames.insert (frame, client);
+ }
+ else
+ {
+ client = mClients[id];
+ mFrames.remove (client->frameId ());
+ mFrames.insert (frame, client);
+
+ client->updateFrame (frame);
+ }
+ }
+ else if (type == KWD::Window::Switcher)
+ {
+ if (!mClients.contains (id))
+ {
+ client = new KWD::Window (mCompositeWindow, id, 0, type,
+ x, y,
+ width + border * 2,
+ height + border * 2);
+ mClients.insert (id, client);
+ mWindows.insert (client->winId (), client);
+ }
+ }
+ else
+ {
+ if (mClients.contains (id))
+ client = mClients[id];
+
+ if (client)
+ {
+ mClients.remove (client->windowId ());
+ mWindows.remove (client->winId ());
+ mFrames.remove (client->frameId ());
+
+ delete client;
+ }
+ }
+}
+
+void
+KWD::Decorator::handleWindowRemoved (WId id)
+{
+ KWD::Window *window = 0;
+
+ if (mClients.contains (id))
+ window = mClients[id];
+ else if (mFrames.contains (id))
+ window = mFrames[id];
+
+ if (window)
+ {
+ mClients.remove (window->windowId ());
+ mWindows.remove (window->winId ());
+ mFrames.remove (window->frameId ());
+
+ delete window;
+ }
+}
+
+void
+KWD::Decorator::handleActiveWindowChanged (WId id)
+{
+ if (id != mActiveId)
+ {
+ KWD::Window *newActiveWindow = 0;
+ KWD::Window *oldActiveWindow = 0;
+
+ if (mClients.contains (id))
+ newActiveWindow = mClients[id];
+
+ if (mClients.contains (mActiveId))
+ oldActiveWindow = mClients[mActiveId];
+
+ mActiveId = id;
+
+ if (oldActiveWindow)
+ oldActiveWindow->handleActiveChange ();
+
+ if (newActiveWindow)
+ newActiveWindow->handleActiveChange ();
+ }
+}
+
+void
+KWD::Decorator::handleWindowChanged (WId id,
+ const unsigned long *properties)
+{
+ KWD::Window *client;
+
+ if (!mClients.contains (id))
+ return;
+
+ client = mClients[id];
+
+ if (properties[0] & NET::WMName)
+ client->updateName ();
+ if (properties[0] & NET::WMVisibleName)
+ client->updateName ();
+ if (properties[0] & NET::WMState)
+ client->updateState ();
+ if (properties[0] & NET::WMIcon)
+ client->updateIcons ();
+ if (properties[0] & NET::WMGeometry)
+ client->updateWindowGeometry ();
+}
+
+void
+KWD::Decorator::sendClientMessage (WId eventWid,
+ WId wid,
+ Atom atom,
+ Atom value,
+ long data1,
+ long data2,
+ long data3)
+{
+ XEvent ev;
+ long mask = 0;
+
+ memset (&ev, 0, sizeof (ev));
+
+ ev.xclient.type = ClientMessage;
+ ev.xclient.window = wid;
+ ev.xclient.message_type = atom;
+ ev.xclient.format = 32;
+
+ ev.xclient.data.l[0] = value;
+ ev.xclient.data.l[1] = tqt_x_time;
+ ev.xclient.data.l[2] = data1;
+ ev.xclient.data.l[3] = data2;
+ ev.xclient.data.l[4] = data3;
+
+ if (eventWid == tqt_xrootwin ())
+ mask = SubstructureRedirectMask | SubstructureNotifyMask;
+
+ KWD::trapXError ();
+ XSendEvent (tqt_xdisplay (), eventWid, false, mask, &ev);
+ KWD::popXError ();
+}
Index: b/tde/window-decorator/decorator.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ b/tde/window-decorator/decorator.h 2013-08-04 15:33:29.000000000 +0200
@@ -0,0 +1,183 @@
+/*
+ * Copyright © 2006 Novell, Inc.
+ * Copyright © 2006 Dennis Kasprzyk <onestone@beryl-project.org>
+ * Copyright © 2006 Volker Krause <vkrause@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * Author: David Reveman <davidr@novell.com>
+ */
+
+#ifndef _DECORATOR_H
+#define _DECORATOR_H
+
+#include <tdeapplication.h>
+
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#include <X11/cursorfont.h>
+
+#include <ntqtimer.h>
+
+#include <fixx11h.h>
+#include <tdeconfig.h>
+#include <kdecoration_plugins_p.h>
+#include <kdecoration_p.h>
+#include <netwm.h>
+
+#include <decoration.h>
+
+#define DBUS_API_SUBJECT_TO_CHANGE
+#include <dbus/connection.h>
+
+#include "window.h"
+#include "KWinInterface.h"
+
+#define ROOT_OFF_X 8192
+#define ROOT_OFF_Y 8192
+
+#define C(name) { 0, XC_ ## name }
+
+struct _cursor {
+ Cursor cursor;
+ unsigned int shape;
+};
+
+extern struct _cursor cursors[3][3];
+
+extern double decorationOpacity;
+extern bool decorationOpacityShade;
+extern double activeDecorationOpacity;
+extern bool activeDecorationOpacityShade;
+
+#define BLUR_TYPE_NONE 0
+#define BLUR_TYPE_TITLEBAR 1
+#define BLUR_TYPE_ALL 2
+
+extern int blurType;
+
+class TDEConfig;
+class KWinModule;
+
+namespace KWD
+{
+ class Options;
+
+class PluginManager:public KDecorationPlugins {
+ public:
+ PluginManager (TDEConfig *config);
+ virtual bool provides (Requirement)
+ {
+ return false;
+ }
+ };
+
+
+class Decorator:public TDEApplication, public KWinInterface {
+ TQ_OBJECT public:
+ Decorator (void);
+ ~Decorator (void);
+
+ static NETRootInfo *rootInfo (void)
+ {
+ return mRootInfo;
+ }
+ static PluginManager *pluginManager (void)
+ {
+ return mPlugins;
+ }
+ static KWD::Options *options (void)
+ {
+ return mOptions;
+ }
+ static WId activeId (void)
+ {
+ return mActiveId;
+ }
+ static decor_shadow_options_t *shadowOptions (void)
+ {
+ return &mShadowOptions;
+ }
+ static decor_shadow_t *defaultWindowShadow (decor_context_t *context,
+ decor_extents_t *border)
+ {
+ if (!mDefaultShadow)
+ return NULL;
+
+ if (memcmp (border, &mDefaultBorder, sizeof (decor_extents_t)) != 0)
+ return NULL;
+
+ *context = mDefaultContext;
+ return mDefaultShadow;
+ }
+ static void sendClientMessage (WId eventWid,
+ WId wid,
+ Atom atom,
+ Atom value,
+ long data1 = 0,
+ long data2 = 0,
+ long data3 = 0);
+ static void updateDefaultShadow (KWD::Window *w);
+
+ bool enableDecorations (Time timestamp, int damageEvent);
+ bool x11EventFilter (XEvent *xevent);
+ void changeShadowOptions (decor_shadow_options_t *opt);
+
+ public slots:
+ void reconfigure (void);
+
+ private:
+ DBusMessage *sendAndBlockForShadowOptionReply (const char *path);
+ WId fetchFrame (WId window);
+ void updateShadow (void);
+ void updateAllShadowOptions (void);
+
+ private slots:
+ void handleWindowAdded (WId id);
+ void handleWindowRemoved (WId id);
+ void handleActiveWindowChanged (WId id);
+ void handleWindowChanged (WId id,
+ const unsigned long *properties);
+ void processDamage (void);
+
+ private:
+ static PluginManager *mPlugins;
+ static KWD::Options *mOptions;
+ static decor_extents_t mDefaultBorder;
+ static decor_context_t mDefaultContext;
+ static decor_shadow_t *mDefaultShadow;
+ static decor_shadow_t *mNoBorderShadow;
+ static decor_shadow_options_t mShadowOptions;
+ static NETRootInfo *mRootInfo;
+ static WId mActiveId;
+
+ KWD::Window *mDecorNormal;
+ KWD::Window *mDecorActive;
+ TQMap <WId, KWD::Window *>mClients;
+ TQMap <WId, KWD::Window *>mFrames;
+ TQMap <WId, KWD::Window *>mWindows;
+ TDEConfig *mConfig;
+ Time mDmSnTimestamp;
+ int mDamageEvent;
+ TQTimer mIdleTimer;
+ KWinModule *mKWinModule;
+ DBusConnection *mDBusConnection;
+ DBusQt::Connection mDBusQtConnection;
+ WId mCompositeWindow;
+ };
+}
+
+#endif
Index: b/tde/window-decorator/main.cpp
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ b/tde/window-decorator/main.cpp 2013-08-04 15:55:52.000000000 +0200
@@ -0,0 +1,143 @@
+/*
+ * Copyright © 2006 Novell, Inc.
+ * Copyright © 2006 Dennis Kasprzyk <onestone@beryl-project.org>
+ * Copyright © 2006 Volker Krause <vkrause@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * Author: David Reveman <davidr@novell.com>
+ */
+
+#include <X11/Xlib.h>
+#include <X11/extensions/Xdamage.h>
+
+#include <fixx11h.h>
+#include <tdeapplication.h>
+#include <tdecmdlineargs.h>
+#include <tdelocale.h>
+
+#include "decorator.h"
+
+static const TDECmdLineOptions options[] = {
+ { "replace", "Replace existing window decorator", 0 },
+ { "sm-disable", "Disable connection to session manager", 0 },
+ { "opacity <value>", "Decoration opacity", "0.75" },
+ { "no-opacity-shade", "No decoration opacity shading", 0 },
+ { "active-opacity <value>", "Active decoration opacity", "1.0" },
+ { "no-active-opacity-shade", "No active decoration opacity shading", 0 },
+ { "blur <type>", "Blur type", "none" },
+ TDECmdLineLastOption
+};
+
+#include <kdebug.h>
+int
+main (int argc, char **argv)
+{
+ KWD::Decorator *app;
+ TDECmdLineArgs *args;
+ int status;
+ int event, error;
+ Time timestamp;
+
+ TDELocale::setMainCatalogue("twin");
+
+ TDECmdLineArgs::init (argc, argv,
+ "tde-window-decorator",
+ "KWD",
+ "TDE Window Decorator",
+ "0.0.1");
+ TDECmdLineArgs::addCmdLineOptions (options);
+ args = TDECmdLineArgs::parsedArgs ();
+
+ if (args->isSet ("opacity"))
+ decorationOpacity = args->getOption ("opacity").toDouble ();
+
+ if (args->isSet ("-opacity-shade"))
+ decorationOpacityShade = true;
+
+ if (args->isSet ("active-opacity"))
+ activeDecorationOpacity =
+ args->getOption ("active-opacity").toDouble ();
+
+ if (args->isSet ("-active-opacity-shade"))
+ activeDecorationOpacityShade = true;
+
+ if (args->isSet ("blur"))
+ {
+ TQString blur = args->getOption ("blur");
+
+ if (blur == TQString ("titlebar"))
+ blurType = BLUR_TYPE_TITLEBAR;
+ else if (blur == TQString ("all"))
+ blurType = BLUR_TYPE_ALL;
+ }
+
+ app = new KWD::Decorator ();
+
+ if (args->isSet ("sm-disable"))
+ app->disableSessionManagement ();
+
+ if (!XDamageQueryExtension (tqt_xdisplay (), &event, &error))
+ {
+ fprintf (stderr,
+ "%s: Damage extension is missing on display \"%s\"\n",
+ argv[0], DisplayString (tqt_xdisplay ()));
+
+ return 1;
+ }
+
+ status = decor_acquire_dm_session (tqt_xdisplay (), tqt_xscreen (), "kwd",
+ args->isSet ("replace"),
+ &timestamp);
+ if (status != DECOR_ACQUIRE_STATUS_SUCCESS)
+ {
+ if (status == DECOR_ACQUIRE_STATUS_FAILED)
+ {
+ fprintf (stderr,
+ "%s: Could not acquire decoration manager "
+ "selection on screen %d display \"%s\"\n",
+ argv[0], tqt_xscreen (), DisplayString (tqt_xdisplay ()));
+ }
+ else if (status == DECOR_ACQUIRE_STATUS_OTHER_DM_RUNNING)
+ {
+ fprintf (stderr,
+ "%s: Screen %d on display \"%s\" already "
+ "has a decoration manager; try using the "
+ "--replace option to replace the current "
+ "decoration manager.\n",
+ argv[0], tqt_xscreen (), DisplayString (tqt_xdisplay ()));
+ }
+
+ return 1;
+ }
+
+ decor_set_dm_check_hint (tqt_xdisplay (), tqt_xscreen ());
+
+ if (!app->enableDecorations (timestamp, event))
+ {
+ fprintf (stderr,
+ "%s: Could not enable decorations on display \"%s\"\n",
+ argv[0], DisplayString (tqt_xdisplay ()));
+
+ return 1;
+ }
+
+ status = app->exec ();
+
+ delete app;
+
+ return status;
+}
Index: b/tde/window-decorator/options.cpp
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ b/tde/window-decorator/options.cpp 2013-08-04 11:50:18.000000000 +0200
@@ -0,0 +1,187 @@
+/*
+ * Copyright © 2006 Novell, Inc.
+ * Copyright © 2006 Dennis Kasprzyk <onestone@beryl-project.org>
+ * Copyright © 2006 Volker Krause <vkrause@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * Author: David Reveman <davidr@novell.com>
+ */
+
+#include "options.h"
+
+#include <tdeconfig.h>
+#include <kdecoration_p.h>
+
+KWD::Options::Options (TDEConfig *config): KDecorationOptions (), mConfig (config)
+{
+ d = new KDecorationOptionsPrivate;
+ updateSettings ();
+}
+
+unsigned long
+KWD::Options::updateSettings (void)
+{
+ unsigned long changed = 0;
+
+ changed |= d->updateKWinSettings (mConfig);
+
+ mConfig->setGroup ("Windows");
+
+ OpTitlebarDblClick =
+ windowOperation (mConfig->readEntry ("TitlebarDoubleClickCommand",
+ "Shade"), true);
+ d->OpMaxButtonLeftClick =
+ windowOperation (mConfig->readEntry ("MaximizeButtonLeftClickCommand",
+ "Maximize"), true);
+ d->OpMaxButtonMiddleClick =
+ windowOperation (mConfig->readEntry ("MaximizeButtonMiddleClickCommand",
+ "Maximize (vertical only)"), true);
+ d->OpMaxButtonRightClick =
+ windowOperation (mConfig->readEntry ("MaximizeButtonRightClickCommand",
+ "Maximize (horizontal only)"),
+ true);
+
+ mConfig->setGroup ("MouseBindings");
+
+ CmdActiveTitlebar1 =
+ mouseCommand (mConfig->readEntry ("CommandActiveTitlebar1",
+ "Raise"), true);
+ CmdActiveTitlebar2 =
+ mouseCommand (mConfig->readEntry ("CommandActiveTitlebar2",
+ "Lower"), true);
+ CmdActiveTitlebar3 =
+ mouseCommand (mConfig->readEntry ("CommandActiveTitlebar3",
+ "Operations menu"), true);
+ CmdInactiveTitlebar1 =
+ mouseCommand (mConfig->readEntry ("CommandInactiveTitlebar1",
+ "Activate and raise"), true);
+ CmdInactiveTitlebar2 =
+ mouseCommand (mConfig->readEntry ("CommandInactiveTitlebar2",
+ "Activate and lower"), true);
+ CmdInactiveTitlebar3 =
+ mouseCommand (mConfig->readEntry ("CommandInactiveTitlebar3",
+ "Operations menu"), true);
+
+ CmdTitlebarWheel =
+ mouseWheelCommand (mConfig->readEntry ("CommandTitlebarWheel",
+ "Nothing"));
+
+ return changed;
+}
+
+// restricted should be true for operations that the user may not be able to
+// repeat if the window is moved out of the workspace (e.g. if the user moves
+// a window by the titlebar, and moves it too high beneath Kicker at the top
+// edge, they may not be able to move it back, unless they know about Alt+LMB)
+KDecorationDefines::WindowOperation
+KWD::Options::windowOperation (const TQString &name, bool restricted)
+{
+ if (name == "Move")
+ return restricted ? KWD::Options::MoveOp :
+ KWD::Options::UnrestrictedMoveOp;
+ else if (name == "Resize")
+ return restricted ? KWD::Options::ResizeOp :
+ KWD::Options::UnrestrictedResizeOp;
+ else if (name == "Maximize")
+ return KWD::Options::MaximizeOp;
+ else if (name == "Minimize")
+ return KWD::Options::MinimizeOp;
+ else if (name == "Close")
+ return KWD::Options::CloseOp;
+ else if (name == "OnAllDesktops")
+ return KWD::Options::OnAllDesktopsOp;
+ else if (name == "Shade")
+ return KWD::Options::ShadeOp;
+ else if (name == "Operations")
+ return KWD::Options::OperationsOp;
+ else if (name == "Maximize (vertical only)")
+ return KWD::Options::VMaximizeOp;
+ else if (name == "Maximize (horizontal only)")
+ return KWD::Options::HMaximizeOp;
+ else if (name == "Lower")
+ return KWD::Options::LowerOp;
+ return KWD::Options::NoOp;
+}
+
+KWD::Options::MouseCommand
+KWD::Options::mouseCommand (const TQString &name,
+ bool restricted)
+{
+ TQString lowerName = name.lower ();
+
+ if (lowerName == "raise") return MouseRaise;
+ if (lowerName == "lower") return MouseLower;
+ if (lowerName == "operations menu") return MouseOperationsMenu;
+ if (lowerName == "toggle raise and lower") return MouseToggleRaiseAndLower;
+ if (lowerName == "activate and raise") return MouseActivateAndRaise;
+ if (lowerName == "activate and lower") return MouseActivateAndLower;
+ if (lowerName == "activate") return MouseActivate;
+ if (lowerName == "activate, raise and pass click")
+ return MouseActivateRaiseAndPassClick;
+ if (lowerName == "activate and pass click")
+ return MouseActivateAndPassClick;
+ if (lowerName == "activate, raise and move")
+ return restricted ? MouseActivateRaiseAndMove :
+ MouseActivateRaiseAndUnrestrictedMove;
+ if (lowerName == "move")
+ return restricted ? MouseMove : MouseUnrestrictedMove;
+ if (lowerName == "resize")
+ return restricted ? MouseResize : MouseUnrestrictedResize;
+ if (lowerName == "shade") return MouseShade;
+ if (lowerName == "minimize") return MouseMinimize;
+ if (lowerName == "nothing") return MouseNothing;
+
+ return MouseNothing;
+}
+
+KWD::Options::MouseWheelCommand
+KWD::Options::mouseWheelCommand (const TQString &name)
+{
+ TQString lowerName = name.lower ();
+
+ if (lowerName == "raise/lower") return MouseWheelRaiseLower;
+ if (lowerName == "shade/unshade") return MouseWheelShadeUnshade;
+ if (lowerName == "maximize/restore") return MouseWheelMaximizeRestore;
+ if (lowerName == "above/below") return MouseWheelAboveBelow;
+ if (lowerName == "previous/next desktop")
+ return MouseWheelPreviousNextDesktop;
+ if (lowerName == "change opacity") return MouseWheelChangeOpacity;
+
+ return MouseWheelNothing;
+}
+
+KWD::Options::MouseCommand
+KWD::Options::wheelToMouseCommand (MouseWheelCommand com,
+ int delta)
+{
+ switch (com) {
+ case MouseWheelRaiseLower:
+ return delta > 0 ? MouseRaise : MouseLower;
+ case MouseWheelShadeUnshade:
+ return delta > 0 ? MouseSetShade : MouseUnsetShade;
+ case MouseWheelMaximizeRestore:
+ return delta > 0 ? MouseMaximize : MouseRestore;
+ case MouseWheelAboveBelow:
+ return delta > 0 ? MouseAbove : MouseBelow;
+ case MouseWheelPreviousNextDesktop:
+ return delta > 0 ? MousePreviousDesktop : MouseNextDesktop;
+ case MouseWheelChangeOpacity:
+ return delta > 0 ? MouseOpacityMore : MouseOpacityLess;
+ default:
+ return MouseNothing;
+ }
+}
Index: b/tde/window-decorator/options.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ b/tde/window-decorator/options.h 2013-08-04 11:50:18.000000000 +0200
@@ -0,0 +1,140 @@
+/*
+ * Copyright © 2006 Novell, Inc.
+ * Copyright © 2006 Dennis Kasprzyk <onestone@beryl-project.org>
+ * Copyright © 2006 Volker Krause <vkrause@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * Author: David Reveman <davidr@novell.com>
+ */
+
+#ifndef _OPTIONS_H
+#define _OPTIONS_H
+
+#include <kdecoration.h>
+
+class TDEConfig;
+
+namespace KWD
+{
+
+class Options : public KDecorationOptions
+ {
+ public:
+ enum MouseCommand
+ {
+ MouseRaise,
+ MouseLower,
+ MouseOperationsMenu,
+ MouseToggleRaiseAndLower,
+ MouseActivateAndRaise,
+ MouseActivateAndLower,
+ MouseActivate,
+ MouseActivateRaiseAndPassClick,
+ MouseActivateAndPassClick,
+ MouseMove,
+ MouseUnrestrictedMove,
+ MouseActivateRaiseAndMove,
+ MouseActivateRaiseAndUnrestrictedMove,
+ MouseResize,
+ MouseUnrestrictedResize,
+ MouseShade,
+ MouseSetShade,
+ MouseUnsetShade,
+ MouseMaximize,
+ MouseRestore,
+ MouseMinimize,
+ MouseNextDesktop,
+ MousePreviousDesktop,
+ MouseAbove,
+ MouseBelow,
+ MouseOpacityMore,
+ MouseOpacityLess,
+ MouseNothing
+ };
+ enum MouseWheelCommand
+ {
+ MouseWheelRaiseLower,
+ MouseWheelShadeUnshade,
+ MouseWheelMaximizeRestore,
+ MouseWheelAboveBelow,
+ MouseWheelPreviousNextDesktop,
+ MouseWheelChangeOpacity,
+ MouseWheelNothing
+ };
+
+ Options (TDEConfig *config);
+
+ virtual unsigned long updateSettings (void);
+
+ WindowOperation operationTitlebarDblClick (void)
+ {
+ return OpTitlebarDblClick;
+ }
+
+ MouseCommand commandActiveTitlebar1 (void)
+ {
+ return CmdActiveTitlebar1;
+ }
+ MouseCommand commandActiveTitlebar2 (void)
+ {
+ return CmdActiveTitlebar2;
+ }
+ MouseCommand commandActiveTitlebar3 (void)
+ {
+ return CmdActiveTitlebar3;
+ }
+ MouseCommand commandInactiveTitlebar1 (void)
+ {
+ return CmdInactiveTitlebar1;
+ }
+ MouseCommand commandInactiveTitlebar2 (void)
+ {
+ return CmdInactiveTitlebar2;
+ }
+ MouseCommand commandInactiveTitlebar3 (void)
+ {
+ return CmdInactiveTitlebar3;
+ }
+
+ MouseCommand operationTitlebarMouseWheel (int delta)
+ {
+ return wheelToMouseCommand (CmdTitlebarWheel, delta);
+ }
+
+ private:
+ static KDecorationDefines::WindowOperation
+ windowOperation (const TQString &name, bool restricted);
+ MouseCommand mouseCommand (const TQString &name, bool restricted);
+ MouseWheelCommand mouseWheelCommand (const TQString &name);
+ MouseCommand wheelToMouseCommand (MouseWheelCommand com, int delta);
+
+ private:
+ KDecorationDefines::WindowOperation OpTitlebarDblClick;
+ MouseCommand CmdActiveTitlebar1;
+ MouseCommand CmdActiveTitlebar2;
+ MouseCommand CmdActiveTitlebar3;
+ MouseCommand CmdInactiveTitlebar1;
+ MouseCommand CmdInactiveTitlebar2;
+ MouseCommand CmdInactiveTitlebar3;
+ MouseWheelCommand CmdTitlebarWheel;
+
+ TDEConfig *mConfig;
+ };
+
+}
+
+#endif
Index: b/tde/window-decorator/utils.cpp
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ b/tde/window-decorator/utils.cpp 2013-08-04 15:43:56.000000000 +0200
@@ -0,0 +1,206 @@
+/*
+ * Copyright © 2006 Novell, Inc.
+ * Copyright © 2006 Dennis Kasprzyk <onestone@beryl-project.org>
+ * Copyright © 2006 Volker Krause <vkrause@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * Author: David Reveman <davidr@novell.com>
+ */
+
+#include "utils.h"
+
+#include <ntqstyle.h>
+#include <ntqt.h>
+
+#include <decoration.h>
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+
+#include <stdlib.h>
+
+static int trappedErrorCode = 0;
+
+namespace KWD
+{
+ namespace Atoms
+ {
+ Atom switchSelectWindow;
+ Atom netWmWindowOpacity;
+ Atom netFrameWindow;
+ Atom netWindowDecor;
+ Atom netWindowDecorNormal;
+ Atom netWindowDecorActive;
+ Atom netWindowDecorBare;
+ Atom wmTakeFocus;
+ Atom netWmContextHelp;
+ Atom wmProtocols;
+ Atom toolkitActionAtom;
+ Atom toolkitActionWindowMenuAtom;
+ Atom toolkitActionForceQuitDialogAtom;
+ Atom compizWindowBlurDecor;
+ }
+}
+
+static int (*oldErrorHandler) (Display *display, XErrorEvent *error);
+
+static int
+xErrorHandler (Display *display,
+ XErrorEvent *error)
+{
+ (void) display;
+
+ trappedErrorCode = error->error_code;
+
+ return 0;
+}
+
+void
+KWD::trapXError (void)
+{
+ trappedErrorCode = 0;
+ oldErrorHandler = XSetErrorHandler (xErrorHandler);
+}
+
+int
+KWD::popXError (void)
+{
+ XSync (tqt_xdisplay(), false);
+ XSetErrorHandler (oldErrorHandler);
+
+ return trappedErrorCode;
+}
+
+void *
+KWD::readXProperty (WId window,
+ Atom property,
+ Atom type,
+ int *items)
+{
+ long offset = 0, length = 2048L;
+ Atom actualType;
+ int format;
+ unsigned long nItems, bytesRemaining;
+ unsigned char *data = 0l;
+ int result;
+
+ KWD::trapXError ();
+ result = XGetWindowProperty (tqt_xdisplay (), window, property, offset,
+ length, false, type,
+ &actualType, &format, &nItems,
+ &bytesRemaining, &data);
+
+ if (KWD::popXError ())
+ return NULL;
+
+ if (result == Success && actualType == type && format == 32 && nItems > 0)
+ {
+ if (items)
+ *items = nItems;
+
+ return reinterpret_cast <void *>(data);
+ }
+
+ if (data)
+ XFree (data);
+
+ if (items)
+ *items = 0;
+
+ return NULL;
+}
+
+bool
+KWD::readWindowProperty (long window,
+ long property,
+ long *value)
+{
+ void *data = readXProperty (window, property, XA_WINDOW, NULL);
+
+ if (data)
+ {
+ if (value)
+ *value = *reinterpret_cast <int *>(data);
+
+ XFree (data);
+
+ return true;
+ }
+
+ return false;
+}
+
+unsigned short
+KWD::readPropertyShort (WId id,
+ Atom property,
+ unsigned short defaultValue)
+{
+ Atom actual;
+ int result, format;
+ unsigned long n, left;
+ unsigned char *data;
+
+ KWD::trapXError ();
+ result = XGetWindowProperty (tqt_xdisplay (), id, property,
+ 0L, 1L, FALSE, XA_CARDINAL, &actual, &format,
+ &n, &left, &data);
+ if (KWD::popXError ())
+ return defaultValue;
+
+ if (result == Success && n && data)
+ {
+ unsigned int value;
+
+ memcpy (&value, data, sizeof (unsigned int));
+
+ XFree (data);
+
+ return value >> 16;
+ }
+
+ return defaultValue;
+}
+
+void
+KWD::Atoms::init (void)
+{
+ Display *xdisplay = tqt_xdisplay ();
+
+ netFrameWindow = XInternAtom (xdisplay, "_NET_FRAME_WINDOW", false);
+ netWindowDecor = XInternAtom (xdisplay, DECOR_WINDOW_ATOM_NAME, false);
+ netWindowDecorNormal =
+ XInternAtom (xdisplay, DECOR_NORMAL_ATOM_NAME, false);
+ netWindowDecorActive =
+ XInternAtom (xdisplay, DECOR_ACTIVE_ATOM_NAME, false);
+ netWindowDecorBare =
+ XInternAtom (xdisplay, DECOR_BARE_ATOM_NAME, false);
+ switchSelectWindow =
+ XInternAtom (xdisplay, DECOR_SWITCH_WINDOW_ATOM_NAME, false);
+ wmTakeFocus = XInternAtom (xdisplay, "WM_TAKE_FOCUS", false);
+ netWmContextHelp =
+ XInternAtom (xdisplay, "_NET_WM_CONTEXT_HELP", false);
+ wmProtocols = XInternAtom (xdisplay, "WM_PROTOCOLS", false);
+ netWmWindowOpacity =
+ XInternAtom (xdisplay, "_NET_WM_WINDOW_OPACITY", false);
+ toolkitActionAtom = XInternAtom (xdisplay, "_COMPIZ_TOOLKIT_ACTION", false);
+ toolkitActionWindowMenuAtom =
+ XInternAtom (xdisplay, "_COMPIZ_TOOLKIT_ACTION_WINDOW_MENU", false);
+ toolkitActionForceQuitDialogAtom =
+ XInternAtom (xdisplay, "_COMPIZ_TOOLKIT_ACTION_FORCE_QUIT_DIALOG",
+ false);
+ compizWindowBlurDecor =
+ XInternAtom (xdisplay, DECOR_BLUR_ATOM_NAME, false);
+}
Index: b/tde/window-decorator/utils.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ b/tde/window-decorator/utils.h 2013-08-04 11:50:18.000000000 +0200
@@ -0,0 +1,63 @@
+/*
+ * Copyright © 2006 Novell, Inc.
+ * Copyright © 2006 Dennis Kasprzyk <onestone@beryl-project.org>
+ * Copyright © 2006 Volker Krause <vkrause@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * Author: David Reveman <davidr@novell.com>
+ */
+
+#ifndef _UTILS_H
+#define _UTILS_H
+
+#include <X11/Xlib.h>
+#include <fixx11h.h>
+#include <ntqwidget.h>
+
+namespace KWD
+{
+ namespace Atoms
+ {
+ extern Atom switchSelectWindow;
+ extern Atom netWmWindowOpacity;
+ extern Atom netFrameWindow;
+ extern Atom netWindowDecor;
+ extern Atom netWindowDecorNormal;
+ extern Atom netWindowDecorActive;
+ extern Atom netWindowDecorBare;
+ extern Atom wmTakeFocus;
+ extern Atom netWmContextHelp;
+ extern Atom wmProtocols;
+ extern Atom toolkitActionAtom;
+ extern Atom toolkitActionWindowMenuAtom;
+ extern Atom toolkitActionForceQuitDialogAtom;
+ extern Atom compizWindowBlurDecor;
+
+ void init (void);
+ }
+
+ void trapXError (void);
+ int popXError (void);
+ bool eventFilter (void *message, long *result);
+ void *readXProperty (WId window, Atom property, Atom type, int *items);
+ bool readWindowProperty (long wId, long property, long *value);
+ unsigned short readPropertyShort (WId id,
+ Atom property,
+ unsigned short defaultValue);
+}
+
+#endif
Index: b/tde/window-decorator/window.cpp
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ b/tde/window-decorator/window.cpp 2013-08-04 15:44:11.000000000 +0200
@@ -0,0 +1,2165 @@
+/*
+ * Copyright © 2006 Novell, Inc.
+ * Copyright © 2006 Dennis Kasprzyk <onestone@beryl-project.org>
+ * Copyright © 2006 Volker Krause <vkrause@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * Author: David Reveman <davidr@novell.com>
+ */
+
+#include "window.h"
+#include "decorator.h"
+#include "options.h"
+#include "utils.h"
+
+#include <X11/Xlib.h>
+#include <X11/extensions/shape.h>
+#include <X11/extensions/Xcomposite.h>
+#include <X11/Xregion.h>
+
+#include <fixx11h.h>
+
+#include <kdebug.h>
+#include <tdeglobal.h>
+#include <tdeglobalsettings.h>
+#include <kiconloader.h>
+#include <kdecoration.h>
+#include <twin.h>
+#include <twinmodule.h>
+#include <tdelocale.h>
+#include <kprocess.h>
+#include <kstandarddirs.h>
+
+#include <ntqapplication.h>
+#include <ntqlayout.h>
+#include <ntqevent.h>
+#include <ntqpainter.h>
+#include <ntqobjectlist.h>
+#include <ntqwidget.h>
+#include <ntqstring.h>
+#include <ntqtimer.h>
+#include <ntqcursor.h>
+#include <ntqpopupmenu.h>
+
+int viewportMenuID;
+
+KWD::Window::Window (WId parentId,
+ WId clientId,
+ WId frame,
+ Type type,
+ int x,
+ int y,
+ int w,
+ int h): TQWidget (0, 0),
+ mType (type),
+ mParentId (parentId),
+ mFrame (0),
+ mClientId (clientId),
+ mSelectedId (0),
+ mDecor (0),
+ mPixmap (0),
+ mDamageId (0),
+ mShadow (0),
+ mPicture (0),
+ mTexturePicture (0),
+ mDecorationPicture (0),
+ mUpdateProperty (false),
+ mShapeSet (false),
+ mUniqueHorzShape (false),
+ mUniqueVertShape (false),
+ mPopup (0),
+ mAdvancedMenu (0),
+ mDesktopMenu (0),
+ mMapped (false),
+ mPendingMap (0),
+ mPendingConfigure (0),
+ mProcessKiller (0)
+{
+ memset (&mBorder, 0, sizeof (mBorder));
+
+ if (mType == Normal || mType == Switcher)
+ {
+ KWin::WindowInfo wInfo = KWin::windowInfo (mClientId, NET::WMState |
+ NET::WMVisibleName, 0);
+
+ mState = wInfo.state ();
+
+ if (mType == Normal)
+ {
+ mName = wInfo.visibleName ();
+
+ mIcons = TQIconSet (KWin::icon (mClientId, 16, 16, TRUE),
+ KWin::icon (mClientId, 32, 32, TRUE));
+ mOpacity = readPropertyShort (mClientId, Atoms::netWmWindowOpacity,
+ 0xffff);
+ }
+ else
+ {
+ mIcons = TQIconSet ();
+ mName = TQString ("");
+ }
+
+ updateFrame (frame);
+
+ mGeometry = TQRect (x, y, w, h);
+
+ getWindowProtocols ();
+ }
+ else
+ {
+ mIcons = TQIconSet ();
+ mName = TQString ("");
+ mGeometry = TQRect (50, 50, 30, 1);
+ }
+
+ setGeometry (TQRect (mGeometry.x () + ROOT_OFF_X,
+ mGeometry.y () + ROOT_OFF_Y,
+ mGeometry.width (), mGeometry.height ()));
+
+ createDecoration ();
+
+ mActiveChild = NULL;
+}
+
+KWD::Window::~Window (void)
+{
+ if (mShadow)
+ decor_shadow_destroy (tqt_xdisplay (), mShadow);
+
+ if (mPicture)
+ XRenderFreePicture (tqt_xdisplay (), mPicture);
+
+ if (mPixmap)
+ XFreePixmap (tqt_xdisplay (), mPixmap);
+
+ if (mTexturePicture)
+ XRenderFreePicture (tqt_xdisplay (), mTexturePicture);
+
+ if (mDecorationPicture)
+ XRenderFreePicture (tqt_xdisplay (), mDecorationPicture);
+
+ if (mDecor)
+ delete mDecor;
+
+ if (mPopup)
+ delete mPopup;
+
+ if (mProcessKiller)
+ delete mProcessKiller;
+}
+
+bool
+KWD::Window::isActive (void) const
+{
+ if (mType == DefaultActive)
+ return true;
+
+ if (mType == Switcher)
+ return true;
+
+ return Decorator::activeId () == mClientId;
+}
+
+bool
+KWD::Window::isCloseable (void) const
+{
+ KWin::WindowInfo wInfo;
+
+ if (mType != Normal)
+ return false;
+
+ wInfo = KWin::windowInfo (mClientId, NET::WMPid, NET::WM2AllowedActions);
+ return wInfo.actionSupported (NET::ActionClose);
+}
+
+bool
+KWD::Window::isMaximizable (void) const
+{
+ KWin::WindowInfo wInfo;
+
+ if (mType != Normal)
+ return false;
+
+ wInfo = KWin::windowInfo (mClientId, NET::WMPid, NET::WM2AllowedActions);
+ return wInfo.actionSupported (NET::ActionMax);
+}
+
+KDecoration::MaximizeMode
+KWD::Window::maximizeMode (void) const
+{
+ MaximizeMode mode = MaximizeRestore;
+
+ if (mType != Normal)
+ return mode;
+
+ mode =
+ ((mState & NET::MaxVert) ? MaximizeVertical : MaximizeRestore) |
+ ((mState & NET::MaxHoriz) ? MaximizeHorizontal : MaximizeRestore);
+
+ return mode;
+}
+
+bool
+KWD::Window::isMinimizable (void) const
+{
+ KWin::WindowInfo wInfo;
+
+ if (mType != Normal)
+ return false;
+
+ wInfo = KWin::windowInfo (mClientId, NET::WMPid, NET::WM2AllowedActions);
+ return wInfo.actionSupported (NET::ActionMinimize);
+}
+
+bool
+KWD::Window::providesContextHelp (void) const
+{
+ if (mType != Normal)
+ return false;
+
+ return mSupportContextHelp;
+}
+
+int
+KWD::Window::desktop (void) const
+{
+ KWin::WindowInfo wInfo = KWin::windowInfo (mClientId, NET::WMDesktop, 0);
+
+ return wInfo.desktop ();
+}
+
+bool
+KWD::Window::isModal (void) const
+{
+ return mState & NET::Modal;
+}
+
+bool
+KWD::Window::isShadeable (void) const
+{
+ KWin::WindowInfo wInfo = KWin::windowInfo (mClientId, NET::WMPid,
+ NET::WM2AllowedActions);
+
+ return wInfo.actionSupported (NET::ActionShade);
+}
+
+bool
+KWD::Window::isShade (void) const
+{
+ if (mType != Normal)
+ return false;
+
+ return (mState & NET::Shaded);
+}
+
+bool
+KWD::Window::isSetShade (void) const
+{
+ return isShade ();
+}
+
+bool
+KWD::Window::keepAbove (void) const
+{
+ if (mType != Normal)
+ return false;
+
+ return (mState & NET::KeepAbove);
+}
+
+bool
+KWD::Window::keepBelow (void) const
+{
+ if (mType != Normal)
+ return false;
+
+ return (mState & NET::KeepBelow);
+}
+
+bool
+KWD::Window::isMovable (void) const
+{
+ KWin::WindowInfo wInfo = KWin::windowInfo (mClientId, NET::WMPid,
+ NET::WM2AllowedActions);
+
+ return wInfo.actionSupported (NET::ActionMove);
+}
+
+NET::WindowType
+KWD::Window::windowType (unsigned long mask) const
+{
+ KWin::WindowInfo wInfo = KWin::windowInfo (mClientId, NET::WMWindowType, 0);
+
+ return wInfo.windowType (mask);
+}
+
+bool
+KWD::Window::isResizable (void) const
+{
+ KWin::WindowInfo wInfo = KWin::windowInfo (mClientId, NET::WMPid,
+ NET::WM2AllowedActions);
+
+ return wInfo.actionSupported (NET::ActionResize);
+}
+
+TQIconSet
+KWD::Window::icon (void) const
+{
+ return mIcons;
+}
+
+TQString
+KWD::Window::caption (void) const
+{
+ return mName;
+}
+
+/* TODO: We should use libtaskmanager, which is part of tdebase to create
+ the window menu instead but the headers for that library are currently
+ not installed. If tdebase could install those headers, we wouldn't have
+ to have our own window menu implementaion here. */
+void
+KWD::Window::showWindowMenu (TQPoint pos)
+{
+ if (!mPopup)
+ {
+ mPopup = new TQPopupMenu ();
+ mPopup->setCheckable (true);
+ mPopup->setFont (TDEGlobalSettings::menuFont ());
+
+ mAdvancedMenu = new TQPopupMenu (mPopup);
+ mAdvancedMenu->setCheckable (true);
+ mAdvancedMenu->setFont (TDEGlobalSettings::menuFont ());
+
+ connect (mAdvancedMenu, SIGNAL (activated (int)),
+ SLOT (handlePopupActivated (int)));
+
+ mAdvancedMenu->insertItem (SmallIconSet ("up"),
+ i18n ("Keep &Above Others"),
+ Options::KeepAboveOp);
+ mAdvancedMenu->insertItem (SmallIconSet ("down"),
+ i18n ("Keep &Below Others"),
+ Options::KeepBelowOp);
+ mAdvancedMenu->insertItem (SmallIconSet ("window_fullscreen"),
+ i18n ("&Fullscreen"),
+ Options::FullScreenOp);
+
+ mPopup->insertItem (i18n ("Ad&vanced"), mAdvancedMenu);
+
+ mDesktopMenu = new TQPopupMenu (mPopup);
+ mDesktopMenu->setCheckable (true);
+ mDesktopMenu->setFont (TDEGlobalSettings::menuFont ());
+
+ connect (mDesktopMenu, SIGNAL (activated (int)),
+ SLOT (handleDesktopPopupActivated (int)));
+
+ mPopup->insertItem (i18n ("To &Desktop"), mDesktopMenu, Options::NoOp);
+
+ mViewportMenu = new TQPopupMenu (mPopup);
+ mViewportMenu->setCheckable (true);
+ mViewportMenu->setFont (TDEGlobalSettings::menuFont ());
+
+ connect (mViewportMenu, SIGNAL (activated (int)),
+ SLOT (handleViewportPopupActivated (int)));
+
+ viewportMenuID = mPopup->insertItem (i18n ("To &Viewport"), mViewportMenu);
+
+ mPopup->insertItem (SmallIconSet ("move"), i18n ("&Move"),
+ Options::MoveOp);
+ mPopup->insertItem (i18n ("Re&size"), Options::ResizeOp);
+
+ mPopup->insertItem (i18n ("Mi&nimize"), Options::MinimizeOp);
+ mPopup->insertItem (i18n ("Ma&ximize"), Options::MaximizeOp);
+ mPopup->insertItem (i18n ("Sh&ade"), Options::ShadeOp);
+
+ mPopup->insertSeparator ();
+
+ mPopup->insertItem (SmallIconSet ("fileclose"), i18n ("&Close"),
+ Options::CloseOp);
+
+ connect (mPopup, SIGNAL (aboutToShow ()),
+ SLOT (handlePopupAboutToShow ()));
+ connect (mPopup, SIGNAL (activated (int)),
+ SLOT (handlePopupActivated (int)));
+ }
+
+ mPopup->exec (pos);
+}
+
+void
+KWD::Window::showWindowMenu (const TQRect &pos)
+{
+ showWindowMenu (pos.bottomLeft ());
+}
+
+void
+KWD::Window::processMousePressEvent (TQMouseEvent *qme)
+{
+ Options::MouseCommand com = Options::MouseNothing;
+ bool active = isActive ();
+
+ if (!mSupportTakeFocus)
+ active = TRUE;
+
+ switch (qme->button ()) {
+ case TQt::LeftButton:
+ com = active ? Decorator::options ()->commandActiveTitlebar1 () :
+ Decorator::options()->commandInactiveTitlebar1 ();
+ break;
+ case TQt::MidButton:
+ com = active ? Decorator::options ()->commandActiveTitlebar2 () :
+ Decorator::options()->commandInactiveTitlebar2 ();
+ break;
+ case TQt::RightButton:
+ com = active ? Decorator::options ()->commandActiveTitlebar3 () :
+ Decorator::options()->commandInactiveTitlebar3 ();
+ default:
+ break;
+ }
+
+ if (qme->button () == TQt::LeftButton)
+ {
+ // actions where it's not possible to get the matching release event
+ if (com != Options::MouseOperationsMenu &&
+ com != Options::MouseMinimize)
+ {
+ moveWindow (qme);
+ return;
+ }
+ }
+
+ performMouseCommand (com, qme);
+}
+
+void
+KWD::Window::performWindowOperation (WindowOperation wo)
+{
+ switch (wo) {
+ case KDecoration::MaximizeOp:
+ maximize (maximizeMode () == KDecoration::MaximizeFull ?
+ KDecoration::MaximizeRestore : KDecoration::MaximizeFull);
+ break;
+ case KDecoration::HMaximizeOp:
+ maximize (maximizeMode () ^ KDecoration::MaximizeHorizontal);
+ break;
+ case KDecoration::VMaximizeOp:
+ maximize (maximizeMode () ^ KDecoration::MaximizeVertical);
+ break;
+ case KDecoration::MinimizeOp:
+ minimize ();
+ break;
+ case KDecoration::ShadeOp:
+ setShade (!isShade ());
+ break;
+ case KDecoration::CloseOp:
+ closeWindow ();
+ break;
+ case KDecoration::KeepAboveOp:
+ setKeepAbove (!keepAbove ());
+ break;
+ case KDecoration::KeepBelowOp:
+ setKeepBelow (!keepBelow ());
+ break;
+ case KDecoration::FullScreenOp:
+ if (mState & NET::FullScreen)
+ KWin::clearState (mClientId, NET::FullScreen);
+ else
+ KWin::setState (mClientId, NET::FullScreen);
+ break;
+ case KDecoration::MoveOp:
+ Decorator::rootInfo ()->moveResizeRequest (mClientId,
+ mGeometry.x () +
+ mGeometry.width () / 2,
+ mGeometry.y () +
+ mGeometry.height () / 2,
+ NET::KeyboardMove);
+ break;
+ case KDecoration::ResizeOp:
+ Decorator::rootInfo ()->moveResizeRequest (mClientId,
+ mGeometry.x () +
+ mGeometry.width () / 2,
+ mGeometry.y () +
+ mGeometry.height () / 2,
+ NET::KeyboardSize);
+ default:
+ break;
+ }
+}
+
+bool
+KWD::Window::isPreview (void) const
+{
+ return false;
+}
+
+TQRect
+KWD::Window::geometry (void) const
+{
+ TQRect rect = TQWidget::geometry ();
+
+ return TQRect (rect.x () - ROOT_OFF_X,
+ rect.y () - ROOT_OFF_Y,
+ rect.width (),
+ rect.height ());
+}
+
+TQRect
+KWD::Window::iconGeometry (void) const
+{
+ return TQRect ();
+}
+
+TQRect
+KWD::Window::clientGeometry (void)
+{
+ TQRect frame = geometry ();
+
+ return TQRect (frame.x () + mBorder.left,
+ frame.y () + mBorder.top,
+ frame.width () - mBorder.left - mBorder.right,
+ frame.height () - mBorder.top - mBorder.bottom);
+}
+
+TQRegion
+KWD::Window::unobscuredRegion (const TQRegion & r) const
+{
+ return r;
+}
+
+TQWidget *
+KWD::Window::workspaceWidget (void) const
+{
+ return const_cast <Window *> (this);
+}
+
+WId
+KWD::Window::windowId (void) const
+{
+ return mClientId;
+}
+
+void
+KWD::Window::closeWindow (void)
+{
+ Decorator::rootInfo ()->closeWindowRequest (mClientId);
+}
+
+void
+KWD::Window::maximize (MaximizeMode mode)
+{
+ KWin::setState (mClientId,
+ ((mode & MaximizeVertical) ? NET::MaxVert : 0) |
+ ((mode & MaximizeHorizontal) ? NET::MaxHoriz : 0));
+ KWin::clearState (mClientId,
+ ((mode & MaximizeVertical) ? 0 : NET::MaxVert) |
+ ((mode & MaximizeHorizontal) ? 0 : NET::MaxHoriz));
+}
+
+void
+KWD::Window::minimize (void)
+{
+ KWin::iconifyWindow (mClientId, false);
+}
+
+void
+KWD::Window::showContextHelp (void)
+{
+ if (mSupportContextHelp)
+ KWD::Decorator::sendClientMessage (mClientId, mClientId,
+ Atoms::wmProtocols,
+ Atoms::netWmContextHelp);
+}
+
+void
+KWD::Window::titlebarDblClickOperation (void)
+{
+ WindowOperation op;
+
+ op = KWD::Decorator::options ()->operationTitlebarDblClick ();
+ performWindowOperation (op);
+}
+
+void
+KWD::Window::setDesktop (int desktop)
+{
+ KWin::setOnDesktop (mClientId, desktop);
+}
+
+void
+KWD::Window::setKeepBelow (bool set)
+{
+ if (set)
+ {
+ KWin::clearState (mClientId, NET::KeepAbove);
+ KWin::setState (mClientId, NET::KeepBelow);
+ }
+ else
+ {
+ KWin::clearState (mClientId, NET::KeepBelow);
+ }
+}
+
+void
+KWD::Window::setKeepAbove (bool set)
+{
+ if (set)
+ {
+ KWin::clearState (mClientId, NET::KeepBelow);
+ KWin::setState (mClientId, NET::KeepAbove);
+ }
+ else
+ {
+ KWin::clearState (mClientId, NET::KeepAbove);
+ }
+}
+
+void
+KWD::Window::setShade (bool set)
+{
+ if (set)
+ KWin::setState (mClientId, NET::Shaded);
+ else
+ KWin::clearState (mClientId, NET::Shaded);
+
+ mDecor->shadeChange ();
+}
+
+void
+KWD::Window::titlebarMouseWheelOperation (int delta)
+{
+ Options::MouseCommand com;
+
+ com = Decorator::options()->operationTitlebarMouseWheel (delta);
+ performMouseCommand (com, 0);
+}
+
+int
+KWD::Window::currentDesktop (void) const
+{
+ return KWin::currentDesktop ();
+}
+
+TQWidget *
+KWD::Window::initialParentWidget (void) const
+{
+ return const_cast <Window *> (this);
+}
+
+TQt::WFlags
+KWD::Window::initialWFlags (void) const
+{
+ return 0;
+}
+
+void
+KWD::Window::helperShowHide (bool)
+{
+}
+
+void
+KWD::Window::grabXServer (bool)
+{
+}
+
+void
+KWD::Window::createDecoration (void)
+{
+ KDecoration *decor;
+
+ if (mDecor)
+ return;
+
+ decor = Decorator::pluginManager ()->createDecoration (this);
+ decor->init ();
+
+ mDecor = decor;
+
+ if (mType == Normal && mFrame)
+ {
+ KWD::trapXError ();
+ XSelectInput (tqt_xdisplay (), mFrame,
+ StructureNotifyMask | PropertyChangeMask |
+ ButtonPressMask | ButtonReleaseMask | PointerMotionMask |
+ EnterWindowMask | LeaveWindowMask);
+ if (KWD::popXError ())
+ return;
+ }
+
+ resizeDecoration (true);
+}
+
+static void
+fillTQRegion (Display *xdisplay,
+ Picture picture,
+ int clipX1,
+ int clipY1,
+ int clipX2,
+ int clipY2,
+ int xOff,
+ int yOff,
+ TQRegion *region)
+{
+ static XRenderColor white = { 0xffff, 0xffff, 0xffff, 0xffff };
+ TQMemArray <TQRect> rects = region->rects ();
+ TQMemArray <TQRect>::ConstIterator it;
+ int x1, y1, x2, y2;
+
+ for (it = rects.begin (); it != rects.end (); it++)
+ {
+ x1 = it->x ();
+ y1 = it->y ();
+ x2 = x1 + it->width ();
+ y2 = y1 + it->height ();
+
+ if (x1 < clipX1)
+ x1 = clipX1;
+ if (y1 < clipY1)
+ y1 = clipY1;
+ if (x2 > clipX2)
+ x2 = clipX2;
+ if (y2 > clipY2)
+ y2 = clipY2;
+
+ if (x1 < x2 && y1 < y2)
+ XRenderFillRectangle (xdisplay, PictOpSrc, picture, &white,
+ xOff + x1,
+ yOff + y1,
+ x2 - x1,
+ y2 - y1);
+ }
+}
+
+static void
+drawBorderShape (Display *xdisplay,
+ Pixmap pixmap,
+ Picture picture,
+ int width,
+ int height,
+ decor_context_t *c,
+ void *closure)
+{
+ static XRenderColor clear = { 0x0000, 0x0000, 0x0000, 0x0000 };
+ static XRenderColor white = { 0xffff, 0xffff, 0xffff, 0xffff };
+ KWD::Window *w = (KWD::Window *) closure;
+ TQRegion *shape;
+ bool uniqueHorzShade;
+ bool uniqueVertShade;
+ int xOffLeft, yOffTop, xOffRight, yOffBottom;
+ TQRect rect = w->geometry ();
+ int x1, y1, x2, y2;
+
+ (void) pixmap;
+
+ XRenderFillRectangle (xdisplay, PictOpSrc, picture, &clear,
+ 0, 0, width, height);
+
+ shape = w->getShape ();
+ w->getShapeInfo (&uniqueHorzShade, &uniqueVertShade);
+
+ xOffLeft = c->left_space - c->extents.left;
+ yOffTop = c->top_space - c->extents.top;
+
+ xOffRight = c->left_space - c->extents.left;
+ yOffBottom = c->top_space - c->extents.top;
+
+ x1 = c->left_space;
+ y1 = c->top_space;
+ x2 = width - c->right_space;
+ y2 = height - c->bottom_space;
+
+ if (shape)
+ {
+ if (uniqueHorzShade && uniqueVertShade)
+ {
+ fillTQRegion (xdisplay, picture,
+ 0, 0,
+ rect.width (), rect.height (),
+ xOffLeft, yOffTop, shape);
+ }
+ else
+ {
+ if (!uniqueHorzShade)
+ xOffRight = x2 - (rect.width () - c->extents.right);
+
+ if (!uniqueVertShade)
+ yOffBottom = y2 - (rect.height () - c->extents.bottom);
+
+ if (uniqueHorzShade)
+ {
+ fillTQRegion (xdisplay, picture,
+ 0, 0,
+ rect.width (), c->extents.top,
+ xOffLeft, yOffTop, shape);
+ fillTQRegion (xdisplay, picture,
+ 0, rect.height () - c->extents.bottom,
+ rect.width (), rect.height (),
+ xOffLeft, yOffBottom, shape);
+ }
+ else
+ {
+ fillTQRegion (xdisplay, picture,
+ 0, 0,
+ c->extents.left, c->extents.top,
+ xOffLeft, yOffTop, shape);
+ fillTQRegion (xdisplay, picture,
+ rect.width () - c->extents.right, 0,
+ rect.width (), c->extents.top,
+ xOffRight, yOffTop, shape);
+ fillTQRegion (xdisplay, picture,
+ 0, rect.height () - c->extents.bottom,
+ c->extents.left, rect.height (),
+ xOffLeft, yOffBottom, shape);
+ fillTQRegion (xdisplay, picture,
+ rect.width () - c->extents.right,
+ rect.height () - c->extents.bottom,
+ rect.width (), rect.height (),
+ xOffRight, yOffBottom, shape);
+
+ y1 -= c->extents.top;
+ y2 += c->extents.bottom;
+ }
+
+ if (uniqueVertShade)
+ {
+ fillTQRegion (xdisplay, picture,
+ 0, c->extents.top,
+ c->extents.left,
+ rect.height () - c->extents.bottom,
+ xOffLeft, yOffTop, shape);
+ fillTQRegion (xdisplay, picture,
+ rect.width () - c->extents.right, c->extents.top,
+ rect.width (),
+ rect.height () - c->extents.bottom,
+ xOffRight, yOffTop, shape);
+ }
+ else
+ {
+ x1 -= c->extents.left;
+ x2 += c->extents.right;
+ }
+ }
+ }
+ else
+ {
+ x1 -= c->extents.left;
+ x2 += c->extents.right;
+ y1 -= c->extents.top;
+ y2 += c->extents.bottom;
+ }
+
+ XRenderFillRectangle (xdisplay, PictOpSrc, picture, &white,
+ x1,
+ y1,
+ x2 - x1,
+ y2 - y1);
+}
+
+static void
+cornersFromTQRegion (TQRegion *region,
+ int width,
+ int height,
+ int left,
+ int right,
+ int top,
+ int bottom,
+ int *leftCorner,
+ int *rightCorner,
+ int *topCorner,
+ int *bottomCorner)
+{
+ TQRegion l, r, t, b;
+
+ l = TQRegion (0, top, left, height - top - bottom) - *region;
+ r = TQRegion (width - right, top, right, height - top - bottom) - *region;
+ t = TQRegion (0, 0, width, top) - *region;
+ b = TQRegion (0, height - bottom, width, bottom) - *region;
+
+ if (l.isEmpty ())
+ *leftCorner = left;
+ else
+ *leftCorner = left -
+ (l.boundingRect ().x () + l.boundingRect ().width ());
+
+ if (r.isEmpty ())
+ *rightCorner = right;
+ else
+ *rightCorner = r.boundingRect ().x () - width + right;
+
+ if (t.isEmpty ())
+ *topCorner = top;
+ else
+ *topCorner = top -
+ (t.boundingRect ().y () + t.boundingRect ().height ());
+
+ if (b.isEmpty ())
+ *bottomCorner = bottom;
+ else
+ *bottomCorner = b.boundingRect ().y () - height + bottom;
+}
+
+void
+KWD::Window::updateShadow (void)
+{
+ Display *xdisplay = tqt_xdisplay ();
+ Screen *xscreen = ScreenOfDisplay (xdisplay, tqt_xscreen ());
+ XRenderPictFormat *xformat;
+ int leftCorner, rightCorner, topCorner, bottomCorner;
+
+ if (mShadow)
+ {
+ decor_shadow_destroy (tqt_xdisplay (), mShadow);
+ mShadow = NULL;
+ }
+
+ if (mShapeSet)
+ {
+ cornersFromTQRegion (&mShape,
+ mGeometry.width () + mBorder.left + mBorder.right,
+ mGeometry.height () + mBorder.top + mBorder.bottom,
+ mBorder.left,
+ mBorder.right,
+ mBorder.top,
+ mBorder.bottom,
+ &leftCorner,
+ &rightCorner,
+ &topCorner,
+ &bottomCorner);
+ }
+ else
+ {
+ leftCorner = mBorder.left;
+ rightCorner = mBorder.right;
+ topCorner = mBorder.top;
+ bottomCorner = mBorder.bottom;
+ }
+
+ /* use default shadow if such exist */
+ if (!mUniqueHorzShape && !mUniqueVertShape)
+ {
+ mShadow = Decorator::defaultWindowShadow (&mContext, &mBorder);
+ if (mShadow)
+ decor_shadow_reference (mShadow);
+ }
+
+ if (!mShadow)
+ {
+ mShadow = decor_shadow_create (xdisplay,
+ xscreen,
+ mUniqueHorzShape ?
+ mGeometry.width () : 1,
+ mUniqueVertShape ?
+ mGeometry.height () : 1,
+ mBorder.left,
+ mBorder.right,
+ mBorder.top,
+ mBorder.bottom,
+ leftCorner,
+ rightCorner,
+ topCorner,
+ bottomCorner,
+ KWD::Decorator::shadowOptions (),
+ &mContext,
+ drawBorderShape,
+ (void *) this);
+
+ if (mType == Default)
+ KWD::Decorator::updateDefaultShadow (this);
+ }
+
+ /* create new layout */
+ if (mType == Normal || mType == Switcher)
+ decor_get_best_layout (&mContext,
+ mGeometry.width (),
+ mGeometry.height (),
+ &mLayout);
+ else
+ decor_get_default_layout (&mContext,
+ mGeometry.width (),
+ mGeometry.height (),
+ &mLayout);
+
+ if (mDecorationPicture)
+ XRenderFreePicture (tqt_xdisplay (), mDecorationPicture);
+
+ if (mTexturePicture)
+ XRenderFreePicture (tqt_xdisplay (), mTexturePicture);
+
+ if (!mTexturePixmapBuffer.isNull ())
+ mTexturePixmapBuffer.resize (0, 0);
+
+ if (!mTexturePixmap.isNull ())
+ mTexturePixmap.resize (0, 0);
+
+ mTexturePixmap = TQPixmap (mLayout.width, mLayout.height, 32);
+ mTexturePixmapBuffer = TQPixmap (mLayout.width, mLayout.height, 32);
+
+ xformat = XRenderFindStandardFormat (tqt_xdisplay (),
+ PictStandardARGB32);
+
+ mDecorationPicture =
+ XRenderCreatePicture (tqt_xdisplay (),
+ mTexturePixmap.handle (),
+ xformat, 0, NULL);
+ mTexturePicture =
+ XRenderCreatePicture (tqt_xdisplay (),
+ mTexturePixmapBuffer.handle (),
+ xformat, 0, NULL);
+
+ decor_fill_picture_extents_with_shadow (tqt_xdisplay (),
+ mShadow,
+ &mContext,
+ mTexturePicture,
+ &mLayout);
+
+ if (mPixmap)
+ mDecor->widget ()->repaint ();
+
+ mUpdateProperty = true;
+}
+
+void
+KWD::Window::setMask (const TQRegion &reg, int)
+{
+ TQRegion top, bottom, left, right;
+ bool uniqueHorzShape, uniqueVertShape;
+
+ if (mShapeSet && reg == mShape)
+ return;
+
+ mShape = reg;
+ mShapeSet = true;
+
+ if (mFrame)
+ {
+ TQRegion r;
+
+ r = reg - TQRegion (mBorder.left, mBorder.top,
+ mGeometry.width (), mGeometry.height ());
+
+ KWD::trapXError ();
+ XShapeCombineRegion (tqt_xdisplay (),
+ mFrame,
+ ShapeInput,
+ 0,
+ 0,
+ r.handle (),
+ ShapeSet);
+ KWD::popXError ();
+ }
+
+ top = TQRegion (mBorder.left, 0,
+ mGeometry.width (), mBorder.top) - reg;
+ bottom = TQRegion (mBorder.left, mGeometry.height () + mBorder.top,
+ mGeometry.width (), mBorder.bottom) - reg;
+ left = TQRegion (0, mBorder.top, mBorder.left,
+ mGeometry.height ()) - reg;
+ right = TQRegion (mBorder.left + mGeometry.width (), mBorder.top,
+ mBorder.right, mGeometry.height ()) - reg;
+
+ uniqueHorzShape = !top.isEmpty () || !bottom.isEmpty ();
+ uniqueVertShape = !left.isEmpty () || !right.isEmpty ();
+
+ if (uniqueHorzShape || mUniqueHorzShape ||
+ uniqueVertShape || mUniqueVertShape)
+ {
+ mUniqueHorzShape = uniqueHorzShape;
+ mUniqueVertShape = uniqueVertShape;
+
+ if (mPixmap)
+ updateShadow ();
+ }
+}
+
+bool
+KWD::Window::resizeDecoration (bool force)
+{
+ int w, h;
+
+ mDecor->borders (mBorder.left, mBorder.right, mBorder.top, mBorder.bottom);
+
+ w = mGeometry.width () + mBorder.left + mBorder.right;
+ h = mGeometry.height () + mBorder.top + mBorder.bottom;
+
+ if (!force)
+ {
+ if (w == width () && h == height ())
+ return FALSE;
+ }
+
+ /* reset shape */
+ mShapeSet = false;
+ mUniqueHorzShape = false;
+ mUniqueVertShape = false;
+
+ if (mType != Normal && mType != Switcher)
+ {
+ Display *xdisplay = tqt_xdisplay ();
+ Screen *xscreen = ScreenOfDisplay (xdisplay, tqt_xscreen ());
+ decor_shadow_t *tmpShadow;
+ decor_context_t c;
+
+ /* XXX: we have to create a temporary shadow to get the client
+ geometry. libdecoration should be fixed so it's able to just
+ fill out a context struct and not necessarily generate a
+ shadow for this purpose. */
+ tmpShadow = decor_shadow_create (xdisplay,
+ xscreen,
+ 1, 1,
+ mBorder.left,
+ mBorder.right,
+ mBorder.top,
+ mBorder.bottom,
+ mBorder.left,
+ mBorder.right,
+ mBorder.top,
+ mBorder.bottom,
+ KWD::Decorator::shadowOptions (),
+ &c,
+ decor_draw_simple,
+ (void *) 0);
+
+ decor_shadow_destroy (xdisplay, tmpShadow);
+
+ w = c.left_corner_space + 1 + c.right_corner_space;
+
+ /* most styles render something useful at least 30 px width */
+ if (w < 30)
+ w = 30;
+
+ mGeometry = TQRect (50, 50, w,
+ c.top_corner_space + 1 + c.bottom_corner_space);
+ }
+
+ w = mGeometry.width () + mBorder.left + mBorder.right;
+ h = mGeometry.height () + mBorder.top + mBorder.bottom;
+
+ if (mPixmap)
+ {
+ XFreePixmap (tqt_xdisplay (), mPixmap);
+ mPixmap = None;
+ }
+
+ if (mPicture)
+ {
+ XRenderFreePicture (tqt_xdisplay (), mPicture);
+ mPicture = 0;
+ }
+
+ if (w != width() || h != height())
+ {
+ mPendingConfigure = 1;
+ }
+
+ setGeometry (TQRect (mGeometry.x () + ROOT_OFF_X - mBorder.left,
+ mGeometry.y () + ROOT_OFF_Y - mBorder.top,
+ w, h));
+
+ mSize = TQSize (w, h);
+
+ if (!mMapped)
+ {
+ mPendingMap = 1;
+
+ XReparentWindow (tqt_xdisplay (), winId (), mParentId, 0, 0);
+
+ show ();
+
+ mMapped = true;
+
+ if (mDamageId != winId ())
+ {
+ mDamageId = winId ();
+ XDamageCreate (tqt_xdisplay (), mDamageId,
+ XDamageReportRawRectangles);
+ }
+ }
+
+ mDecor->resize (TQSize (w, h));
+ mDecor->widget ()->show ();
+ mDecor->widget ()->repaint ();
+
+ return TRUE;
+}
+
+void
+KWD::Window::rebindPixmap (void)
+{
+ XRenderPictFormat *xformat;
+ TQPaintEvent *e;
+
+ if (mPicture)
+ XRenderFreePicture (tqt_xdisplay (), mPicture);
+
+ if (mPixmap)
+ XFreePixmap (tqt_xdisplay (), mPixmap);
+
+ mPixmap = XCompositeNameWindowPixmap (tqt_xdisplay (), winId ());
+
+ xformat = XRenderFindVisualFormat (tqt_xdisplay (),
+ (Visual *) x11Visual ());
+
+ mPicture = XRenderCreatePicture (tqt_xdisplay (), mPixmap,
+ xformat, 0, NULL);
+
+ updateShadow ();
+
+ e = new TQPaintEvent (mDecor->widget ()->rect (), false);
+ TQApplication::postEvent (mDecor->widget (), e);
+}
+
+bool
+KWD::Window::handleMap (void)
+{
+ if (!mPendingMap)
+ return FALSE;
+
+ mPendingMap = 0;
+ if (mPendingConfigure)
+ return FALSE;
+
+ rebindPixmap ();
+
+ return TRUE;
+}
+
+bool
+KWD::Window::handleConfigure (TQSize size)
+{
+ if (!mPendingConfigure)
+ return FALSE;
+
+ if (size != mSize)
+ return FALSE;
+
+ mPendingConfigure = 0;
+ if (mPendingConfigure || mPendingMap)
+ return FALSE;
+
+ rebindPixmap ();
+
+ return TRUE;
+}
+
+void
+KWD::Window::updateBlurProperty (int topOffset,
+ int bottomOffset,
+ int leftOffset,
+ int rightOffset)
+{
+ Atom atom = Atoms::compizWindowBlurDecor;
+ TQRegion topTQRegion, bottomTQRegion, leftTQRegion, rightTQRegion;
+ Region topRegion = NULL;
+ Region bottomRegion = NULL;
+ Region leftRegion = NULL;
+ Region rightRegion = NULL;
+ int size = 0;
+ int w, h;
+
+ w = mGeometry.width () + mContext.extents.left + mContext.extents.right;
+ h = mGeometry.height () + mContext.extents.top + mContext.extents.bottom;
+
+ if (blurType != BLUR_TYPE_NONE)
+ {
+ TQRegion r, shape = TQRegion (0, 0, w, h);
+
+ if (mShapeSet)
+ shape = mShape;
+
+ r = TQRegion (0, 0, w, mContext.extents.top);
+ topTQRegion = r.intersect (shape);
+ if (!topTQRegion.isEmpty ())
+ {
+ topTQRegion.translate (-mContext.extents.left,
+ -mContext.extents.top);
+ topRegion = topTQRegion.handle ();
+ }
+
+ if (blurType == BLUR_TYPE_ALL)
+ {
+ r = TQRegion (0, h - mContext.extents.bottom,
+ w, mContext.extents.bottom);
+ bottomTQRegion = r.intersect (shape);
+ if (!bottomTQRegion.isEmpty ())
+ {
+ bottomTQRegion.translate (-mContext.extents.left,
+ -(h - mContext.extents.bottom));
+ bottomRegion = bottomTQRegion.handle ();
+ }
+
+ r = TQRegion (0, mContext.extents.top,
+ mContext.extents.left, mGeometry.height ());
+ leftTQRegion = r.intersect (shape);
+ if (!leftTQRegion.isEmpty ())
+ {
+ leftTQRegion.translate (-mContext.extents.left,
+ -mContext.extents.top);
+ leftRegion = leftTQRegion.handle ();
+ }
+
+ r = TQRegion (w - mContext.extents.right, mContext.extents.top,
+ mContext.extents.right, mGeometry.height ());
+ rightTQRegion = r.intersect (shape);
+ if (!rightTQRegion.isEmpty ())
+ {
+ rightTQRegion.translate (-(w - mContext.extents.right),
+ -mContext.extents.top);
+ rightRegion = rightTQRegion.handle ();
+ }
+ }
+ }
+
+ if (topRegion)
+ size += topRegion->numRects;
+ if (bottomRegion)
+ size += bottomRegion->numRects;
+ if (leftRegion)
+ size += leftRegion->numRects;
+ if (rightRegion)
+ size += rightRegion->numRects;
+
+ if (size)
+ {
+ long data[size * 6 + 2];
+
+ decor_region_to_blur_property (data, 4, 0,
+ mGeometry.width (),
+ mGeometry.height (),
+ topRegion, topOffset,
+ bottomRegion, bottomOffset,
+ leftRegion, leftOffset,
+ rightRegion, rightOffset);
+
+ KWD::trapXError ();
+ XChangeProperty (tqt_xdisplay (), mClientId, atom,
+ XA_INTEGER,
+ 32, PropModeReplace, (unsigned char *) data,
+ 2 + size * 6);
+ KWD::popXError ();
+ }
+ else
+ {
+ KWD::trapXError ();
+ XDeleteProperty (tqt_xdisplay (), mClientId, atom);
+ KWD::popXError ();
+ }
+}
+
+void
+KWD::Window::updateProperty (void)
+{
+ Atom atom = Atoms::netWindowDecor;
+ decor_extents_t maxExtents;
+ long data[256];
+ decor_quad_t quads[N_QUADS_MAX];
+ int nQuad;
+ int lh, rh;
+ int w;
+ int minWidth;
+ unsigned int saveState;
+
+ if (mType == Default)
+ atom = Atoms::netWindowDecorNormal;
+ else if (mType == DefaultActive)
+ atom = Atoms::netWindowDecorActive;
+
+ saveState = mState;
+ mState = NET::MaxVert | NET::MaxHoriz;
+ mDecor->borders (maxExtents.left, maxExtents.right,
+ maxExtents.top, maxExtents.bottom);
+ mState = saveState;
+ mDecor->borders (mBorder.left, mBorder.right, mBorder.top, mBorder.bottom);
+
+ if (mLayout.rotation)
+ lh = mLayout.left.x2 - mLayout.left.x1;
+ else
+ lh = mLayout.left.y2 - mLayout.left.y1;
+
+ if (mLayout.rotation)
+ rh = mLayout.right.x2 - mLayout.right.x1;
+ else
+ rh = mLayout.right.y2 - mLayout.right.y1;
+
+ w = mLayout.top.x2 - mLayout.top.x1 - mContext.left_space -
+ mContext.right_space;
+
+ if (mType == Normal || mType == Switcher)
+ {
+ int topXOffset = w / 2;
+ TQWidget *widget = mDecor->widget ();
+ int x;
+
+ x = w - mContext.left_space - mContext.left_corner_space;
+ if (x > topXOffset)
+ topXOffset = x;
+
+ if (widget)
+ {
+ const TQObjectList *children = widget->children ();
+
+ if (children)
+ {
+ TQWidget *child;
+
+ for (TQObjectListIt it(*children); it.current (); ++it)
+ {
+ if (!it.current ()->isWidgetType ())
+ continue;
+
+ child = static_cast <TQWidget *> (it.current ());
+
+ x = child->x () - mBorder.left - 2;
+ if (x > w / 2 && x < topXOffset)
+ topXOffset = x;
+ }
+ }
+ }
+
+ nQuad = decor_set_lXrXtXbX_window_quads (quads,
+ &mContext,
+ &mLayout,
+ lh / 2,
+ rh / 2,
+ topXOffset,
+ w / 2);
+
+ updateBlurProperty (topXOffset, w / 2, lh / 2, rh / 2);
+
+ minWidth = mContext.left_corner_space + 1 + mContext.right_corner_space;
+ }
+ else
+ {
+ nQuad = decor_set_lSrStSbS_window_quads (quads, &mContext, &mLayout);
+
+ minWidth = 1;
+ }
+
+ decor_quads_to_property (data, mTexturePixmap.handle (),
+ &mBorder, &maxExtents,
+ minWidth, 0,
+ quads, nQuad);
+
+ KWD::trapXError ();
+ XChangeProperty (tqt_xdisplay (), mClientId, atom,
+ XA_INTEGER,
+ 32, PropModeReplace, (unsigned char *) data,
+ BASE_PROP_SIZE + QUAD_PROP_SIZE * nQuad);
+ KWD::popXError ();
+
+ mUpdateProperty = false;
+}
+
+void
+KWD::Window::handleActiveChange (void)
+{
+ mDecor->activeChange ();
+ resizeDecoration ();
+}
+
+void
+KWD::Window::updateFrame (WId frame)
+{
+ mFrame = frame;
+
+ KWD::trapXError ();
+ XSelectInput (tqt_xdisplay (), mFrame,
+ StructureNotifyMask | PropertyChangeMask |
+ ButtonPressMask | ButtonReleaseMask | PointerMotionMask |
+ EnterWindowMask | LeaveWindowMask);
+ KWD::popXError ();
+}
+
+void
+KWD::Window::updateSelected (WId selectedId)
+{
+ mSelectedId = selectedId;
+
+ updateName ();
+}
+
+void
+KWD::Window::updateWindowGeometry (void)
+{
+ KWin::WindowInfo wInfo = KWin::windowInfo (mClientId, NET::WMGeometry);
+ TQRect geometry = wInfo.geometry ();
+
+ if (mGeometry.width () != geometry.width () ||
+ mGeometry.height () != geometry.height ())
+ {
+ mGeometry = geometry;
+
+ if (resizeDecoration ())
+ return;
+ }
+ else
+ {
+ mGeometry = geometry;
+ }
+
+ move (mGeometry.x () + ROOT_OFF_X - mBorder.left,
+ mGeometry.y () + ROOT_OFF_Y - mBorder.top);
+}
+
+void
+KWD::Window::reloadDecoration (void)
+{
+ delete mDecor;
+ mDecor = 0;
+
+ mMapped = false;
+ mShapeSet = false;
+
+ if (mShadow)
+ {
+ decor_shadow_destroy (tqt_xdisplay (), mShadow);
+ mShadow = NULL;
+ }
+
+ createDecoration ();
+}
+
+Cursor
+KWD::Window::positionToCursor (TQPoint pos)
+{
+ switch (mDecor->mousePosition (pos)) {
+ case PositionCenter:
+ return cursors[1][1].cursor;
+ case PositionLeft:
+ return cursors[1][0].cursor;
+ case PositionRight:
+ return cursors[1][2].cursor;
+ case PositionTop:
+ return cursors[0][1].cursor;
+ case PositionBottom:
+ return cursors[2][1].cursor;
+ case PositionTopLeft:
+ return cursors[0][0].cursor;
+ case PositionTopRight:
+ return cursors[0][2].cursor;
+ case PositionBottomLeft:
+ return cursors[2][0].cursor;
+ case PositionBottomRight:
+ return cursors[2][2].cursor;
+ default:
+ break;
+ }
+
+ return cursors[1][1].cursor;
+}
+
+void
+KWD::Window::updateCursor (TQPoint pos)
+{
+ KWD::trapXError ();
+ XDefineCursor (tqt_xdisplay (), mFrame, positionToCursor (pos));
+ KWD::popXError ();
+}
+
+void
+KWD::Window::getWindowProtocols (void)
+{
+ Atom *p;
+ int n;
+ int status;
+
+ mSupportTakeFocus = false;
+ mSupportContextHelp = false;
+
+ KWD::trapXError ();
+ status = XGetWMProtocols (tqt_xdisplay (), mClientId, &p, &n);
+ if (KWD::popXError ())
+ return;
+
+ if (status)
+ {
+ int i;
+
+ for (i = 0; i < n; i++)
+ {
+ if (p[i] == Atoms::wmTakeFocus)
+ mSupportTakeFocus = true;
+ else if (p[i] == Atoms::netWmContextHelp)
+ mSupportContextHelp = true;
+ }
+
+ if (n > 0)
+ XFree (p);
+ }
+}
+
+void
+KWD::Window::handlePopupActivated (int id)
+{
+ WindowOperation op = static_cast <WindowOperation> (id);
+
+ performWindowOperation (op);
+}
+
+void
+KWD::Window::handleDesktopPopupActivated (int id)
+{
+ if (id)
+ setDesktop (id);
+ else
+ KWin::setOnAllDesktops (mClientId, true);
+}
+
+void
+KWD::Window::handleViewportPopupActivated (int id)
+{
+ KWinModule *m_twin;
+ int m_curDesk;
+ m_twin = new KWinModule(this);
+ m_curDesk = m_twin->currentDesktop();
+ TQSize s(m_twin->numberOfViewports(m_twin->currentDesktop()));
+ TQPoint p(m_twin->currentViewport(m_twin->currentDesktop()));
+ int CurrentViewportNumber = p.x(); // FIXME: Handle vertical viewports
+
+ int viewportMove;
+
+ if (id) {
+ viewportMove = ((id - CurrentViewportNumber) * TQApplication::desktop()->width());
+
+ XWindowAttributes attr;
+ XGetWindowAttributes(tqt_xdisplay(), mFrame, &attr);
+ XMoveWindow(tqt_xdisplay(), mClientId, attr.x + viewportMove, attr.y);
+ }
+}
+
+void
+KWD::Window::handlePopupAboutToShow (void)
+{
+ int numberOfDesktops;
+ int numberOfViewports;
+
+ numberOfDesktops = KWin::numberOfDesktops();
+ if (numberOfDesktops > 1)
+ {
+ NETRootInfo *rootInfo = Decorator::rootInfo ();
+ TQString name;
+ int id, i;
+ int winDesktop = desktop ();
+
+ mDesktopMenu->clear ();
+
+ id = mDesktopMenu->insertItem (i18n ("&All Desktops"), 0);
+
+ mDesktopMenu->setItemChecked (id, (winDesktop == NET::OnAllDesktops));
+ mDesktopMenu->insertSeparator ();
+
+ for (i = 1; i <= numberOfDesktops; i++)
+ {
+ TQString name;
+
+ name =
+ TQString ("&%1 ").arg (i) +
+ TQString (rootInfo->desktopName (i)).replace ('&', "&&");
+
+ id = mDesktopMenu->insertItem (name, i);
+ mDesktopMenu->setItemChecked (id, (winDesktop == i));
+ }
+
+ mPopup->setItemVisible (Options::NoOp, true);
+ }
+ else
+ {
+ mPopup->setItemVisible (Options::NoOp, false);
+ }
+
+ KWinModule *m_twin;
+ int m_curDesk;
+ m_twin = new KWinModule(this);
+ m_curDesk = m_twin->currentDesktop();
+ TQSize s(m_twin->numberOfViewports(m_twin->currentDesktop()));
+ numberOfViewports = s.width() * s.height();
+
+ if (numberOfViewports > 1)
+ {
+ NETRootInfo *rootInfo = Decorator::rootInfo ();
+ TQString name;
+ int id, i;
+ int winViewport = m_twin->currentViewport(m_twin->currentDesktop()).x(); // FIXME: vertical viewports
+
+ mViewportMenu->clear ();
+
+// id = mViewportMenu->insertItem (i18n ("&All Viewports"), 0);
+//
+// mViewportMenu->setItemChecked (id, (winViewport == NET::OnAllDesktops));
+// mViewportMenu->insertSeparator ();
+
+ for (i = 1; i <= numberOfViewports; i++)
+ {
+ TQString name;
+
+ //name = TQString ("&%1 ").arg (i) + TQString (rootInfo->desktopName (i)).replace ('&', "&&");
+ name = TQString ("&Viewport %1").arg (i);
+
+ id = mViewportMenu->insertItem (name, i);
+ mViewportMenu->setItemChecked (id, (winViewport == i));
+ }
+
+ mPopup->setItemVisible (viewportMenuID, true);
+ }
+ else
+ {
+ mPopup->setItemVisible (viewportMenuID, false);
+ }
+
+ mPopup->setItemEnabled (Options::ResizeOp, isResizable ());
+ mPopup->setItemEnabled (Options::MoveOp, isMovable ());
+
+ mPopup->setItemEnabled (Options::MaximizeOp, isMaximizable ());
+ mPopup->setItemChecked (Options::MaximizeOp,
+ maximizeMode () == MaximizeFull);
+
+ mPopup->setItemChecked (Options::ShadeOp, isShade ());
+ mPopup->setItemEnabled (Options::ShadeOp, isShadeable ());
+
+ mAdvancedMenu->setItemChecked (Options::KeepAboveOp, keepAbove ());
+ mAdvancedMenu->setItemChecked (Options::KeepBelowOp, keepBelow ());
+ mAdvancedMenu->setItemChecked (Options::FullScreenOp,
+ mState & NET::FullScreen);
+
+ mPopup->setItemEnabled (Options::MinimizeOp, isMinimizable ());
+ mPopup->setItemEnabled (Options::CloseOp, isCloseable ());
+}
+
+void
+KWD::Window::updateState (void)
+{
+ KWin::WindowInfo wInfo = KWin::windowInfo (mClientId, NET::WMState, 0);
+ unsigned long newState = wInfo.state ();
+ unsigned long stateChange = mState ^ newState;
+
+ mState = newState;
+
+ if (stateChange & NET::Max)
+ {
+ mDecor->maximizeChange ();
+ resizeDecoration (false);
+ }
+
+ if (stateChange & NET::KeepAbove && !(mState & NET::KeepAbove))
+ mDecor->emitKeepAboveChanged (mState & NET::KeepAbove);
+ if (stateChange & NET::KeepBelow && !(mState & NET::KeepBelow))
+ mDecor->emitKeepBelowChanged (mState & NET::KeepBelow);
+ if (stateChange & NET::KeepAbove && mState & NET::KeepAbove)
+ mDecor->emitKeepAboveChanged (mState & NET::KeepAbove);
+ if (stateChange & NET::KeepBelow && mState & NET::KeepBelow)
+ mDecor->emitKeepBelowChanged (mState & NET::KeepBelow);
+ if (stateChange & NET::Shaded)
+ mDecor->shadeChange ();
+ if (stateChange & NET::Sticky)
+ mDecor->desktopChange ();
+}
+
+void
+KWD::Window::updateName (void)
+{
+ KWin::WindowInfo wInfo;
+ WId window;
+
+ if (mType == Switcher)
+ {
+ if (!mSelectedId)
+ return;
+ window = mSelectedId;
+ }
+ else
+ window = mClientId;
+
+ wInfo = KWin::windowInfo (window, NET::WMVisibleName, 0);
+
+ mName = wInfo.visibleName ();
+
+ mDecor->captionChange ();
+}
+
+void
+KWD::Window::updateIcons (void)
+{
+ mIcons = TQIconSet (KWin::icon (mClientId, 16, 16, TRUE),
+ KWin::icon (mClientId, 32, 32, TRUE));
+ mDecor->iconChange ();
+}
+
+NET::Direction
+KWD::Window::positionToDirection (int pos)
+{
+ switch (pos) {
+ case PositionLeft:
+ return NET::Left;
+ case PositionRight:
+ return NET::Right;
+ case PositionTop:
+ return NET::Top;
+ case PositionBottom:
+ return NET::Bottom;
+ case PositionTopLeft:
+ return NET::TopLeft;
+ case PositionTopRight:
+ return NET::TopRight;
+ case PositionBottomLeft:
+ return NET::BottomLeft;
+ case PositionBottomRight:
+ return NET::BottomRight;
+ default:
+ break;
+ }
+
+ return NET::Move;
+}
+
+void
+KWD::Window::moveWindow (TQMouseEvent *qme)
+{
+ NET::Direction direction;
+
+ direction = positionToDirection (mDecor->mousePosition (qme->pos ()));
+
+ XUngrabPointer (tqt_xdisplay (), CurrentTime);
+ XUngrabKeyboard (tqt_xdisplay (), CurrentTime);
+
+ Decorator::rootInfo ()->restackRequest (mClientId, None, Above);
+ Decorator::rootInfo ()->moveResizeRequest (mClientId,
+ qme->globalX (),
+ qme->globalY (),
+ direction);
+}
+
+#define OPACITY_STEP (0xffff / 10)
+
+void
+KWD::Window::performMouseCommand (Options::MouseCommand command,
+ TQMouseEvent *qme)
+{
+ switch (command) {
+ case Options::MouseRaise:
+ KWin::raiseWindow (mClientId);
+ break;
+ case Options::MouseLower:
+ KWin::lowerWindow (mClientId);
+ break;
+ case Options::MouseShade :
+ setShade (!isShade ());
+ break;
+ case Options::MouseSetShade:
+ setShade (true);
+ break;
+ case Options::MouseUnsetShade:
+ setShade (false);
+ break;
+ case Options::MouseOperationsMenu:
+ {
+ TQPoint mp (0, 0);
+
+ if (qme)
+ mp = TQPoint (qme->globalX (), qme->globalY ());
+
+ showWindowMenu (mp);
+ } break;
+ case Options::MouseMaximize:
+ maximize (KDecoration::MaximizeFull);
+ break;
+ case Options::MouseRestore:
+ maximize (KDecoration::MaximizeRestore);
+ break;
+ case Options::MouseMinimize:
+ minimize ();
+ break;
+ case Options::MouseAbove:
+ if (keepBelow ())
+ setKeepBelow (false);
+ else
+ setKeepAbove (true);
+ break;
+ case Options::MouseBelow:
+ if (keepAbove ())
+ setKeepAbove (false);
+ else
+ setKeepBelow (true);
+ break;
+ case Options::MousePreviousDesktop:
+ break;
+ case Options::MouseNextDesktop:
+ break;
+ case Options::MouseOpacityMore:
+ {
+ int opacity = mOpacity;
+
+ if (opacity < 0xffff)
+ {
+ opacity += OPACITY_STEP;
+ if (opacity > 0xffff)
+ opacity = 0xffff;
+
+ Decorator::sendClientMessage (tqt_xrootwin (),
+ mClientId,
+ Atoms::netWmWindowOpacity,
+ (opacity << 16) | opacity);
+ }
+ } break;
+ case Options::MouseOpacityLess:
+ {
+ int opacity = mOpacity;
+
+ if (opacity > OPACITY_STEP)
+ {
+ opacity -= OPACITY_STEP;
+ if (opacity < OPACITY_STEP)
+ opacity = OPACITY_STEP;
+
+ Decorator::sendClientMessage (tqt_xrootwin (),
+ mClientId,
+ Atoms::netWmWindowOpacity,
+ (opacity << 16) | opacity);
+ }
+ } break;
+ case Options::MouseActivateRaiseAndMove:
+ case Options::MouseActivateRaiseAndUnrestrictedMove:
+ case Options::MouseMove:
+ case Options::MouseUnrestrictedMove:
+ case Options::MouseResize:
+ case Options::MouseUnrestrictedResize:
+ if (qme)
+ moveWindow (qme);
+ case Options::MouseNothing:
+ default:
+ break;
+ }
+}
+
+void
+KWD::Window::processDamage (void)
+{
+ TQRegion r1, r2;
+ int xOff, yOff, w;
+ double alpha;
+ int shade_alpha;
+
+ if (isActive ())
+ {
+ alpha = activeDecorationOpacity;
+ shade_alpha = activeDecorationOpacityShade;
+ }
+ else
+ {
+ alpha = decorationOpacity;
+ shade_alpha = decorationOpacityShade;
+ }
+
+ if (!mPixmap)
+ return;
+
+ if (mDamage.isEmpty ())
+ return;
+
+ if (mShapeSet)
+ mDamage = mShape.intersect (mDamage);
+
+ w = mGeometry.width () + mContext.extents.left + mContext.extents.right;
+
+ if (mType == Switcher)
+ shade_alpha = 0;
+
+ xOff = 0;
+ yOff = 0;
+
+ r1 = TQRegion (xOff, yOff, w, mContext.extents.top);
+ r2 = r1.intersect (mDamage);
+
+ if (!r2.isEmpty ())
+ {
+ r2.translate (-xOff, -yOff);
+
+ decor_blend_border_picture (tqt_xdisplay (),
+ &mContext,
+ mPicture,
+ xOff, xOff,
+ mTexturePicture,
+ &mLayout,
+ BORDER_TOP,
+ r2.handle (),
+ (unsigned short) (alpha * 0xffff),
+ shade_alpha,
+ TRUE);
+ }
+
+ xOff = 0;
+ yOff = mContext.extents.top + mGeometry.height ();
+
+ r1 = TQRegion (xOff, yOff, w, mContext.extents.bottom);
+ r2 = r1.intersect (mDamage);
+
+ if (!r2.isEmpty ())
+ {
+ r2.translate (-xOff, -yOff);
+
+ decor_blend_border_picture (tqt_xdisplay (),
+ &mContext,
+ mPicture,
+ xOff, yOff,
+ mTexturePicture,
+ &mLayout,
+ BORDER_BOTTOM,
+ r2.handle (),
+ (unsigned short) (alpha * 0xffff),
+ shade_alpha,
+ TRUE);
+ }
+
+ xOff = 0;
+ yOff = mContext.extents.top;
+
+ r1 = TQRegion (xOff, yOff, mContext.extents.left, mGeometry.height ());
+ r2 = r1.intersect (mDamage);
+
+ if (!r2.isEmpty ())
+ {
+ r2.translate (-xOff, -yOff);
+
+ decor_blend_border_picture (tqt_xdisplay (),
+ &mContext,
+ mPicture,
+ xOff, yOff,
+ mTexturePicture,
+ &mLayout,
+ BORDER_LEFT,
+ r2.handle (),
+ (unsigned short) (alpha * 0xffff),
+ shade_alpha,
+ TRUE);
+ }
+
+ xOff = mContext.extents.left + mGeometry.width ();
+ yOff = mContext.extents.top;
+
+ r1 = TQRegion (xOff, yOff, mContext.extents.right, mGeometry.height ());
+ r2 = r1.intersect (mDamage);
+
+ if (!r2.isEmpty ())
+ {
+ r2.translate (-xOff, -yOff);
+
+ decor_blend_border_picture (tqt_xdisplay (),
+ &mContext,
+ mPicture,
+ xOff, yOff,
+ mTexturePicture,
+ &mLayout,
+ BORDER_RIGHT,
+ r2.handle (),
+ (unsigned short) (alpha * 0xffff),
+ shade_alpha,
+ TRUE);
+ }
+
+ mDamage = TQRegion ();
+
+ XRenderComposite (tqt_xdisplay (),
+ PictOpSrc,
+ mTexturePicture,
+ None,
+ mDecorationPicture,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ mTexturePixmap.width (),
+ mTexturePixmap.height ());
+
+ if (mUpdateProperty)
+ {
+ if (mType == Switcher)
+ {
+ TQPainter p (this);
+ unsigned long pixel;
+ TQColor bg = p.backgroundColor ();
+
+ pixel = (((int) (alpha * 0xff) << 24) |
+ ((int) (alpha * bg.red ()) << 16) |
+ ((int) (alpha * bg.green ()) << 8) |
+ ((int) (alpha * bg.blue ()) << 0));
+
+ KWD::trapXError ();
+ XSetWindowBackground (tqt_xdisplay (), mClientId, pixel);
+ XClearWindow (tqt_xdisplay (), mClientId);
+ KWD::popXError ();
+ }
+
+ updateProperty ();
+ }
+}
+
+void
+KWD::Window::handleProcessKillerExited (void)
+{
+ if (mProcessKiller)
+ {
+ delete mProcessKiller;
+ mProcessKiller = NULL;
+ }
+}
+
+void
+KWD::Window::showKillProcessDialog (Time timestamp)
+{
+ KWin::WindowInfo kWinInfo =
+ KWin::windowInfo (mClientId, 0,
+ NET::WM2WindowClass | NET::WM2ClientMachine);
+ NETWinInfo wInfo = NETWinInfo (tqt_xdisplay(), mClientId,
+ tqt_xrootwin (), NET::WMPid);
+ TQCString clientMachine, resourceClass;
+ pid_t pid;
+ char buf[257];
+
+ if (mProcessKiller)
+ return;
+
+ clientMachine = kWinInfo.clientMachine ();
+ resourceClass = kWinInfo.windowClassClass ();
+ pid = wInfo.pid ();
+
+ if (gethostname (buf, sizeof (buf) - 1) == 0)
+ {
+ if (strcmp (buf, clientMachine) == 0)
+ clientMachine = "localhost";
+ }
+
+ mProcessKiller = new TDEProcess (this);
+
+ *mProcessKiller << TDEStandardDirs::findExe ("twin_killer_helper") <<
+ "--pid" << TQCString ().setNum (pid) <<
+ "--hostname" << clientMachine <<
+ "--windowname" << mName.utf8 () <<
+ "--applicationname" << resourceClass <<
+ "--wid" << TQCString ().setNum (mClientId) <<
+ "--timestamp" << TQCString ().setNum (timestamp);
+
+ connect (mProcessKiller, SIGNAL (processExited (TDEProcess *)),
+ SLOT (handleProcessKillerExited ()));
+
+ if (!mProcessKiller->start (TDEProcess::NotifyOnExit))
+ {
+ delete mProcessKiller;
+ mProcessKiller = NULL;
+ }
+}
+
+void
+KWD::Window::hideKillProcessDialog (void)
+{
+ handleProcessKillerExited ();
+}
Index: b/tde/window-decorator/window.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ b/tde/window-decorator/window.h 2013-08-04 11:50:19.000000000 +0200
@@ -0,0 +1,245 @@
+/*
+ * Copyright © 2006 Novell, Inc.
+ * Copyright © 2006 Dennis Kasprzyk <onestone@beryl-project.org>
+ * Copyright © 2006 Volker Krause <vkrause@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * Author: David Reveman <davidr@novell.com>
+ */
+
+#ifndef _WINDOW_H
+#define _WINDOW_H
+
+#include <kdecoration_p.h>
+
+#include <ntqpixmap.h>
+#include <ntqwidget.h>
+
+#include <decoration.h>
+
+#include <X11/extensions/Xdamage.h>
+
+#include "utils.h"
+#include "options.h"
+
+class TDEProcess;
+class KDecoration;
+class TQPopupMenu;
+
+namespace KWD
+{
+class Window:public TQWidget, public KDecorationBridge {
+ TQ_OBJECT public:
+
+ enum Type
+ {
+ Normal,
+ Switcher,
+ Default,
+ DefaultActive
+ };
+
+ public:
+ Window (WId parentId, WId clientId, WId frame, Type type,
+ int x = 0, int y = 0, int w = 1, int h = 1);
+ ~Window (void);
+
+ virtual bool isActive (void) const;
+ virtual bool isCloseable (void) const;
+ virtual bool isMaximizable (void) const;
+ virtual MaximizeMode maximizeMode (void) const;
+ virtual bool isMinimizable (void) const;
+ virtual bool providesContextHelp (void) const;
+ virtual int desktop (void) const;
+ virtual bool isModal (void) const;
+ virtual bool isShadeable (void) const;
+ virtual bool isShade (void) const;
+ virtual bool isSetShade (void) const;
+ virtual bool keepAbove (void) const;
+ virtual bool keepBelow (void) const;
+ virtual bool isMovable (void) const;
+ virtual bool isResizable (void) const;
+ virtual NET::WindowType
+ windowType (unsigned long supported_types) const;
+ virtual TQIconSet icon (void) const;
+ virtual TQString caption (void) const;
+ virtual void processMousePressEvent (TQMouseEvent *);
+ virtual void showWindowMenu (const TQRect &);
+ virtual void showWindowMenu (TQPoint);
+ virtual void performWindowOperation (WindowOperation);
+ virtual void setMask (const TQRegion &, int);
+ virtual bool isPreview (void) const;
+ virtual TQRect geometry (void) const;
+ virtual TQRect iconGeometry (void) const;
+ virtual TQRegion unobscuredRegion (const TQRegion & r) const;
+ virtual TQWidget *workspaceWidget (void) const;
+ virtual WId windowId (void) const;
+ virtual void closeWindow (void);
+ virtual void maximize (MaximizeMode mode);
+ virtual void minimize (void);
+ virtual void showContextHelp (void);
+ virtual void setDesktop (int desktop);
+ virtual void titlebarDblClickOperation (void);
+ virtual void titlebarMouseWheelOperation (int delta);
+ virtual void setShade (bool set);
+ virtual void setKeepAbove (bool);
+ virtual void setKeepBelow (bool);
+ virtual int currentDesktop (void) const;
+ virtual TQWidget *initialParentWidget (void) const;
+ virtual TQt::WFlags initialWFlags (void) const;
+ virtual void helperShowHide (bool);
+ virtual void grabXServer (bool grab);
+
+ void handleActiveChange (void);
+ void updateFrame (WId frame);
+ void updateWindowGeometry (void);
+ void updateCursor (TQPoint pos);
+ void updateSelected (WId selected);
+ WId frameId (void) const
+ {
+ return mFrame;
+ }
+ KDecoration *decoration (void) const
+ {
+ return mDecor;
+ }
+ TQWidget *activeChild (void) const
+ {
+ return mActiveChild;
+ }
+ void setActiveChild (TQWidget * child)
+ {
+ mActiveChild = child;
+ }
+ TQRegion *getShape (void)
+ {
+ if (mShapeSet)
+ return &mShape;
+
+ return NULL;
+ }
+ void getShapeInfo (bool *horz, bool *vert)
+ {
+ *horz = mUniqueHorzShape;
+ *vert = mUniqueVertShape;
+ }
+ void moveWindow (TQMouseEvent *qme);
+ void reloadDecoration (void);
+ void updateState (void);
+ void updateName (void);
+ void updateIcons (void);
+ void updateOpacity (void)
+ {
+ mOpacity = readPropertyShort (mClientId, Atoms::netWmWindowOpacity,
+ 0xffff);
+ }
+ Drawable pixmapId (void) const
+ {
+ return mPixmap;
+ }
+ void addDamageRect (int x, int y, int w, int h)
+ {
+ mDamage += TQRegion (x, y, w, h);
+ }
+ bool handleMap (void);
+ bool handleConfigure (TQSize size);
+ void processDamage (void);
+ decor_context_t *context (void)
+ {
+ return &mContext;
+ }
+ decor_shadow_t *shadow (void)
+ {
+ return mShadow;
+ }
+ decor_extents_t *border (void)
+ {
+ return &mBorder;
+ }
+ TQRect clientGeometry (void);
+ void showKillProcessDialog (Time timestamp);
+ void hideKillProcessDialog (void);
+
+ private:
+ void createDecoration (void);
+ void updateShadow (void);
+ bool resizeDecoration (bool force = false);
+ void updateBlurProperty (int topOffset,
+ int bottomOffset,
+ int leftOffset,
+ int rightOffset);
+ void updateProperty (void);
+ void getWindowProtocols (void);
+ void performMouseCommand (KWD::Options::MouseCommand command,
+ TQMouseEvent *qme);
+ NET::Direction positionToDirection (int pos);
+ Cursor positionToCursor (TQPoint pos);
+ void rebindPixmap (void);
+
+
+ private slots:
+ void handlePopupActivated (int id);
+ void handleDesktopPopupActivated (int id);
+ void handleViewportPopupActivated (int id);
+ void handlePopupAboutToShow (void);
+ void handleProcessKillerExited (void);
+
+ private:
+ Type mType;
+ WId mParentId;
+ WId mFrame;
+ WId mClientId;
+ WId mSelectedId;
+ TQRect mGeometry;
+ TQString mName;
+ TQIconSet mIcons;
+ decor_extents_t mBorder;
+ unsigned short mOpacity;
+ KDecoration *mDecor;
+ TQPixmap mTexturePixmap;
+ TQPixmap mTexturePixmapBuffer;
+ Pixmap mPixmap;
+ TQRegion mDamage;
+ WId mDamageId;
+ decor_layout_t mLayout;
+ decor_context_t mContext;
+ decor_shadow_t *mShadow;
+ Picture mPicture;
+ Picture mTexturePicture;
+ Picture mDecorationPicture;
+ bool mUpdateProperty;
+ bool mShapeSet;
+ bool mUniqueHorzShape;
+ bool mUniqueVertShape;
+ TQRegion mShape;
+ TQWidget *mActiveChild;
+ bool mSupportTakeFocus;
+ bool mSupportContextHelp;
+ TQPopupMenu *mPopup;
+ TQPopupMenu *mAdvancedMenu;
+ TQPopupMenu *mDesktopMenu;
+ TQPopupMenu *mViewportMenu;
+ unsigned long mState;
+ bool mMapped;
+ int mPendingMap;
+ int mPendingConfigure;
+ TQSize mSize;
+ TDEProcess *mProcessKiller;
+ };
+}
+
+#endif