summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am46
-rw-r--r--src/Makefile.in686
-rw-r--r--src/hi16-action-kompose_current_virtual_desktop.pngbin0 -> 886 bytes
-rw-r--r--src/hi16-action-kompose_grouped_by_virtual_desktop.pngbin0 -> 809 bytes
-rw-r--r--src/hi16-action-kompose_ungrouped.pngbin0 -> 681 bytes
-rw-r--r--src/hi16-app-kompose.pngbin0 -> 684 bytes
-rw-r--r--src/hi32-action-kompose_current_virtual_desktop.pngbin0 -> 1941 bytes
-rw-r--r--src/hi32-action-kompose_grouped_by_virtual_desktop.pngbin0 -> 1490 bytes
-rw-r--r--src/hi32-action-kompose_ungrouped.pngbin0 -> 1352 bytes
-rw-r--r--src/hi32-app-kompose.pngbin0 -> 1646 bytes
-rw-r--r--src/kompose.cpp88
-rw-r--r--src/kompose.desktop19
-rw-r--r--src/kompose.h47
-rw-r--r--src/kompose.lsm16
-rw-r--r--src/komposedcopiface.h33
-rw-r--r--src/komposedesktopwidget.cpp239
-rw-r--r--src/komposedesktopwidget.h70
-rw-r--r--src/komposefullscreenwidget.cpp223
-rw-r--r--src/komposefullscreenwidget.h61
-rw-r--r--src/komposegldesktopwidget.cpp116
-rw-r--r--src/komposeglfullscreenwidget.cpp176
-rw-r--r--src/komposeglobal.cpp375
-rw-r--r--src/komposeglobal.h109
-rw-r--r--src/komposegltaskwidget.cpp119
-rw-r--r--src/komposeglwidget.cpp119
-rw-r--r--src/komposeimage.cpp256
-rw-r--r--src/komposeimage.h87
-rw-r--r--src/komposelayout.cpp426
-rw-r--r--src/komposelayout.h95
-rw-r--r--src/komposepreferences.cpp411
-rw-r--r--src/komposepreferences.cpp.orig291
-rw-r--r--src/komposepreferences.h109
-rw-r--r--src/komposesettings.cpp235
-rw-r--r--src/komposesettings.h174
-rw-r--r--src/komposesystray.cpp127
-rw-r--r--src/komposesystray.h47
-rw-r--r--src/komposetask.cpp357
-rw-r--r--src/komposetask.h118
-rw-r--r--src/komposetaskcontainerwidget.cpp254
-rw-r--r--src/komposetaskcontainerwidget.h58
-rw-r--r--src/komposetaskmanager.cpp387
-rw-r--r--src/komposetaskmanager.h86
-rw-r--r--src/komposetaskprefswidget.cpp54
-rw-r--r--src/komposetaskprefswidget.h32
-rw-r--r--src/komposetaskvisualizer.cpp458
-rw-r--r--src/komposetaskvisualizer.h87
-rw-r--r--src/komposetaskwidget.cpp427
-rw-r--r--src/komposetaskwidget.h100
-rw-r--r--src/komposeui.rc8
-rw-r--r--src/komposeviewmanager.cpp258
-rw-r--r--src/komposeviewmanager.h79
-rw-r--r--src/komposewidget.cpp94
-rw-r--r--src/komposewidget.h56
-rw-r--r--src/main.cpp94
54 files changed, 7807 insertions, 0 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..77d2354
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,46 @@
+# set the include path for X, qt and KDE
+INCLUDES = $(all_includes) -I `imlib2-config --cflags`
+
+# these are the headers for your project
+noinst_HEADERS = kompose.h komposetaskmanager.h komposetask.h komposewidget.h \
+ komposetaskwidget.h komposedesktopwidget.h komposelayout.h komposesystray.h \
+ komposefullscreenwidget.h komposesettings.h komposepreferences.h komposetaskprefswidget.h \
+ komposeglobal.h komposetaskcontainerwidget.h komposetaskvisualizer.h \
+ komposeviewmanager.h komposedcopiface.h
+
+# let automoc handle all of the meta source files (moc)
+METASOURCES = AUTO
+
+messages: rc.cpp
+ $(XGETTEXT) *.cpp --language=C --from-code=UTF-8 -o $(podir)/kompose.pot
+
+komposeiconsdir = $(kde_datadir)/kompose/icons
+komposeicons_ICON = AUTO
+
+#########################################################################
+# APPLICATION SECTION
+#########################################################################
+# this is the program that gets installed. it's name is used for all
+# of the other Makefile.am variables
+bin_PROGRAMS = kompose
+
+# the application source, library search path, and link libraries
+kompose_SOURCES = main.cpp kompose.cpp komposetaskmanager.cpp komposetask.cpp \
+ komposewidget.cpp komposetaskwidget.cpp komposedesktopwidget.cpp komposelayout.cpp \
+ komposesystray.cpp komposefullscreenwidget.cpp komposesettings.cpp komposepreferences.cpp \
+ komposetaskprefswidget.cpp komposeglobal.cpp komposetaskcontainerwidget.cpp \
+ komposetaskvisualizer.cpp komposeviewmanager.cpp komposedcopiface.skel
+#kompose_LDFLAGS = $(KDE_RPATH) $(all_libraries) -lX11 -lXext -lm `pkg-config xft xrender xcomposite xdamage xfixes --libs` `imlib2-config --libs`
+kompose_LDFLAGS = $(KDE_RPATH) $(all_libraries) -lX11 -lXext -lm `imlib2-config --libs`
+kompose_LDADD = $(LIB_KDEUI) $(LIB_XCOMPOSITE) $(LIB_XDAMAGE)
+
+# this is where the desktop file will go
+shelldesktopdir = $(kde_appsdir)/Utilities
+shelldesktop_DATA = kompose.desktop
+
+# this is where the shell's XML-GUI resource file goes
+shellrcdir = $(kde_datadir)/kompose
+shellrc_DATA = komposeui.rc
+
+
+
diff --git a/src/Makefile.in b/src/Makefile.in
new file mode 100644
index 0000000..5e620fc
--- /dev/null
+++ b/src/Makefile.in
@@ -0,0 +1,686 @@
+# Makefile.in generated by automake 1.9.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+bin_PROGRAMS = kompose$(EXEEXT)
+subdir = src
+DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
+ $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/admin/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(shelldesktopdir)" \
+ "$(DESTDIR)$(shellrcdir)"
+binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+PROGRAMS = $(bin_PROGRAMS)
+am_kompose_OBJECTS = main.$(OBJEXT) kompose.$(OBJEXT) \
+ komposetaskmanager.$(OBJEXT) komposetask.$(OBJEXT) \
+ komposewidget.$(OBJEXT) komposetaskwidget.$(OBJEXT) \
+ komposedesktopwidget.$(OBJEXT) komposelayout.$(OBJEXT) \
+ komposesystray.$(OBJEXT) komposefullscreenwidget.$(OBJEXT) \
+ komposesettings.$(OBJEXT) komposepreferences.$(OBJEXT) \
+ komposetaskprefswidget.$(OBJEXT) komposeglobal.$(OBJEXT) \
+ komposetaskcontainerwidget.$(OBJEXT) \
+ komposetaskvisualizer.$(OBJEXT) komposeviewmanager.$(OBJEXT)
+kompose_OBJECTS = $(am_kompose_OBJECTS)
+am__DEPENDENCIES_1 =
+kompose_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1)
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/admin/depcomp
+am__depfiles_maybe = depfiles
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CXXFLAGS) $(CXXFLAGS)
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) --tag=CXX --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(kompose_SOURCES)
+DIST_SOURCES = $(kompose_SOURCES)
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+shelldesktopDATA_INSTALL = $(INSTALL_DATA)
+shellrcDATA_INSTALL = $(INSTALL_DATA)
+DATA = $(shelldesktop_DATA) $(shellrc_DATA)
+HEADERS = $(noinst_HEADERS)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AR = @AR@
+ARTSCCONFIG = @ARTSCCONFIG@
+AUTOCONF = @AUTOCONF@
+AUTODIRS = @AUTODIRS@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CONF_FILES = @CONF_FILES@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DCOPIDL = @DCOPIDL@
+DCOPIDL2CPP = @DCOPIDL2CPP@
+DCOPIDLNG = @DCOPIDLNG@
+DCOP_DEPENDENCIES = @DCOP_DEPENDENCIES@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FRAMEWORK_COREAUDIO = @FRAMEWORK_COREAUDIO@
+GMSGFMT = @GMSGFMT@
+IMLIB2_CFLAGS = @IMLIB2_CFLAGS@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+KCFG_DEPENDENCIES = @KCFG_DEPENDENCIES@
+KCONFIG_COMPILER = @KCONFIG_COMPILER@
+KDECONFIG = @KDECONFIG@
+KDE_EXTRA_RPATH = @KDE_EXTRA_RPATH@
+KDE_INCLUDES = @KDE_INCLUDES@
+KDE_LDFLAGS = @KDE_LDFLAGS@
+KDE_MT_LDFLAGS = @KDE_MT_LDFLAGS@
+KDE_MT_LIBS = @KDE_MT_LIBS@
+KDE_NO_UNDEFINED = @KDE_NO_UNDEFINED@
+KDE_PLUGIN = @KDE_PLUGIN@
+KDE_RPATH = @KDE_RPATH@
+KDE_USE_CLOSURE_FALSE = @KDE_USE_CLOSURE_FALSE@
+KDE_USE_CLOSURE_TRUE = @KDE_USE_CLOSURE_TRUE@
+KDE_USE_FINAL_FALSE = @KDE_USE_FINAL_FALSE@
+KDE_USE_FINAL_TRUE = @KDE_USE_FINAL_TRUE@
+KDE_USE_NMCHECK_FALSE = @KDE_USE_NMCHECK_FALSE@
+KDE_USE_NMCHECK_TRUE = @KDE_USE_NMCHECK_TRUE@
+KDE_XSL_STYLESHEET = @KDE_XSL_STYLESHEET@
+LDFLAGS = @LDFLAGS@
+LIBCOMPAT = @LIBCOMPAT@
+LIBCRYPT = @LIBCRYPT@
+LIBDL = @LIBDL@
+LIBJPEG = @LIBJPEG@
+LIBOBJS = @LIBOBJS@
+LIBPNG = @LIBPNG@
+LIBPTHREAD = @LIBPTHREAD@
+LIBRESOLV = @LIBRESOLV@
+LIBS = @LIBS@
+LIBSM = @LIBSM@
+LIBSOCKET = @LIBSOCKET@
+LIBTOOL = @LIBTOOL@
+LIBUCB = @LIBUCB@
+LIBUTIL = @LIBUTIL@
+LIBZ = @LIBZ@
+LIB_IMLIB2 = @LIB_IMLIB2@
+LIB_KAB = @LIB_KAB@
+LIB_KABC = @LIB_KABC@
+LIB_KDECORE = @LIB_KDECORE@
+LIB_KDEPIM = @LIB_KDEPIM@
+LIB_KDEPRINT = @LIB_KDEPRINT@
+LIB_KDEUI = @LIB_KDEUI@
+LIB_KFILE = @LIB_KFILE@
+LIB_KFM = @LIB_KFM@
+LIB_KHTML = @LIB_KHTML@
+LIB_KIO = @LIB_KIO@
+LIB_KPARTS = @LIB_KPARTS@
+LIB_KSPELL = @LIB_KSPELL@
+LIB_KSYCOCA = @LIB_KSYCOCA@
+LIB_KUTILS = @LIB_KUTILS@
+LIB_POLL = @LIB_POLL@
+LIB_QPE = @LIB_QPE@
+LIB_QT = @LIB_QT@
+LIB_SMB = @LIB_SMB@
+LIB_X11 = @LIB_X11@
+LIB_XCOMPOSITE = @LIB_XCOMPOSITE@
+LIB_XDAMAGE = @LIB_XDAMAGE@
+LIB_XEXT = @LIB_XEXT@
+LIB_XRENDER = @LIB_XRENDER@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MCOPIDL = @MCOPIDL@
+MEINPROC = @MEINPROC@
+MOC = @MOC@
+MSGFMT = @MSGFMT@
+NOOPT_CFLAGS = @NOOPT_CFLAGS@
+NOOPT_CXXFLAGS = @NOOPT_CXXFLAGS@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+QTE_NORTTI = @QTE_NORTTI@
+QT_INCLUDES = @QT_INCLUDES@
+QT_LDFLAGS = @QT_LDFLAGS@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+TOPSUBDIRS = @TOPSUBDIRS@
+UIC = @UIC@
+UIC_TR = @UIC_TR@
+USER_INCLUDES = @USER_INCLUDES@
+USER_LDFLAGS = @USER_LDFLAGS@
+USE_EXCEPTIONS = @USE_EXCEPTIONS@
+USE_RTTI = @USE_RTTI@
+USE_THREADS = @USE_THREADS@
+VERSION = @VERSION@
+WOVERLOADED_VIRTUAL = @WOVERLOADED_VIRTUAL@
+XGETTEXT = @XGETTEXT@
+XMLLINT = @XMLLINT@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_INCLUDES = @X_INCLUDES@
+X_LDFLAGS = @X_LDFLAGS@
+X_PRE_LIBS = @X_PRE_LIBS@
+X_RPATH = @X_RPATH@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+all_includes = @all_includes@
+all_libraries = @all_libraries@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
+am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+include_ARTS_FALSE = @include_ARTS_FALSE@
+include_ARTS_TRUE = @include_ARTS_TRUE@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+kde_appsdir = @kde_appsdir@
+kde_bindir = @kde_bindir@
+kde_confdir = @kde_confdir@
+kde_datadir = @kde_datadir@
+kde_htmldir = @kde_htmldir@
+kde_icondir = @kde_icondir@
+kde_includes = @kde_includes@
+kde_kcfgdir = @kde_kcfgdir@
+kde_libraries = @kde_libraries@
+kde_libs_htmldir = @kde_libs_htmldir@
+kde_libs_prefix = @kde_libs_prefix@
+kde_locale = @kde_locale@
+kde_mimedir = @kde_mimedir@
+kde_moduledir = @kde_moduledir@
+kde_qtver = @kde_qtver@
+kde_servicesdir = @kde_servicesdir@
+kde_servicetypesdir = @kde_servicetypesdir@
+kde_sounddir = @kde_sounddir@
+kde_styledir = @kde_styledir@
+kde_templatesdir = @kde_templatesdir@
+kde_wallpaperdir = @kde_wallpaperdir@
+kde_widgetdir = @kde_widgetdir@
+kdeinitdir = @kdeinitdir@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+qt_includes = @qt_includes@
+qt_libraries = @qt_libraries@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+x_includes = @x_includes@
+x_libraries = @x_libraries@
+xdg_appsdir = @xdg_appsdir@
+xdg_directorydir = @xdg_directorydir@
+xdg_menudir = @xdg_menudir@
+
+# set the include path for X, qt and KDE
+INCLUDES = $(all_includes) -I `imlib2-config --cflags`
+
+# these are the headers for your project
+noinst_HEADERS = kompose.h komposetaskmanager.h komposetask.h komposewidget.h \
+ komposetaskwidget.h komposedesktopwidget.h komposelayout.h komposesystray.h \
+ komposefullscreenwidget.h komposesettings.h komposepreferences.h komposetaskprefswidget.h \
+ komposeglobal.h komposetaskcontainerwidget.h komposetaskvisualizer.h \
+ komposeviewmanager.h komposedcopiface.h
+
+
+# let automoc handle all of the meta source files (moc)
+METASOURCES = AUTO
+komposeiconsdir = $(kde_datadir)/kompose/icons
+komposeicons_ICON = AUTO
+
+# the application source, library search path, and link libraries
+kompose_SOURCES = main.cpp kompose.cpp komposetaskmanager.cpp komposetask.cpp \
+ komposewidget.cpp komposetaskwidget.cpp komposedesktopwidget.cpp komposelayout.cpp \
+ komposesystray.cpp komposefullscreenwidget.cpp komposesettings.cpp komposepreferences.cpp \
+ komposetaskprefswidget.cpp komposeglobal.cpp komposetaskcontainerwidget.cpp \
+ komposetaskvisualizer.cpp komposeviewmanager.cpp komposedcopiface.skel
+
+#kompose_LDFLAGS = $(KDE_RPATH) $(all_libraries) -lX11 -lXext -lm `pkg-config xft xrender xcomposite xdamage xfixes --libs` `imlib2-config --libs`
+kompose_LDFLAGS = $(KDE_RPATH) $(all_libraries) -lX11 -lXext -lm `imlib2-config --libs`
+kompose_LDADD = $(LIB_KDEUI) $(LIB_XCOMPOSITE) $(LIB_XDAMAGE)
+
+# this is where the desktop file will go
+shelldesktopdir = $(kde_appsdir)/Utilities
+shelldesktop_DATA = kompose.desktop
+
+# this is where the shell's XML-GUI resource file goes
+shellrcdir = $(kde_datadir)/kompose
+shellrc_DATA = komposeui.rc
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .cpp .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)"
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ if test -f $$p \
+ || test -f $$p1 \
+ ; then \
+ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \
+ else :; fi; \
+ done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
+ rm -f "$(DESTDIR)$(bindir)/$$f"; \
+ done
+
+clean-binPROGRAMS:
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f $$p $$f"; \
+ rm -f $$p $$f ; \
+ done
+kompose$(EXEEXT): $(kompose_OBJECTS) $(kompose_DEPENDENCIES)
+ @rm -f kompose$(EXEEXT)
+ $(CXXLINK) $(kompose_LDFLAGS) $(kompose_OBJECTS) $(kompose_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kompose.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/komposedesktopwidget.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/komposefullscreenwidget.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/komposeglobal.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/komposelayout.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/komposepreferences.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/komposesettings.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/komposesystray.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/komposetask.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/komposetaskcontainerwidget.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/komposetaskmanager.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/komposetaskprefswidget.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/komposetaskvisualizer.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/komposetaskwidget.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/komposeviewmanager.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/komposewidget.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@
+
+.cpp.o:
+@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $<
+
+.cpp.obj:
+@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cpp.lo:
+@am__fastdepCXX_TRUE@ if $(LTCXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+ -rm -f libtool
+uninstall-info-am:
+install-shelldesktopDATA: $(shelldesktop_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(shelldesktopdir)" || $(mkdir_p) "$(DESTDIR)$(shelldesktopdir)"
+ @list='$(shelldesktop_DATA)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(shelldesktopDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(shelldesktopdir)/$$f'"; \
+ $(shelldesktopDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(shelldesktopdir)/$$f"; \
+ done
+
+uninstall-shelldesktopDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(shelldesktop_DATA)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(shelldesktopdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(shelldesktopdir)/$$f"; \
+ done
+install-shellrcDATA: $(shellrc_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(shellrcdir)" || $(mkdir_p) "$(DESTDIR)$(shellrcdir)"
+ @list='$(shellrc_DATA)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(shellrcDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(shellrcdir)/$$f'"; \
+ $(shellrcDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(shellrcdir)/$$f"; \
+ done
+
+uninstall-shellrcDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(shellrc_DATA)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(shellrcdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(shellrcdir)/$$f"; \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+ list='$(DISTFILES)'; for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+ esac; \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ dir="/$$dir"; \
+ $(mkdir_p) "$(distdir)$$dir"; \
+ else \
+ dir=''; \
+ fi; \
+ if test -d $$d/$$file; then \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS) $(DATA) $(HEADERS)
+installdirs:
+ for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(shelldesktopdir)" "$(DESTDIR)$(shellrcdir)"; do \
+ test -z "$$dir" || $(mkdir_p) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-libtool distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-shelldesktopDATA install-shellrcDATA
+
+install-exec-am: install-binPROGRAMS
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS uninstall-info-am \
+ uninstall-shelldesktopDATA uninstall-shellrcDATA
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \
+ clean-generic clean-libtool ctags distclean distclean-compile \
+ distclean-generic distclean-libtool distclean-tags distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-binPROGRAMS install-data install-data-am install-exec \
+ install-exec-am install-info install-info-am install-man \
+ install-shelldesktopDATA install-shellrcDATA install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-binPROGRAMS \
+ uninstall-info-am uninstall-shelldesktopDATA \
+ uninstall-shellrcDATA
+
+
+messages: rc.cpp
+ $(XGETTEXT) *.cpp --language=C --from-code=UTF-8 -o $(podir)/kompose.pot
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/hi16-action-kompose_current_virtual_desktop.png b/src/hi16-action-kompose_current_virtual_desktop.png
new file mode 100644
index 0000000..de19389
--- /dev/null
+++ b/src/hi16-action-kompose_current_virtual_desktop.png
Binary files differ
diff --git a/src/hi16-action-kompose_grouped_by_virtual_desktop.png b/src/hi16-action-kompose_grouped_by_virtual_desktop.png
new file mode 100644
index 0000000..26dc380
--- /dev/null
+++ b/src/hi16-action-kompose_grouped_by_virtual_desktop.png
Binary files differ
diff --git a/src/hi16-action-kompose_ungrouped.png b/src/hi16-action-kompose_ungrouped.png
new file mode 100644
index 0000000..7bd14a3
--- /dev/null
+++ b/src/hi16-action-kompose_ungrouped.png
Binary files differ
diff --git a/src/hi16-app-kompose.png b/src/hi16-app-kompose.png
new file mode 100644
index 0000000..691be39
--- /dev/null
+++ b/src/hi16-app-kompose.png
Binary files differ
diff --git a/src/hi32-action-kompose_current_virtual_desktop.png b/src/hi32-action-kompose_current_virtual_desktop.png
new file mode 100644
index 0000000..0854ab6
--- /dev/null
+++ b/src/hi32-action-kompose_current_virtual_desktop.png
Binary files differ
diff --git a/src/hi32-action-kompose_grouped_by_virtual_desktop.png b/src/hi32-action-kompose_grouped_by_virtual_desktop.png
new file mode 100644
index 0000000..c3d92a0
--- /dev/null
+++ b/src/hi32-action-kompose_grouped_by_virtual_desktop.png
Binary files differ
diff --git a/src/hi32-action-kompose_ungrouped.png b/src/hi32-action-kompose_ungrouped.png
new file mode 100644
index 0000000..5497100
--- /dev/null
+++ b/src/hi32-action-kompose_ungrouped.png
Binary files differ
diff --git a/src/hi32-app-kompose.png b/src/hi32-app-kompose.png
new file mode 100644
index 0000000..45ec52a
--- /dev/null
+++ b/src/hi32-app-kompose.png
Binary files differ
diff --git a/src/kompose.cpp b/src/kompose.cpp
new file mode 100644
index 0000000..60cec12
--- /dev/null
+++ b/src/kompose.cpp
@@ -0,0 +1,88 @@
+/***************************************************************************
+ * Copyright (C) 2004 by Hans Oischinger *
+ * *
+ * 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 "kompose.h"
+
+#include "komposeglobal.h"
+#include "komposesettings.h"
+#include "komposetaskmanager.h"
+
+#include <klocale.h>
+#include <kuniqueapplication.h>
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#ifdef COMPOSITE
+#include <X11/Xatom.h>
+#include <X11/extensions/Xcomposite.h>
+#include <X11/extensions/Xdamage.h>
+#include <X11/extensions/Xrender.h>
+#endif
+
+Kompose::Kompose()
+{
+}
+
+Kompose::~Kompose()
+{}
+
+bool Kompose::x11EventFilter (XEvent *event)
+{
+#ifdef COMPOSITE
+ if ( KomposeGlobal::instance()->hasXcomposite() && KomposeSettings::instance()->getUseComposite() )
+ {
+ if ( event->type == KomposeGlobal::instance()->getDamageEvent() + XDamageNotify )
+ {
+ KomposeTaskManager::instance()->processX11Event( event );
+ // XDamageNotifyEvent *e = reinterpret_cast<XDamageNotifyEvent*>( event );
+ // // e->drawable is the window ID of the damaged window
+ // // e->geometry is the geometry of the damaged window
+ // // e->area is the bounding rect for the damaged area
+ // // e->damage is the damage handle returned by XDamageCreate()
+ //
+ // // Subtract all the damage, repairing the window.
+ // XDamageSubtract( dpy, e->damage, None, None );
+ }
+ //
+ // else if ( event->type == shape_event + ShapeNotify )
+ // {
+ // XShapeEvent *e = reinterpret_cast<XShapeEvent*>( event );
+ // // It's probably safe to assume that the window shape region
+ // // is invalid at this point...
+ // }
+
+ else if ( event->type == ConfigureNotify )
+ {
+ // XConfigureEvent *e = &event->xconfigure;
+ // The windows size, position or Z index in the stacking
+ // order has changed
+ KomposeTaskManager::instance()->processX11Event( event );
+ }
+
+ }
+#endif
+
+ // This costed me nerves:
+ // Call this or kwinmodule won't work
+ return KApplication::x11EventFilter(event);
+}
+
+
+#include "kompose.moc"
diff --git a/src/kompose.desktop b/src/kompose.desktop
new file mode 100644
index 0000000..6ee7710
--- /dev/null
+++ b/src/kompose.desktop
@@ -0,0 +1,19 @@
+[Desktop Entry]
+Comment=An Apple Exposé like Taskmanager
+Comment[en_US]=An Apple Exposé like Taskmanager
+Encoding=UTF-8
+Exec=kompose
+GenericName=Window Switcher
+GenericName[en_US]=
+Icon=kompose
+MimeType=
+Name=Komposé
+Name[en_US]=Komposé
+Path=
+StartupNotify=true
+Terminal=false
+TerminalOptions=
+Type=Application
+X-DCOP-ServiceType=
+X-KDE-SubstituteUID=false
+X-KDE-Username=
diff --git a/src/kompose.h b/src/kompose.h
new file mode 100644
index 0000000..749c0ec
--- /dev/null
+++ b/src/kompose.h
@@ -0,0 +1,47 @@
+/***************************************************************************
+ * Copyright (C) 2004 by Hans Oischinger *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#ifndef _KOMPOSE_H_
+#define _KOMPOSE_H_
+
+// #ifdef HAVE_CONFIG_H
+// #include <config.h>
+// #endif
+
+#include <kuniqueapplication.h>
+
+
+/**
+ * @short Application Main entry point and x11 Event Receiver
+ * @author Hans Oischinger <[email protected]>
+ */
+class Kompose : public KUniqueApplication
+{
+ Q_OBJECT
+public:
+ Kompose();
+ virtual ~Kompose();
+
+protected:
+ bool x11EventFilter (XEvent *);
+
+};
+
+#endif // _KOMPOSE_H_
diff --git a/src/kompose.lsm b/src/kompose.lsm
new file mode 100644
index 0000000..872b99d
--- /dev/null
+++ b/src/kompose.lsm
@@ -0,0 +1,16 @@
+Begin3
+Title: kompose -- Some description
+Version: 0.5.2
+Entered-date:
+Description:
+Keywords: KDE Qt
+Author: Hans Oischinger <[email protected]>
+Maintained-by: Hans Oischinger <[email protected]>
+Home-page:
+Alternate-site:
+Primary-site: ftp://ftp.kde.org/pub/kde/unstable/apps/utils
+ xxxxxx kompose-0.5.2.tar.gz
+ xxx kompose.lsm
+Platform: Linux. Needs KDE
+Copying-policy: GPL
+End
diff --git a/src/komposedcopiface.h b/src/komposedcopiface.h
new file mode 100644
index 0000000..2527af3
--- /dev/null
+++ b/src/komposedcopiface.h
@@ -0,0 +1,33 @@
+//
+// C++ Interface: %{MODULE}
+//
+// Description:
+//
+//
+// Author: %{AUTHOR} <%{EMAIL}>, (C) %{YEAR}
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#ifndef KOMPOSEDCOPIFACE_H
+#define KOMPOSEDCOPIFACE_H
+
+#include <dcopobject.h>
+
+/**
+@author Hans Oischinger
+*/
+class KomposeDcopIface : virtual public DCOPObject
+{
+ K_DCOP
+
+ k_dcop:
+
+ virtual void createDefaultView() = 0;
+ virtual void createVirtualDesktopView() = 0;
+ virtual void createCurrentDesktopView() = 0;
+ virtual void createWorldView() = 0;
+ virtual void closeCurrentView() = 0;
+};
+
+#endif
diff --git a/src/komposedesktopwidget.cpp b/src/komposedesktopwidget.cpp
new file mode 100644
index 0000000..952366c
--- /dev/null
+++ b/src/komposedesktopwidget.cpp
@@ -0,0 +1,239 @@
+/***************************************************************************
+ * Copyright (C) 2004 by Hans Oischinger *
+ * *
+ * 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 "komposedesktopwidget.h"
+#include "komposelayout.h"
+#include "komposetask.h"
+#include "komposetaskwidget.h"
+#include "komposeviewmanager.h"
+#include "komposetaskmanager.h"
+#include "komposesettings.h"
+#include "komposeglobal.h"
+
+#include <qdesktopwidget.h>
+#include <qcolor.h>
+#include <qpainter.h>
+#include <qapplication.h>
+#include <qdragobject.h>
+#include <qtooltip.h>
+
+#include <klocale.h>
+#include <kwin.h>
+#include <ksharedpixmap.h>
+#include <krootpixmap.h>
+#include <kwinmodule.h>
+#include <kcursor.h>
+#include <kdebug.h>
+
+
+KomposeDesktopWidget::KomposeDesktopWidget(int desktop, QWidget *parent, KomposeLayout *l, const char *name)
+ : KomposeTaskContainerWidget( desktop, parent, l, name ),
+ highlight(false)
+{
+ // Retrieve geometry
+ // QDesktopWidget *deskwidget = new QDesktopWidget();
+ // deskRect = deskwidget->screenGeometry();
+ // delete deskwidget;
+ initFonts();
+
+ // Set Desktop background as our background
+ setBackgroundMode( Qt::NoBackground );
+
+ KWinModule kwinmodule( this, 1 );
+ deskName = kwinmodule.desktopName(desktop+1);
+
+ QToolTip::add( this, i18n("Desktop %1 - %2").arg(desktop).arg(deskName) );
+
+ rootpix = new KRootPixmap (this);
+ rootpix->start();
+ setAcceptDrops(TRUE);
+
+ createTaskWidgets();
+
+ connect( KomposeTaskManager::instance(), SIGNAL( newTask( KomposeTask* ) ), this, SLOT( createTaskWidget( KomposeTask* ) ) );
+
+ setFocusPolicy(QWidget::ClickFocus);
+
+}
+
+
+KomposeDesktopWidget::~KomposeDesktopWidget()
+{
+ disconnect( KomposeTaskManager::instance(), SIGNAL( newTask( KomposeTask* ) ), this, SLOT( createTaskWidget( KomposeTask* ) ) );
+}
+
+void KomposeDesktopWidget::initFonts()
+{
+ titleFont = KomposeSettings::instance()->getDesktopTitleFont();
+}
+
+
+// int KomposeDesktopWidget::getHeightForWidth( int w ) const
+// {
+// kdDebug() << "KomposeDesktopWidget::getHeightForWidth()");
+// return ((double)w / (double)deskRect.width()) * deskRect.height();
+// }
+//
+// int KomposeDesktopWidget::getWidthForHeight( int h ) const
+// {
+// kdDebug() << "KomposeDesktopWidget::getWidthForHeight()");
+// return ((double)h / (double)deskRect.height()) * deskRect.width();
+// }
+//
+// double KomposeDesktopWidget::getAspectRatio()
+// {
+// kdDebug() << "KomposeDesktopWidget::getAspectRatio()");
+// return (double)deskRect.width() / (double)deskRect.height();
+// }
+
+
+void KomposeDesktopWidget::leaveEvent ( QEvent * )
+{
+ // Unset highlight if cursor moves out of our rect
+ // but not if it enters a child widget
+ QRect deskRect;
+ deskRect.setTopLeft(mapToGlobal( QPoint(0,0) ));
+ deskRect.setWidth(width());
+ deskRect.setHeight(height());
+ if ( !deskRect.contains( QCursor::pos() ) )
+ highlight = false;
+
+ unsetCursor();
+ repaint();
+}
+
+void KomposeDesktopWidget::enterEvent ( QEvent * )
+{
+ setFocus();
+ setCursor( KCursor::handCursor() );
+ highlight = true;
+ repaint();
+}
+
+void KomposeDesktopWidget::focusInEvent ( QFocusEvent * )
+{
+ highlight = true;
+ repaint();
+}
+
+void KomposeDesktopWidget::focusOutEvent ( QFocusEvent * )
+{
+ // Unset highlight if cursor moves out of our rect
+ // but not if it enters a child widget
+ QRect deskRect;
+ deskRect.setTopLeft(mapToGlobal( QPoint(0,0) ));
+ deskRect.setWidth(width());
+ deskRect.setHeight(height());
+ if ( !deskRect.contains( QCursor::pos() ) )
+ highlight = false;
+
+ repaint();
+}
+
+void KomposeDesktopWidget::mouseReleaseEvent ( QMouseEvent * e )
+{
+ if ( !rect().contains( e->pos() ) )
+ return;
+ KomposeViewManager::instance()->setCurrentDesktop(desktop);
+}
+
+
+void KomposeDesktopWidget::mouseDoubleClickEvent ( QMouseEvent * e )
+{
+ if ( !rect().contains( e->pos() ) )
+ return;
+ KomposeViewManager::instance()->setCurrentDesktop(desktop);
+}
+
+
+void KomposeDesktopWidget::paintEvent ( QPaintEvent * )
+{
+ // KomposeWidget::paintEvent(e);
+ QPainter p;
+ p.begin( this );
+// QPoint tl = mapToGlobal(QPoint(0,0));
+// p.drawPixmap(0,0, *KomposeGlobal::instance()->getDesktopBgPixmap(),
+// tl.x(), tl.y(), width(), height());
+
+ p.setFont(titleFont);
+
+ if (highlight)
+ p.setPen( KomposeSettings::instance()->getDesktopTitleFontHighlightColor() );
+ else
+ p.setPen( KomposeSettings::instance()->getDesktopTitleFontColor() );
+
+ // Bounding rect
+ p.drawRect(rect());
+
+ // paint the Desktop num & name (centered if empty, bottom right if not)
+ if ( layout->getNumofChilds() == 0 )
+ p.drawText(QRect(QPoint(0,0), size()), Qt::AlignCenter, QString("Desktop %1 - %2").arg(desktop+1).arg(deskName));
+ else
+ p.drawText(QRect(QPoint(0,0), size()), Qt::AlignRight | Qt::AlignBottom, QString("Desktop %1 - %2").arg(desktop+1).arg(deskName));
+
+ p.end();
+}
+
+void KomposeDesktopWidget::dragEnterEvent( QDragEnterEvent* e )
+{
+ kdDebug() << "KomposeDesktopWidget::dragEnterEvent" << endl;
+ e->accept( QTextDrag::canDecode(e) );
+}
+
+void KomposeDesktopWidget::dropEvent ( QDropEvent * e )
+{
+ QString text;
+ if ( QTextDrag::decode(e, text) )
+ {
+ kdDebug() << "KomposeDesktopWidget::dropEvent - Received Task drop" << endl;
+ KomposeTaskWidget* dropWidget = dynamic_cast<KomposeTaskWidget*>(e->source());
+ dropWidget->getTask()->toDesktop( desktop + 1);
+ //if ( dropWidget->parentWidget() != this)
+ // dropWidget->reparent( this, QPoint(0,0), true );
+
+ e->accept();
+ }
+}
+
+
+void KomposeDesktopWidget::childEvent ( QChildEvent * ce)
+{
+ KomposeWidget::childEvent( ce );
+ emit contentsChanged();
+}
+
+
+void KomposeDesktopWidget::keyReleaseEvent ( QKeyEvent * e )
+{
+ if ( e->key() == Qt::Key_Return || e->key() == Qt::Key_Space )
+ {
+ kdDebug() << "KomposeDesktopWidget::keyReleaseEvent - Switching to Desktop!" << endl;
+ KomposeViewManager::instance()->setCurrentDesktop(desktop);
+ e->accept();
+ }
+ else
+ {
+ kdDebug() << "KomposeDesktopWidget::keyReleaseEvent - ignored..." << endl;
+ e->ignore();
+ }
+ KomposeTaskContainerWidget::keyReleaseEvent(e);
+}
+
+
+#include "komposedesktopwidget.moc"
diff --git a/src/komposedesktopwidget.h b/src/komposedesktopwidget.h
new file mode 100644
index 0000000..83db0ca
--- /dev/null
+++ b/src/komposedesktopwidget.h
@@ -0,0 +1,70 @@
+/***************************************************************************
+ * Copyright (C) 2004 by Hans Oischinger *
+ * *
+ * 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. *
+ ***************************************************************************/
+#ifndef KOMPOSEDESKTOPWIDGET_H
+#define KOMPOSEDESKTOPWIDGET_H
+
+#include "komposetaskcontainerwidget.h"
+
+class KomposeLayout;
+class KomposeTask;
+class KRootPixmap;
+/**
+@author Hans Oischinger
+*/
+class KomposeDesktopWidget : public KomposeTaskContainerWidget
+{
+ Q_OBJECT
+public:
+ KomposeDesktopWidget(int desktop, QWidget *parent = 0, KomposeLayout *l = 0, const char *name = 0);
+
+ ~KomposeDesktopWidget();
+
+ // int getHeightForWidth( int w ) const;
+ // int getWidthForHeight( int h ) const;
+ // double getAspectRatio();
+
+signals:
+ void contentsChanged();
+
+protected:
+ void paintEvent ( QPaintEvent * );
+ void dragEnterEvent ( QDragEnterEvent * );
+ void dropEvent ( QDropEvent * );
+ void leaveEvent ( QEvent * );
+ void enterEvent ( QEvent * );
+ void mouseReleaseEvent ( QMouseEvent * e );
+ void mouseDoubleClickEvent ( QMouseEvent * e );
+ void childEvent( QChildEvent * ce);
+ void focusInEvent ( QFocusEvent * );
+ void focusOutEvent ( QFocusEvent * );
+ void keyReleaseEvent ( QKeyEvent * e );
+
+protected slots:
+ void initFonts();
+
+private:
+ QRect deskRect;
+ QString deskName;
+ bool highlight; // Highlight widget?
+ QFont titleFont;
+ KRootPixmap *rootpix;
+};
+
+#endif
diff --git a/src/komposefullscreenwidget.cpp b/src/komposefullscreenwidget.cpp
new file mode 100644
index 0000000..9c8f3e0
--- /dev/null
+++ b/src/komposefullscreenwidget.cpp
@@ -0,0 +1,223 @@
+//
+// C++ Implementation: komposefullscreenwidget
+//
+// Description:
+//
+//
+// Author: Hans Oischinger <[email protected]>, (C) 2004
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#include "komposefullscreenwidget.h"
+
+#include "komposedesktopwidget.h"
+#include "komposetaskwidget.h"
+#include "komposeviewmanager.h"
+#include "komposetaskmanager.h"
+#include "komposeglobal.h"
+#include "komposelayout.h"
+
+#include <qobjectlist.h>
+#include <qptrlist.h>
+#include <qpainter.h>
+#include <qdesktopwidget.h>
+
+#include <kwin.h>
+#include <kapplication.h>
+#include <kpopupmenu.h>
+#include <kaction.h>
+#include <ksharedpixmap.h>
+#include <kcursor.h>
+#include <kglobalsettings.h>
+#include <kdebug.h>
+#include <krootpixmap.h>
+
+
+KomposeFullscreenWidget::KomposeFullscreenWidget( int displayType, KomposeLayout *l )
+ : KomposeTaskContainerWidget( -1, 0, l ),
+ type(displayType)
+{
+ // if ( QT_VERSION < 0x030300 )
+
+ /* use showMaximized instead of setWindowState to make it compile on qt 3.1 or whatever */
+ // showMaximized();
+ // KWin::setState( winId(), NET::KeepAbove );
+
+ // Set Desktop background as our background
+ setBackgroundMode( Qt::FixedPixmap );
+// setBackgroundPixmap(*(KomposeGlobal::instance()->getDesktopBgPixmap()));
+ rootpix = new KRootPixmap (this);
+ rootpix->start();
+ initMenu();
+ initView();
+ //showFullScreen();
+
+ // Alternate showFullscreen
+ setWindowState(windowState() | WindowFullScreen);
+ //setWFlags(WStyle_NoBorder);
+
+ kdDebug() << KomposeSettings::instance()->getViewScreen() << endl;
+ if (KomposeSettings::instance()->getViewScreen() == -1)
+ setGeometry( KGlobalSettings::desktopGeometry( this ) );
+ else
+ {
+ QDesktopWidget deskwidget;
+ QRect deskRect = deskwidget.screenGeometry(KomposeSettings::instance()->getViewScreen());
+ setGeometry(deskRect);
+ kdDebug() << deskRect << endl;
+ }
+
+ if (!isTopLevel())
+ QApplication::sendPostedEvents(this, QEvent::ShowFullScreen);
+ setActiveWindow();
+
+ KWin::setOnAllDesktops( winId(), true );
+}
+
+KomposeFullscreenWidget::~KomposeFullscreenWidget()
+{
+ menu->deleteLater();
+}
+
+
+void KomposeFullscreenWidget::initMenu()
+{
+ menu = new KPopupMenu();
+
+ KomposeGlobal::instance()->getActShowWorldView()->plug(menu);
+ KomposeGlobal::instance()->getActShowVirtualDesktopView()->plug(menu);
+ KomposeGlobal::instance()->getActShowCurrentDesktopView()->plug(menu);
+ menu->insertSeparator();
+ KomposeGlobal::instance()->getActPreferencesDialog()->plug(menu);
+ KomposeGlobal::instance()->getActConfigGlobalShortcuts()->plug(menu);
+ KomposeGlobal::instance()->getActAboutDlg()->plug(menu);
+ //menu->insertSeparator();
+ //KomposeGlobal::instance()->getActQuit()->plug(menu);
+}
+
+
+void KomposeFullscreenWidget::destroyChildWidgets()
+{
+ setUpdatesEnabled( false );
+ KomposeWidget *child;
+ QPtrListIterator<KomposeWidget> it( *(layout->getManagedWidgets()));
+ while ( (child = it.current()) != 0 )
+ {
+ ++it;
+ layout->remove(child);
+ dynamic_cast<QWidget*>(child)->deleteLater();
+ }
+ setUpdatesEnabled( true );
+ kdDebug() << "KomposeFullscreenWidget::destroyChildWidgets() - all children destroyed" << endl;
+}
+
+void KomposeFullscreenWidget::initView()
+{
+ setCursor( KCursor::waitCursor() );
+
+ destroyChildWidgets();
+
+ if ( type == KOMPOSEDISPLAY_VIRTUALDESKS )
+ {
+ disconnect( KomposeTaskManager::instance(), SIGNAL( newTask( KomposeTask* ) ), this, SLOT( createTaskWidget( KomposeTask* ) ) );
+ layout->setType( TLAYOUT_TASKCONTAINERS );
+ setDesktop( -2 );
+ createDesktopWidgets();
+ }
+ else if ( type == KOMPOSEDISPLAY_WORLD )
+ {
+ layout->setType( TLAYOUT_GENERIC );
+ setDesktop( -1 );
+ createTaskWidgets();
+ connect( KomposeTaskManager::instance(), SIGNAL( newTask( KomposeTask* ) ), this, SLOT( createTaskWidget( KomposeTask* ) ) );
+ }
+ else if ( type == KOMPOSEDISPLAY_CURRENTDESK )
+ {
+ layout->setType( TLAYOUT_GENERIC );
+ setDesktop( KomposeViewManager::instance()->getDesktopBeforeSnaps() );
+ createTaskWidgets();
+ connect( KomposeTaskManager::instance(), SIGNAL( newTask( KomposeTask* ) ), this, SLOT( createTaskWidget( KomposeTask* ) ) );
+ }
+
+ unsetCursor();
+}
+
+void KomposeFullscreenWidget::createDesktopWidgets()
+{
+ kdDebug() << "KomposeFullscreenWidget::createDesktopWidgets()" << endl;
+ // Create a Widget for every desktop
+ for (int i=0; i < KomposeTaskManager::instance()->getNumDesktops(); ++i)
+ {
+ //int row = i / 2;
+ //int col = i % 2;
+ //kdDebug() << "rc %d %d", row, col);
+ KomposeDesktopWidget *desktop = new KomposeDesktopWidget(i, this );
+ connect(desktop, SIGNAL(contentsChanged()), layout, SLOT(arrangeLayout()) );
+ desktop->show();
+ }
+}
+
+void KomposeFullscreenWidget::mouseReleaseEvent (QMouseEvent * )
+{}
+
+void KomposeFullscreenWidget::mousePressEvent ( QMouseEvent * e )
+{
+ if ( !rect().contains( e->pos() ) )
+ return;
+
+ switch ( e->button() )
+ {
+ case LeftButton:
+ break;
+ case MidButton:
+ // fall through
+ case RightButton:
+ menu->popup( e->globalPos() );
+ break;
+ default:
+ // nothing
+ break;
+ }
+}
+
+void KomposeFullscreenWidget::keyReleaseEvent ( QKeyEvent * e )
+{
+ if ( e->key() == Qt::Key_Escape )
+ {
+ kdDebug() << "KomposeFullscreenWidget::keyReleaseEvent - Esc key pressed - Closing view" << endl;
+ KomposeViewManager::instance()->closeCurrentView();
+ e->accept();
+ }
+ else
+ {
+ kdDebug() << "KomposeFullscreenWidget::keyReleaseEvent - ignored..." << endl;
+ e->ignore();
+ }
+ KomposeTaskContainerWidget::keyReleaseEvent(e);
+}
+
+int KomposeFullscreenWidget::getHeightForWidth ( int w ) const
+{
+ return (int)(((double)w / (double)width()) * (double)height());
+}
+
+int KomposeFullscreenWidget::getWidthForHeight ( int h ) const
+{
+ return (int)(((double)h / (double)height()) * (double)width());
+}
+
+double KomposeFullscreenWidget::getAspectRatio()
+{
+ return (double)width() / (double)height();
+}
+
+// void KomposeFullscreenWidget::paintEvent ( QPaintEvent * )
+// {
+// QPainter p( this );
+// p.drawPixmap(rect(), *(KomposeGlobal::instance()->getDesktopBgPixmap()));
+// p.end();
+// }
+
+
+#include "komposefullscreenwidget.moc"
diff --git a/src/komposefullscreenwidget.h b/src/komposefullscreenwidget.h
new file mode 100644
index 0000000..226736c
--- /dev/null
+++ b/src/komposefullscreenwidget.h
@@ -0,0 +1,61 @@
+//
+// C++ Interface: komposefullscreenwidget
+//
+// Description:
+//
+//
+// Author: Hans Oischinger <[email protected]>, (C) 2004
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#ifndef KOMPOSEFULLSCREENWIDGET_H
+#define KOMPOSEFULLSCREENWIDGET_H
+
+
+#include "komposetaskcontainerwidget.h"
+#include "komposesettings.h"
+
+
+class KRootPixmap;
+class KomposeDesktopWidget;
+class KPopupMenu;
+
+/**
+@author Hans Oischinger
+*/
+class KomposeFullscreenWidget : public KomposeTaskContainerWidget
+{
+Q_OBJECT
+public:
+ KomposeFullscreenWidget( int displayType = KOMPOSEDISPLAY_VIRTUALDESKS ,KomposeLayout *l = 0 );
+
+ virtual ~KomposeFullscreenWidget();
+
+ int getHeightForWidth( int w ) const;
+ int getWidthForHeight( int h ) const;
+ double getAspectRatio();
+
+ void setType( int t ) { type = t; initView(); }
+ int getType() { return type; }
+
+protected:
+ void initView();
+ void initMenu();
+ void createDesktopWidgets();
+
+ void mouseReleaseEvent (QMouseEvent *);
+ void mousePressEvent (QMouseEvent *);
+ void keyReleaseEvent ( QKeyEvent * e );
+// void paintEvent ( QPaintEvent * );
+
+ void destroyChildWidgets();
+// virtual void closeEvent ( QCloseEvent * e );
+
+private:
+ int type;
+ KPopupMenu *menu;
+ KRootPixmap *rootpix;
+};
+
+#endif
diff --git a/src/komposegldesktopwidget.cpp b/src/komposegldesktopwidget.cpp
new file mode 100644
index 0000000..2c33135
--- /dev/null
+++ b/src/komposegldesktopwidget.cpp
@@ -0,0 +1,116 @@
+//
+// C++ Implementation: komposegldesktopwidget
+//
+// Description:
+//
+//
+// Author: Hans Oischinger <[email protected]>, (C) 2004
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#include "komposegldesktopwidget.h"
+
+#include "komposetask.h"
+#include "komposegltaskwidget.h"
+#include "komposetaskmanager.h"
+
+#include <qdesktopwidget.h>
+#include <qobjectlist.h>
+#include <kdebug.h>
+
+#include <GL/gl.h>
+
+KomposeGLDesktopWidget::KomposeGLDesktopWidget(int desktop, QObject *parent, const char *name)
+ : KomposeGLWidget( parent ),
+ deskNum( desktop )
+{
+ // Retrieve geometry
+ QDesktopWidget *deskwidget = new QDesktopWidget();
+ deskRect = deskwidget->availableGeometry();
+ delete deskwidget;
+
+ createTaskWidgets();
+
+ //connect( KomposeTaskManager::instance(), SIGNAL( newTask( KomposeTask* ) ), this, SLOT( createTaskWidget( KomposeTask* ) ) );
+}
+
+
+KomposeGLDesktopWidget::~KomposeGLDesktopWidget()
+{}
+
+void KomposeGLDesktopWidget::createTaskWidgets()
+{
+ TaskList tl = KomposeTaskManager::instance()->getTasks();
+ qDebug("KomposeGLDesktopWidget::createTaskWidgets() on %d tasks", tl.count());
+ QPtrListIterator<KomposeTask> it( tl );
+ KomposeTask *task;
+ while ( (task = it.current()) != 0 )
+ {
+ ++it;
+ Q_CHECK_PTR(task);
+ createTaskWidget( task );
+ }
+}
+
+
+void KomposeGLDesktopWidget::createTaskWidget( KomposeTask* task )
+{
+ if (deskNum == task->onDesktop()-1 )
+ {
+ qDebug("KomposeGLDesktopWidget::createTaskWidget()" );
+ KomposeGLTaskWidget *taskwidget = new KomposeGLTaskWidget( task, this, 0, "" );
+ }
+}
+
+int KomposeGLDesktopWidget::getHeightForWidth( int w ) const
+{
+ qDebug("KomposeGLDesktopWidget::getHeightForWidth()");
+ return ((double)w / (double)deskRect.width()) * deskRect.height();
+}
+
+int KomposeGLDesktopWidget::getWidthForHeight( int h ) const
+{
+ qDebug("KomposeGLDesktopWidget::getWidthForHeight()");
+ return ((double)h / (double)deskRect.height()) * deskRect.width();
+}
+
+double KomposeGLDesktopWidget::getAspectRatio()
+{
+ qDebug("KomposeGLDesktopWidget::getAspectRatio()");
+ return (double)deskRect.width() / (double)deskRect.height();
+}
+
+
+void KomposeGLDesktopWidget::draw()
+{
+ KomposeGLWidget::draw();
+ qDebug("KomposeGLDesktopWidget::draw() - %d,%d %dx%d", getRect().x(), getRect().y(), getRect().width(), getRect().height());
+ glColor3f(0.0f, 0.0f, 1.0f);
+
+ glBegin( GL_QUADS );
+ glVertex2i( getRect().x() + getRect().width(), getRect().y() );
+ glVertex2i( getRect().x(), getRect().y() );
+ glVertex2i( getRect().x(), getRect().y() + getRect().height() );
+ glVertex2i( getRect().x() + getRect().width(), getRect().y() + getRect().height() );
+ glEnd();
+
+ // Draw Task Widgets
+ QPtrListIterator<KomposeGLWidget> it( list );
+
+ // Check or empty list
+ if (it.count() == 0)
+ {
+ qDebug("KomposeGLDesktopWidget::draw() - empty list... skipping!");
+ return;
+ }
+
+ KomposeGLWidget *widget;
+ while ( (widget = (KomposeGLWidget*)it.current()) != 0 )
+ {
+ ++it;
+ widget->draw();
+ }
+}
+
+#include "komposegldesktopwidget.moc"
diff --git a/src/komposeglfullscreenwidget.cpp b/src/komposeglfullscreenwidget.cpp
new file mode 100644
index 0000000..095a1de
--- /dev/null
+++ b/src/komposeglfullscreenwidget.cpp
@@ -0,0 +1,176 @@
+//
+// C++ Implementation: komposeglwidget
+//
+// Description:
+//
+//
+// Author: Hans Oischinger <[email protected]>, (C) 2004
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#include "komposeglfullscreenwidget.h"
+
+#include "komposelayout.h"
+#include "komposetaskmanager.h"
+#include "komposegldesktopwidget.h"
+#include <kdebug.h>
+
+#include <GL/gl.h>
+#include <GL/glut.h>
+
+KomposeGLFullscreenWidget::KomposeGLFullscreenWidget(QWidget *parent, const char *name) :
+ QGLWidget(parent, name)
+{
+ qDebug("KomposeGLFullscreenWidget::KomposeGLFullscreenWidget()");
+ layout = new KomposeLayout( this );
+
+ setWindowState(Qt::WindowMaximized | Qt::WindowActive);
+ showFullScreen();
+
+ createDesktopWidgets();
+}
+
+
+KomposeGLFullscreenWidget::~KomposeGLFullscreenWidget()
+{}
+
+void KomposeGLFullscreenWidget::createDesktopWidgets()
+{
+ // Create a Widget for every desktop
+ for (int i=0; i < KomposeTaskManager::instance()->getNumDesktops(); ++i)
+ {
+ int row = i / 2;
+ int col = i % 2;
+ //qDebug("rc %d %d", row, col);
+ desktop[i] = new KomposeGLDesktopWidget(i, this);
+ layout->add(dynamic_cast<KomposeWidgetInterface*>(desktop[i]));
+ }
+}
+
+void KomposeGLFullscreenWidget::initializeGL()
+{
+ // Set up the rendering context, define display lists etc.:
+ if( !format().hasOpenGL() )
+ {
+ qWarning( "KomposeGLFullscreenWidget::initializeGL() - OpenGL not supported!" );
+ return;
+ }
+
+ if ( !format().doubleBuffer() )
+ {
+ qWarning( "KomposeGLFullscreenWidget::initializeGL() - Direct rendering enabled !" );
+ }
+// glShadeModel(GL_SMOOTH);
+//
+// format().setDirectRendering( true );
+// format().setDoubleBuffer( true );
+// format().setRgba( true );
+// format().setDepth ( false );
+// format().setAccum( false );
+// format().setStencil( false );
+// format().setAlpha( true );
+
+ // Alpha blend
+// glEnable( GL_BLEND );
+// glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
+
+ // All smoothing stuff
+// glEnable( GL_POLYGON_SMOOTH );
+// glHint( GL_POLYGON_SMOOTH_HINT, GL_FASTEST );
+// glEnable( GL_POINT_SMOOTH );
+// glHint( GL_POINT_SMOOTH_HINT, GL_FASTEST );
+// glEnable( GL_LINE_SMOOTH );
+// glHint( GL_LINE_SMOOTH_HINT, GL_FASTEST );
+
+ // Lighting and Depth Test
+ glDisable( GL_LIGHTING );
+// glDisable( GL_DEPTH_TEST );
+// glDisable( GL_NORMALIZE );
+
+ glClearColor( 0.0, 0.0, 0.0, 0.0 );
+ glClear( GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_ACCUM_BUFFER_BIT );
+
+ /*! Setup sizes */
+// glLineWidth( 1.0 );
+// glPointSize( 2.0 );
+
+ setOrthographicProjection();
+}
+
+void KomposeGLFullscreenWidget::resizeGL( int w, int h )
+{
+ // setup viewport, projection etc.:
+ setOrthographicProjection();
+ layout->arrangeLayout();
+}
+
+
+/*! draw OpenGL scene ( called from Qt ) */
+void KomposeGLFullscreenWidget::paintGL()
+{
+ qDebug("KomposeGLFullscreenWidget::paintGL()");
+
+ glPushMatrix();
+
+ // clears the color buffer (this will set the window to black)
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ // Draw Desktop Widgets
+ for (int i=0; i < KomposeTaskManager::instance()->getNumDesktops(); ++i)
+ {
+ // FIXME: Make desktop arrays dynamic or at least avoid KomposeTaskManager::instance()->getNumDesktops() here
+ desktop[i]->draw();
+ }
+
+ glFlush();
+ glPopMatrix();
+}
+
+
+void KomposeGLFullscreenWidget::setOrthographicProjection()
+{
+ qDebug("KomposeGLFullscreenWidget::setOrthographicProjection() - %dx%d", width(), height());
+ glViewport( 0, 0, (GLint)width(), (GLint)height() );
+ // switch to projection mode
+ glMatrixMode(GL_PROJECTION);
+ // reset matrix
+ glLoadIdentity();
+ // set a 2D orthographic projection
+ gluOrtho2D(0.0, (GLdouble)width(), 0.0, (GLdouble)height());
+ // invert the y axis, down is positive
+ glScalef(1, -1, 1);
+ // mover the origin from the bottom left corner
+ // to the upper left corner
+ glTranslatef(0, -height(), 0);
+ glMatrixMode(GL_MODELVIEW);;
+}
+
+// Redirect these functions to QGLWidget
+
+void KomposeGLFullscreenWidget::setGeom ( const QRect &rect )
+{
+ QGLWidget::setGeometry( rect );
+}
+
+void KomposeGLFullscreenWidget::setGeom ( const QSize &size )
+{
+ QGLWidget::resize( size );
+}
+
+QSize KomposeGLFullscreenWidget::getSize() const
+{
+ return QGLWidget::size();
+}
+
+QRect KomposeGLFullscreenWidget::getRect() const
+{
+ return QGLWidget::rect();
+}
+
+void KomposeGLFullscreenWidget::removeChildWidget( KomposeWidgetInterface* obj )
+{
+ QGLWidget::removeChild((QObject *) obj);
+}
+
+#include "komposeglfullscreenwidget.moc"
diff --git a/src/komposeglobal.cpp b/src/komposeglobal.cpp
new file mode 100644
index 0000000..a03b1d4
--- /dev/null
+++ b/src/komposeglobal.cpp
@@ -0,0 +1,375 @@
+//
+// C++ Implementation: komposeglobal
+//
+// Description:
+//
+//
+// Author: Hans Oischinger <[email protected]>, (C) 2004
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#include "komposeglobal.h"
+
+
+#include "komposetaskmanager.h"
+#include "komposeviewmanager.h"
+#include "komposesettings.h"
+#include "komposesystray.h"
+
+#include <qtimer.h>
+
+#include <kapplication.h>
+#include <kpopupmenu.h>
+#include <kaction.h>
+#include <kactioncollection.h>
+#include <klocale.h>
+#include <kiconloader.h>
+#include <kaccel.h>
+#include <kkeydialog.h>
+#include <kaboutapplication.h>
+#include <ksharedpixmap.h>
+#include <kwinmodule.h>
+#include <kdebug.h>
+#include <dcopclient.h>
+#include <dcopref.h>
+
+#include <dcopclient.h>
+
+// #include those AFTER Qt-includes!
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <Imlib2.h>
+
+#ifdef COMPOSITE
+#include <X11/Xatom.h>
+#include <X11/extensions/Xcomposite.h>
+#include <X11/extensions/Xdamage.h>
+#include <X11/extensions/Xrender.h>
+#endif
+
+static KomposeGlobal* globalInstance = 0;
+Display *disp;
+
+static QString wallpaperForDesktop(int desktop)
+{
+ return DCOPRef("kdesktop", "KBackgroundIface").call("currentWallpaper", desktop);
+}
+
+/**
+ * KomposeSettings is a singleton
+ */
+KomposeGlobal* KomposeGlobal::instance()
+{
+ if ( !globalInstance )
+ {
+ kdDebug() << "KomposeSettings::instance() - Creating Singleton instance" << endl;
+ KomposeGlobal *settiglobalInstance = new KomposeGlobal();
+ }
+ return globalInstance;
+}
+
+KomposeGlobal::KomposeGlobal(QObject *parent, const char *name)
+ : QObject(parent, name),
+ aboutDialogOpen(0),
+ hideSystray( false ),
+ singleShot( false ),
+ xcomposite(0),
+ damageEvent(0)
+{
+ globalInstance = this;
+ kwin_module = new KWinModule(); //FIXME: only needed for sharedpixmap :(
+ currentDesktop = kwin_module->currentDesktop();
+
+ desktopBgPixmap = new KSharedPixmap;
+ connect(desktopBgPixmap, SIGNAL(done(bool)), SLOT(slotDone(bool)));
+ initSharedPixmaps();
+ initCompositeExt();
+ initImlib();
+
+ connect( KomposeSettings::instance(), SIGNAL(settingsChanged()), this, SLOT(slotConfigChanged()) );
+}
+
+KomposeGlobal::~KomposeGlobal()
+{
+ delete systray;
+ delete actionCollection;
+ delete actConfigGlobalShortcuts;
+ delete actPreferencesDialog;
+ delete actShowVirtualDesktopView;
+ delete actShowCurrentDesktopView;
+ delete actShowWorldView;
+ delete actAboutDlg;
+ delete actQuit;
+ delete desktopBgPixmap;
+}
+
+void KomposeGlobal::slotConfigChanged( )
+{
+ initCompositeExt();
+}
+
+/**
+ * Gives us control about when the GUI should appear. Called from outside
+ * Called from outside as KomposeGlobal is a singleton that can be instantiated at any time
+ */
+void KomposeGlobal::initGui()
+{
+ // Initialise the Singleton instances
+ KomposeSettings::instance();
+ KomposeViewManager::instance();
+ KomposeTaskManager::instance();
+
+ // Create DCop Client
+ kapp->dcopClient()->setDefaultObject( "KomposeTaskMgrDcopIface" );
+
+ initActions();
+
+ if ( !hideSystray && !singleShot )
+ {
+ // Create systray
+ systray = new KomposeSysTray();
+ kapp->setMainWidget( systray );
+ systray->currentDesktopChanged( currentDesktop );
+
+ actionCollection->setWidget( systray );
+ systray->show();
+ }
+ else
+ kdDebug() << "KomposeGlobal::initGui() - Hiding systray icon" << endl;
+
+ if ( singleShot )
+ {
+ kdDebug() << "KomposeGlobal::initGui() - SingleShot has been selected" << endl;
+ KomposeViewManager::instance()->createView();
+ }
+}
+
+
+/**
+ * Initialise Kompose's global actions. Retrieve these via the getters in KomposeGlobal
+ */
+void KomposeGlobal::initActions()
+{
+ actionCollection = new KActionCollection( (QWidget*)0 );
+
+ // Actions
+ actQuit = KStdAction::quit( kapp, SLOT(quit()), actionCollection );
+ actShowWorldView = new KAction(i18n("Komposé (ungrouped)"), "kompose_ungrouped",
+ 0,
+ KomposeViewManager::instance(), SLOT(createWorldView()),
+ actionCollection, "showWorldView");
+ actShowVirtualDesktopView = new KAction(i18n("Komposé (grouped by virtual desktops)"), "kompose_grouped_by_virtual_desktop",
+ 0,
+ KomposeViewManager::instance(), SLOT(createVirtualDesktopView()),
+ actionCollection, "showVirtualDesktopView");
+ actShowCurrentDesktopView = new KAction(i18n("Komposé (current virtual desktop)"), "kompose_current_virtual_desktop",
+ 0,
+ KomposeViewManager::instance(), SLOT(createCurrentDesktopView()),
+ actionCollection, "showCurrentDesktopView");
+
+ actPreferencesDialog = KStdAction::preferences( KomposeSettings::instance(), SLOT(showPreferencesDlg()), actionCollection );
+
+ actConfigGlobalShortcuts = KStdAction::keyBindings(this, SLOT(showGlobalShortcutsSettingsDialog()),
+ actionCollection, "options_configure_global_keybinding");
+ actConfigGlobalShortcuts->setText(i18n("Configure &Global Shortcuts..."));
+ actAboutDlg = new KAction(i18n("About Komposé"), "kompose",
+ 0,
+ this, SLOT(showAboutDlg()),
+ actionCollection, "showAboutDlg");
+}
+
+void KomposeGlobal::initSharedPixmaps()
+{
+ // Whenever the background pixmap changes we'll have to reload it:
+ //connect(kwin_module, SIGNAL(windowChanged(WId, unsigned int)), SLOT(desktopChanged(WId, unsigned int)));
+ connect(kwin_module, SIGNAL(currentDesktopChanged(int)), SLOT(slotDesktopChanged(int)));
+ connect(kapp, SIGNAL(backgroundChanged(int)), SLOT(slotBackgroundChanged(int)));
+
+ enablePixmapExports();
+ // When Kompose is started by session management the bg shared pixmap may not be available yet
+ if (!desktopBgPixmap->isAvailable( pixmapName(1) ))
+ {
+ qWarning("KomposeGlobal::initSharedPixmaps() - Pixmap not available");
+ //enablePixmapExports();
+ QTimer::singleShot( 1000, this, SLOT( initSharedPixmaps() ) );
+ //initSharedPixmaps();
+ //return;
+ }
+
+ kdDebug() << "KomposeGlobal::initSharedPixmaps()" << endl;
+ refreshSharedPixmaps();
+}
+
+void KomposeGlobal::slotDesktopChanged(int desktop)
+{
+ systray->currentDesktopChanged( desktop );
+ if (desktop != -2)
+ {
+ // -2 is for manual loading, everything else enables the following checks:
+ if (wallpaperForDesktop(currentDesktop) == wallpaperForDesktop(desktop) &&
+ !wallpaperForDesktop(currentDesktop).isNull())
+ return;
+
+ if ( !(pixmapName(currentDesktop) != pixmapName(desktop)) )
+ return;
+ }
+
+ currentDesktop = kwin_module->currentDesktop();
+ refreshSharedPixmaps();
+}
+
+void KomposeGlobal::slotBackgroundChanged(int)
+{
+ refreshSharedPixmaps();
+}
+
+void KomposeGlobal::refreshSharedPixmaps()
+{
+ desktopBgPixmap->loadFromShared( pixmapName(currentDesktop) );
+}
+
+QString KomposeGlobal::pixmapName(int desk)
+{
+ // To simplify things we take the background of the first desktop
+ QString pattern = QString("DESKTOP%1");
+ int screen_number = DefaultScreen(qt_xdisplay());
+ if (screen_number)
+ {
+ pattern = QString("SCREEN%1-DESKTOP").arg(screen_number) + "%1";
+ }
+ return pattern.arg( desk );
+}
+
+void KomposeGlobal::slotDone(bool success)
+{
+ if (!success)
+ {
+ kdDebug() << "KomposeGlobal::slotDone() - loading of desktop background failed.\n" << endl;
+ //QTimer::singleShot( 1000, this, SLOT( initSharedPixmaps() ) );
+ }
+}
+
+void KomposeGlobal::enablePixmapExports()
+{
+#ifdef Q_WS_X11
+ kdDebug() << "KomposeGlobal::enablePixmapExports()" << endl;
+ DCOPClient *client = kapp->dcopClient();
+ if (!client->isAttached())
+ client->attach();
+ QByteArray data;
+ QDataStream args( data, IO_WriteOnly );
+ args << 1;
+
+ QCString appname( "kdesktop" );
+ int screen_number = DefaultScreen(qt_xdisplay());
+ if ( screen_number )
+ appname.sprintf("kdesktop-screen-%d", screen_number );
+
+ client->send( appname, "KBackgroundIface", "setExport(int)", data );
+#endif
+}
+
+/**
+ * Show Global Shortcuts Dialog for Kompose
+ */
+void KomposeGlobal::showGlobalShortcutsSettingsDialog()
+{
+ KKeyDialog::configure( KomposeSettings::instance()->getGlobalAccel() );
+ KomposeSettings::instance()->writeConfig();
+}
+
+/**
+ * Show About Dialog for Kompose
+ */
+void KomposeGlobal::showAboutDlg()
+{
+ aboutDialogOpen = true;
+ KAboutApplication* kabout = new KAboutApplication();
+ kabout->exec();
+ delete kabout;
+ aboutDialogOpen = false;
+}
+
+/**
+ * Initialise Imlib2.
+ * Should only be called by the KomposeGlobal constructor
+ */
+void KomposeGlobal::initImlib()
+{
+ Display *disp;
+ Visual *vis;
+ Colormap cm;
+ //int screen;
+ disp = QPaintDevice::x11AppDisplay();
+ vis = DefaultVisual(disp, DefaultScreen(disp));
+ cm = DefaultColormap(disp, DefaultScreen(disp));
+ // context = imlib_context_new();
+
+ // imlib_context_push(d->context);
+ imlib_set_cache_size(0);
+ imlib_set_color_usage(128);
+ imlib_context_set_dither(1);
+ imlib_context_set_display(disp);
+ imlib_context_set_visual(vis);
+ imlib_context_set_colormap(cm);
+ kdDebug() << "KomposeGlobal::initImlib() - Imlib2 support enabled." << endl;
+}
+
+/**
+ * Detect and initialise the XComposite extension.
+ * Should only be called by the KomposeGlobal constructor
+ */
+void KomposeGlobal::initCompositeExt()
+{
+ if ( !(!xcomposite && KomposeSettings::instance()->getUseComposite()) )
+ return;
+
+ xcomposite = false;
+#ifdef COMPOSITE
+ // Check for XComposite
+ Display *dpy = QPaintDevice::x11AppDisplay();
+
+ int event_base, error_base;
+ if ( XCompositeQueryExtension( dpy, &event_base, &error_base ) )
+ {
+ // If we get here the server supports the extension
+ xcomposite = true;
+
+ // XComposite version check
+ int major = 1, minor = 1; // The highest version we support
+ XCompositeQueryVersion( dpy, &major, &minor );
+ // major and minor will now contain the version the server supports.
+ if (!(major > 0 || minor >= 2))
+ {
+ kdDebug() << "KomposeGlobal::initCompositeExt() - XComposite doesn't allow NamePixmap requests! - Disabling XComposite support" << endl;
+ // TODO: create a namewindowpixbool to make it work with composite 0.1
+ xcomposite = false;
+ }
+
+ // XRender version check
+ int renderEvent, renderError;
+ if (!XRenderQueryExtension (dpy, &renderEvent, &renderError))
+ {
+ kdDebug() << "KomposeGlobal::initCompositeExt() - XRender not available! - Disabling XComposite support" << endl;
+ }
+
+ //XDamage version check
+ //int damageEvent, damageError; // The event base is important here
+ if (!XDamageQueryExtension( dpy, &damageEvent, &damageError ))
+ {
+ kdDebug() << "KomposeGlobal::initCompositeExt() - XDamage is not available! - Disabling XComposite support" << endl;
+ xcomposite = false;
+ }
+
+ }
+ else
+ xcomposite = false;
+#endif
+
+ if ( xcomposite )
+ kdDebug() << "KomposeGlobal::initCompositeExt() - XComposite extension found and enabled." << endl;
+}
+
+
+#include "komposeglobal.moc"
diff --git a/src/komposeglobal.h b/src/komposeglobal.h
new file mode 100644
index 0000000..de39dab
--- /dev/null
+++ b/src/komposeglobal.h
@@ -0,0 +1,109 @@
+//
+// C++ Interface: komposeglobal
+//
+// Description:
+//
+//
+// Author: Hans Oischinger <[email protected]>, (C) 2004
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#ifndef KOMPOSEGLOBAL_H
+#define KOMPOSEGLOBAL_H
+
+class KomposeSysTray;
+
+#include <qobject.h>
+#include <qstring.h>
+
+class KPopupMenu;
+class KActionCollection;
+class KAction;
+class KSharedPixmap;
+class KWinModule;
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#if defined(Q_WS_X11) && defined(HAVE_XCOMPOSITE) && defined(HAVE_XDAMAGE) && QT_VERSION >= 0x030300
+# define COMPOSITE
+#endif
+
+/**
+@author Hans Oischinger
+*/
+class KomposeGlobal : public QObject
+{
+ Q_OBJECT
+protected:
+ KomposeGlobal(QObject *parent = 0, const char *name = 0);
+
+ ~KomposeGlobal();
+
+public:
+ static KomposeGlobal *instance();
+ KomposeSysTray* getSysTray() { return systray; }
+ void initGui();
+
+ bool hasAboutDialogOpen() { return aboutDialogOpen; }
+ void setHideSystray( bool b ) { hideSystray = b; }
+ void setSingleShot( bool b ) { singleShot = b; }
+ bool getSingleShot() { return singleShot; }
+ bool hasXcomposite() { return xcomposite; }
+ int getDamageEvent() { return damageEvent; }
+
+ // Action getters
+ KAction *getActConfigGlobalShortcuts() { return actConfigGlobalShortcuts; }
+ KAction *getActPreferencesDialog() { return actPreferencesDialog; }
+ KAction *getActShowVirtualDesktopView() { return actShowVirtualDesktopView; }
+ KAction *getActShowCurrentDesktopView() { return actShowCurrentDesktopView; }
+ KAction *getActShowWorldView() { return actShowWorldView; }
+ KAction *getActAboutDlg() { return actAboutDlg; }
+ KAction *getActQuit() { return actQuit; }
+
+ const KSharedPixmap *getDesktopBgPixmap() const { return desktopBgPixmap; }
+
+protected:
+ void initActions();
+ void initImlib();
+
+protected slots:
+ void initSharedPixmaps();
+ QString pixmapName(int desk);
+ void slotDone(bool success);
+ void enablePixmapExports();
+ void slotDesktopChanged(int desktop);
+ void slotBackgroundChanged(int desktop);
+ void refreshSharedPixmaps();
+
+ void slotConfigChanged();
+ void initCompositeExt();
+ void showGlobalShortcutsSettingsDialog();
+ void showAboutDlg();
+
+private:
+ bool aboutDialogOpen;
+ bool hideSystray;
+ bool singleShot;
+ bool xcomposite;
+ int damageEvent, damageError;
+
+ KSharedPixmap *desktopBgPixmap;
+ int currentDesktop;
+ KomposeSysTray* systray;
+ KActionCollection* actionCollection;
+
+ KAction *actConfigGlobalShortcuts;
+ KAction *actPreferencesDialog;
+ KAction *actShowVirtualDesktopView;
+ KAction *actShowCurrentDesktopView;
+ KAction *actShowWorldView;
+ KAction *actAboutDlg;
+ KAction *actQuit;
+
+ KWinModule* kwin_module;
+};
+
+#endif
diff --git a/src/komposegltaskwidget.cpp b/src/komposegltaskwidget.cpp
new file mode 100644
index 0000000..69e1927
--- /dev/null
+++ b/src/komposegltaskwidget.cpp
@@ -0,0 +1,119 @@
+//
+// C++ Implementation: komposegltaskwidget
+//
+// Description:
+//
+//
+// Author: Hans Oischinger <[email protected]>, (C) 2004
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#include "komposegltaskwidget.h"
+
+#include "komposetaskmanager.h"
+#include "komposetask.h"
+#include "komposelayout.h"
+#include <kdebug.h>
+
+#include <qgl.h>
+#include <qimage.h>
+
+
+
+KomposeGLTaskWidget::KomposeGLTaskWidget(KomposeTask *t, QObject *parent, KomposeLayout *l, const char *name)
+ : KomposeGLWidget(parent, l),
+ task(t)
+{
+ QImage img = task->getScreenshot().convertToImage();
+ img = img.smoothScale( 256, 256, QImage::ScaleMin );
+ tex = QGLWidget::convertToGLFormat( img );
+ glGenTextures(1, &texture);
+ glBindTexture(GL_TEXTURE_2D, texture);
+ /* glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); // cheap scaling when image bigger than texture
+ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); // cheap scaling when image smalled than texture*/
+ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); // scale linearly when image bigger than texture
+ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); // scale linearly when image smalled than texture
+
+ glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
+
+ glTexImage2D( GL_TEXTURE_2D, 0, 3, 256, 256, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, tex.bits() );
+
+
+
+
+ connect( t, SIGNAL( closed() ), this, SLOT( slotTaskDestroyed() ) );
+ connect( t, SIGNAL( stateChanged() ), this, SLOT( draw() ) );
+}
+
+
+KomposeGLTaskWidget::~KomposeGLTaskWidget()
+{}
+
+void KomposeGLTaskWidget::slotTaskDestroyed()
+{
+ disconnect( task, SIGNAL( closed() ), this, SLOT( slotTaskDestroyed() ) );
+ disconnect( task, SIGNAL( stateChanged() ), this, SLOT( draw() ) );
+ if (KomposeTaskManager::instance()->hasActiveView())
+ {
+ this->parent()->removeChild( this );
+ }
+}
+
+int KomposeGLTaskWidget::getHeightForWidth ( int w ) const
+{
+ qDebug("KomposeGLTaskWidget::getHeightForWidth()");
+ return task->getHeightForWidth(w);
+}
+
+int KomposeGLTaskWidget::getWidthForHeight ( int h ) const
+{
+ qDebug("KomposeGLTaskWidget::getWidthForHeight()");
+ return task->getWidthForHeight(h);
+}
+
+double KomposeGLTaskWidget::getAspectRatio()
+{
+ qDebug("KomposeGLTaskWidget::getAspectRatio()");
+ return task->getAspectRatio();
+}
+
+void KomposeGLTaskWidget::draw()
+{
+ KomposeGLWidget::draw();
+ qDebug("KomposeGLTaskWidget::draw() - %d,%d %dx%d", getRect().x(), getRect().y(), getRect().width(), getRect().height());
+ glColor3f(1.0f, 0.0f, 0.0f);
+
+ glBindTexture(GL_TEXTURE_2D, texture);
+
+ /* glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+ glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );*/
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
+ glEnable( GL_TEXTURE_2D );
+
+ // glTexImage2D( GL_TEXTURE_2D, 0, 3, tex.width(), tex.height(), 0,
+ // GL_RGBA, GL_UNSIGNED_BYTE, tex.bits() );
+ // qDebug("KomposeGLTaskWidget::draw() - tex: %dx%d", tex.width(), tex.height() );
+
+ glBegin( GL_QUADS );
+ glTexCoord2f(0.0, 0.0);
+ glVertex2i( getRect().x(), getRect().y() );
+ glTexCoord2f(0.0, 1.0);
+ glVertex2i( getRect().x(), getRect().y() + getRect().height() );
+ glTexCoord2f(1.0, 1.0);
+ glVertex2i( getRect().x() + getRect().width(), getRect().y() + getRect().height() );
+ glTexCoord2f(1.0, 0.0);
+ glVertex2i( getRect().x() + getRect().width(), getRect().y() );
+ glEnd();
+
+ glDisable( GL_TEXTURE_2D );
+/*
+glRasterPos2i (getRect().x(), getRect().y());
+ glPixelZoom( (GLfloat)(getSize().width())/(GLfloat)(tex.width()), (GLfloat)(getSize().height())/(GLfloat)(tex.height()) );
+ glDrawPixels(tex.width(), tex.height(), GL_RGBA, GL_UNSIGNED_BYTE, tex.bits() ); */
+}
+
+#include "komposegltaskwidget.moc"
diff --git a/src/komposeglwidget.cpp b/src/komposeglwidget.cpp
new file mode 100644
index 0000000..5ce4cff
--- /dev/null
+++ b/src/komposeglwidget.cpp
@@ -0,0 +1,119 @@
+/***************************************************************************
+ * Copyright (C) 2004 by Hans Oischinger *
+ * *
+ * 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 "komposeglwidget.h"
+#include "komposelayout.h"
+
+#include <qtimer.h>
+#include <kdebug.h>
+
+
+/*
+ * The constructor accepts a custom layout, if none is specified a defaultlayout is used
+ */
+KomposeGLWidget::KomposeGLWidget(QObject *parent, KomposeLayout *l, const char *name)
+ : QObject(parent)
+{
+ geometry = QRect(0,0,1,1);
+ if (!l)
+ layout = new KomposeLayout( this );
+ else
+ layout = l;
+}
+
+
+KomposeGLWidget::~KomposeGLWidget()
+{}
+
+
+/*
+ * Whenever a child is added to the widget it's also added to the layout
+ */
+void KomposeGLWidget::childEvent ( QChildEvent * ce )
+{
+ if ( !ce->child()->inherits("KomposeGLWidget") )
+ return;
+
+ if ( ce->inserted() )
+ {
+ qDebug("KomposeGLWidget::childEvent : Added widget " << ce->child()->className() << " to " << className() << endl;
+ list.append( dynamic_cast<KomposeGLWidget*>(ce->child()) );
+ layout->add( dynamic_cast<KomposeWidgetInterface*>(ce->child()) );
+ }
+ else if ( ce->removed() )
+ {
+ qDebug("KomposeGLWidget::childEvent : Removed widget %s from %s", ce->child()->className(), className() );
+ list.remove( dynamic_cast<KomposeGLWidget*>(ce->child()) );
+ layout->remove( dynamic_cast<KomposeWidgetInterface*>(ce->child()) );
+ }
+
+ // Whenever a child is added/removed: rearrange layout
+ // FIXME: sometimes widget's aren't added in time, so we have to add a short delay:
+ QTimer::singleShot( 200, layout, SLOT( arrangeLayout() ) );
+}
+
+/*
+ * Main GL draw routine
+ */
+void KomposeGLWidget::draw()
+{
+ qDebug("KomposeGLWidget::draw - Arranging layout");
+ layout->arrangeLayout();
+}
+
+
+// Redirect these functions to QWidget
+
+void KomposeGLWidget::setGeom ( const QRect &rect )
+{
+ geometry = rect;
+}
+
+void KomposeGLWidget::setGeom ( const QSize &size )
+{
+ geometry.setSize( size );
+}
+
+QSize KomposeGLWidget::getSize() const
+{
+ return geometry.size();
+}
+
+QRect KomposeGLWidget::getRect() const
+{
+ return geometry;
+}
+
+KomposeWidgetInterface* KomposeGLWidget::getParentWidget() const
+{
+ if ( QObject::parent()->inherits("KomposeWidgetInterface") )
+ return (KomposeWidgetInterface*)QObject::parent();
+ else
+ {
+ qDebug("KomposeGLWidget::getParentWidget() - QWidget::parent() does not inherit (KomposeWidgetInterface)");
+ return NULL;
+ }
+}
+
+void KomposeGLWidget::removeChildWidget( KomposeWidgetInterface* obj )
+{
+ QObject::removeChild((QObject *) obj);
+}
+
+#include "komposeglwidget.moc"
diff --git a/src/komposeimage.cpp b/src/komposeimage.cpp
new file mode 100644
index 0000000..c542796
--- /dev/null
+++ b/src/komposeimage.cpp
@@ -0,0 +1,256 @@
+//
+// C++ Implementation: komposeimage
+//
+// Description:
+//
+//
+// Author: Hans Oischinger <[email protected]>, (C) 2004
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#include "komposeimage.h"
+#include "komposesettings.h"
+#include <kdebug.h>
+
+
+
+KomposeImage::KomposeImage( Imlib_Image& im )
+ : QObject( 0L, 0L ),
+ bhasImage(true),
+ bhasSourcePixmap(false),
+ lasteffect( IEFFECT_NONE ),
+ myWidth(-1),
+ myHeight(-1)
+{
+ myIm = im;
+ imlib_context_set_image( myIm );
+ myWidth = imlib_image_get_width();
+ myHeight = imlib_image_get_height();
+ myIsDirty = true;
+
+ init();
+}
+
+
+KomposeImage::KomposeImage()
+ : QObject( 0L, 0L ),
+ bhasImage(false),
+ bhasSourcePixmap(false),
+ lasteffect( IEFFECT_NONE ),
+ myWidth(-1),
+ myHeight(-1)
+{
+ myIsDirty = false;
+ init();
+}
+
+KomposeImage::~KomposeImage()
+{
+ clearCached();
+}
+
+/*
+ * Call this function when the Imlib image and the qpixmap that is drawn is not needed anymore
+ * (normally when Kompos� view is closed)
+ */
+void KomposeImage::clearCached()
+{
+ if ( bhasSourcePixmap && bhasImage)
+ {
+ // Delete image as it takes a lot of ram
+ bhasImage = false;
+ imlib_context_set_image( myIm );
+ imlib_free_image();
+ }
+
+ if ( !KomposeSettings::instance()->getCacheScaledPixmaps() )
+ {
+ myQPixmap.resize(0,0);
+ myIsDirty = true;
+ }
+}
+
+void KomposeImage::init()
+{
+ myOrigWidth = myWidth;
+ myOrigHeight = myHeight;
+
+ myQPixmap.setOptimization( QPixmap::BestOptim );
+
+ // Create highlight color modifier
+ cmHighlight = imlib_create_color_modifier();
+ imlib_context_set_color_modifier(cmHighlight);
+ imlib_modify_color_modifier_brightness(0.13);
+
+ cmMinimized = imlib_create_color_modifier();
+ imlib_context_set_color_modifier(cmMinimized);
+ imlib_modify_color_modifier_brightness(-0.13);
+ imlib_context_set_color_modifier(0);
+}
+
+void KomposeImage::setImage( Imlib_Image &im )
+{
+ if (bhasImage)
+ {
+ imlib_context_set_image( myIm );
+ imlib_free_image();
+ }
+
+ myIm = im;
+ if ( !bhasSourcePixmap ) // SourcePixmap overrides Image
+ {
+ imlib_context_set_image( myIm );
+ myOrigWidth = imlib_image_get_width();
+ myOrigHeight = imlib_image_get_height();
+ qDebug("KomposeTask::setImage() - Set Image: size:" << myWidth << "x" << myHeight << endl;
+ }
+
+ myIsDirty = true;
+ bhasImage = true;
+}
+
+void KomposeImage::setImage( QPixmap &pm )
+{
+ mySourceQPixmap = pm;
+ bhasSourcePixmap = true;
+
+ myOrigWidth = pm.width();
+ myOrigHeight = pm.height();
+
+ myIsDirty = true;
+}
+
+void KomposeImage::createImageFromPixmap()
+{
+ if ( !bhasSourcePixmap )
+ return;
+
+ qDebug("KomposeImage::createImageFromPixmap()");
+ imlib_context_set_drawable( mySourceQPixmap.handle() );
+
+ if ( !KomposeSettings::instance()->getImageEffects() )
+ {
+ Imlib_Image img = imlib_create_image_from_drawable((Pixmap)0, 0, 0, mySourceQPixmap.width(), mySourceQPixmap.height(), 1);
+
+ setImage( img );
+ }
+ else
+ {
+ Imlib_Image imgOrig = imlib_create_image_from_drawable((Pixmap)0, 0, 0, mySourceQPixmap.width(), mySourceQPixmap.height(), 1);
+
+ imlib_context_set_anti_alias(1);
+
+ imlib_context_set_image( imgOrig );
+ Imlib_Image img = imlib_create_cropped_scaled_image(0, 0, mySourceQPixmap.width(), mySourceQPixmap.height(), myWidth, myHeight);
+ imlib_free_image();
+
+ setImage( img );
+ }
+}
+
+void KomposeImage::resize( int width, int height )
+{
+ if ( myWidth == width && myHeight == height )
+ return;
+
+ if (bhasImage)
+ {
+ bhasImage = false;
+ imlib_context_set_image( myIm );
+ imlib_free_image();
+ }
+
+ myWidth = width;
+ myHeight = height;
+ myIsDirty = true;
+}
+
+QPixmap* KomposeImage::qpixmap( int effect )
+{
+ if ( KomposeSettings::instance()->getImageEffects() && (lasteffect != effect ) )
+ {
+ myIsDirty = true;
+ lasteffect = effect;
+ }
+
+ if ( myIsDirty)
+ renderPixmap();
+
+ return &myQPixmap;
+}
+
+
+void KomposeImage::renderPixmap()
+{
+ // Is image dirty? has a width been set?
+ if ( !myIsDirty || myWidth==-1 )
+ return;
+
+ emit startRendering();
+
+ if ( !bhasImage && bhasSourcePixmap )
+ createImageFromPixmap();
+ else if ( !bhasImage && !bhasSourcePixmap )
+ return;
+
+ qDebug("KomposeImage::renderPixmap() - Creating %dx%d pixmap", myWidth, myHeight);
+
+ imlib_context_set_image( myIm );
+ imlib_image_set_has_alpha(0);
+
+ if ( KomposeSettings::instance()->getImageEffects() )
+ applyEffect();
+
+ myQPixmap.resize( myWidth, myHeight);
+
+ imlib_context_set_drawable(myQPixmap.handle());
+ imlib_context_set_anti_alias(1);
+ imlib_render_image_on_drawable_at_size(0, 0, myWidth, myHeight);
+
+ emit stoppedRendering();
+
+ myIsDirty = false;
+}
+
+void KomposeImage::applyEffect()
+{
+ imlib_context_set_color_modifier(0);
+
+ if ( lasteffect == IEFFECT_MINIMIZED || lasteffect == IEFFECT_MINIMIZED_AND_TITLE )
+ {
+ //FIXME: maybe there is a faster tint filter?!
+ imlib_context_set_color_modifier(cmMinimized);
+ }
+
+ if ( lasteffect == IEFFECT_HIGHLIGHT )
+ {
+ //FIXME: maybe there is a faster tint filter?!
+ imlib_context_set_color_modifier(cmHighlight);
+ }
+
+ if ( lasteffect == IEFFECT_TITLE || lasteffect == IEFFECT_MINIMIZED_AND_TITLE )
+ {
+ /* we can blend stuff now */
+ imlib_context_set_blend(1);
+ /* our color range */
+ Imlib_Color_Range range;
+
+ /* draw a gradient on top of things at the top left of the window */
+ /* create a range */
+ range = imlib_create_color_range();
+ imlib_context_set_color_range(range);
+ imlib_context_set_color(255, 255, 255, 0);
+ imlib_add_color_to_color_range(0);
+ imlib_context_set_color(255, 255, 255, 255);
+ imlib_add_color_to_color_range(1000);
+ /* draw the range */
+ imlib_context_set_image(myIm);
+ imlib_image_fill_color_range_rectangle(0, 0, myWidth, KomposeSettings::instance()->getWindowTitleFontAscent() * 3, -180.0);
+ /* free it */
+ imlib_free_color_range();
+ }
+
+}
+
+#include "komposeimage.moc"
diff --git a/src/komposeimage.h b/src/komposeimage.h
new file mode 100644
index 0000000..3fa5c25
--- /dev/null
+++ b/src/komposeimage.h
@@ -0,0 +1,87 @@
+//
+// C++ Interface: komposeimage
+//
+// Description:
+//
+//
+// Author: Hans Oischinger <[email protected]>, (C) 2004
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#ifndef KOMPOSEIMAGE_H
+#define KOMPOSEIMAGE_H
+
+#include <qobject.h>
+#include <qstring.h>
+#include <qpixmap.h>
+
+// #include those AFTER Qt-includes!
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <Imlib2.h>
+
+enum ImageEffect { IEFFECT_NONE, IEFFECT_TITLE, IEFFECT_MINIMIZED, IEFFECT_MINIMIZED_AND_TITLE, IEFFECT_HIGHLIGHT };
+
+/**
+@author Hans Oischinger
+*/
+class KomposeImage : public QObject
+{
+ Q_OBJECT
+
+public:
+ KomposeImage( Imlib_Image &im );
+ KomposeImage();
+ ~KomposeImage();
+
+ int width() const { return myWidth; }
+ int height() const { return myHeight; }
+ int originalWidth() const { return myOrigWidth; }
+ int originalHeight() const { return myOrigHeight; }
+
+ void resize( int width, int height );
+
+ QPixmap* qpixmap( int effect );
+ void renderPixmap();
+
+ void setDirty( bool d ) { myIsDirty = d; }
+ bool isDirty() const { return myIsDirty; }
+ bool isValid() { return bhasImage || bhasSourcePixmap; }
+ bool hasImage() { return bhasImage; }
+ void setImage( Imlib_Image &im );
+ void setImage( QPixmap &pm );
+
+public slots:
+ void clearCached();
+
+protected:
+ void createImageFromPixmap();
+ void applyEffect();
+ void init();
+
+private:
+ int myWidth;
+ int myHeight;
+
+ Imlib_Image myIm;
+ QPixmap myQPixmap;
+ QPixmap mySourceQPixmap;
+
+ Imlib_Color_Modifier cmHighlight, cmMinimized;
+
+ bool myIsDirty;
+ bool bhasImage;
+ bool bhasSourcePixmap;
+
+ int myOrigWidth;
+ int myOrigHeight;
+
+ int lasteffect;
+
+signals:
+ void startRendering();
+ void stoppedRendering();
+};
+
+#endif
diff --git a/src/komposelayout.cpp b/src/komposelayout.cpp
new file mode 100644
index 0000000..5dfd1a9
--- /dev/null
+++ b/src/komposelayout.cpp
@@ -0,0 +1,426 @@
+/***************************************************************************
+ * Copyright (C) 2004 by Hans Oischinger *
+ * *
+ * 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 "komposelayout.h"
+
+#include "komposewidget.h"
+#include "komposeviewmanager.h"
+#include "komposetaskmanager.h"
+#include "komposefullscreenwidget.h"
+
+#include <math.h>
+
+#include <kwin.h>
+#include <kdebug.h>
+
+
+KomposeLayout::KomposeLayout( KomposeWidget *parent, int type, int dist, const char *name )
+ : QObject(parent, name),
+ spacing(dist),
+ widgetsChanged(false),
+ currentRows(0),
+ currentColumns(0),
+ parentWidget(parent)
+{
+ setType( type );
+ currentSize = QSize( 1, 1 );
+}
+
+KomposeLayout::~KomposeLayout()
+{}
+
+void KomposeLayout::setType( int t )
+{
+ if ( t == TLAYOUT_TASKCONTAINERS &&
+ !KomposeSettings::instance()->getDynamicVirtDeskLayout() )
+ t = TLAYOUT_GENERIC;
+ layoutType = t;
+}
+
+
+void KomposeLayout::add( KomposeWidget *w )
+{
+ //kdDebug() << "KomposeLayout::add()@%s - Added widget to layout", parent()->className());
+ //kdDebug() << "KomposeLayout::add() - Added widget to layout");
+ list.append( w );
+ widgetsChanged = true;
+}
+
+void KomposeLayout::remove( KomposeWidget *w )
+{
+ list.remove( w );
+ widgetsChanged = true;
+}
+
+
+void KomposeLayout::arrangeLayout()
+{
+ //kdDebug() << "KomposeLayout::arrangeLayout()");
+ rearrangeContents();
+}
+
+void KomposeLayout::rearrangeContents()
+{
+ // Check or empty list
+ if (list.count() == 0)
+ {
+ kdDebug() << "KomposeLayout::rearrangeContents() - empty list... skipping!" << endl;
+ return;
+ }
+
+
+ // Check for layout Type and do the work
+ if (layoutType==TLAYOUT_TASKCONTAINERS)
+ {
+ filledContainers.clear();
+ emptyContainers.clear();
+
+ // Check for empty containers
+ QPtrListIterator<KomposeWidget> it( list );
+ KomposeWidget *task;
+ while ( (task = it.current()) != 0 )
+ {
+ ++it;
+ KomposeTaskContainerWidget *containerTask = dynamic_cast<KomposeTaskContainerWidget*>(task);
+
+ if ( containerTask->getNumofChilds() > 0 )
+ {
+ filledContainers.append( containerTask );
+ }
+ else
+ {
+ emptyContainers.append( containerTask );
+ }
+ }
+
+ // Arrange filled containers
+ QRect filledRect( 0,
+ 0,
+ parentWidget->width(),
+ parentWidget->height() - ( 40 + 2*spacing ) );
+ // arrange the filled desktops taking 90% of the screen
+ rearrangeContents( filledRect, filledContainers );
+
+ // Arrange empty containers
+ QRect emptyRect( 0,
+ parentWidget->height() - ( 40 + 2*spacing ),
+ parentWidget->width(),
+ ( 40 + 2*spacing ) );
+ // arrange the empty widget in one row
+ rearrangeContents( emptyRect, emptyContainers, 1, -1, false );
+
+
+ }
+ else // default type (generic)
+ {
+ QRect availRect( 0,
+ 0,
+ parentWidget->width(),
+ parentWidget->height());
+ rearrangeContents( availRect, list );
+ }
+
+
+ currentSize = parentWidget->size();
+ widgetsChanged = false;
+}
+
+
+/**
+ * availRect specifies the size&pos of the contents
+ * Specify either rows or cols to set a fixed number of those (setting both won't work correctly)
+ */
+void KomposeLayout::rearrangeContents( const QRect& availRect, const QPtrList<KomposeWidget> widgets, int rows, int columns, bool setMemberRowsCols )
+{
+ // Check or empty list
+ if (widgets.count() == 0)
+ {
+ kdDebug() << "KomposeLayout::rearrangeContents() - empty list... skipping!" << endl;
+ return;
+ }
+
+ QPtrListIterator<KomposeWidget> it( widgets );
+
+ // Calculate grid's rows & cols
+ if ( rows != -1 ) // rows have been specified
+ {
+ columns = (int)ceil(widgets.count() / rows);
+ }
+ else if ( columns != -1 ) // columns have been specified
+ {
+ rows = (int)ceil(widgets.count() / columns);
+ }
+ else // neither rows nor cols have been specified
+ {
+ double parentRatio = (double)availRect.width() / (double)availRect.height();
+ // Use more columns than rows when parent's width > parent's height
+ if ( parentRatio > 1 )
+ {
+ columns = (int)ceil( sqrt(widgets.count()) );
+ rows = (int)ceil( (double)widgets.count() / (double)columns );
+ }
+ else
+ {
+ rows = (int)ceil( sqrt(widgets.count()) );
+ columns = (int)ceil( (double)widgets.count() / (double)rows );
+ }
+ }
+
+ kdDebug() << "KomposeLayout::rearrangeContents() - Relayouting " << widgets.count() << " child widgets with " << rows << " rows & " << columns << " columns" << endl;
+
+ // Calculate width & height
+ int w = (availRect.width() - (columns+1) * spacing ) / columns;
+ int h = (availRect.height() - (rows+1) * spacing ) / rows;
+
+ QValueList<QRect> geometryRects;
+ QValueList<int> maxRowHeights;
+ // Process rows
+ for ( int i=0; i<rows; ++i )
+ {
+ int xOffsetFromLastCol = 0;
+ int maxHeightInRow = 0;
+ // Process columns
+ for ( int j=0; j<columns; ++j )
+ {
+ KomposeWidget *task;
+
+ // Check for end of List
+ if ( (task = it.current()) == 0)
+ break;
+
+ // Calculate width and height of widget
+ double ratio = task->getAspectRatio();
+
+ int widgetw = 100;
+ int widgeth = 100;
+ int usableW = w;
+ int usableH = h;
+
+ // use width of two boxes if there is no right neighbour
+ if (it.atLast() && j!=columns-1)
+ {
+ usableW = 2*w;
+ }
+ ++it; // We need access to the neighbour in the following
+ // expand if right neighbour has ratio < 1
+ if (j!=columns-1 && it.current() && it.current()->getAspectRatio() < 1)
+ {
+ int addW = w - it.current()->getWidthForHeight(h);
+ if ( addW > 0 )
+ {
+ usableW = w + addW;
+ }
+ }
+
+ if ( ratio == -1 )
+ {
+ widgetw = w;
+ widgeth = h;
+ }
+ else
+ {
+ double widthForHeight = task->getWidthForHeight(usableH);
+ double heightForWidth = task->getHeightForWidth(usableW);
+ if ( (ratio >= 1.0 && heightForWidth <= usableH) ||
+ (ratio < 1.0 && widthForHeight > usableW) )
+ {
+ widgetw = usableW;
+ widgeth = (int)heightForWidth;
+ }
+ else if ( (ratio < 1.0 && widthForHeight <= usableW) ||
+ (ratio >= 1.0 && heightForWidth > usableH) )
+ {
+ widgeth = usableH;
+ widgetw = (int)widthForHeight;
+ }
+ }
+
+ // Set the Widget's size
+
+ int alignmentXoffset = 0;
+ int alignmentYoffset = 0;
+ if ( i==0 && h > widgeth )
+ alignmentYoffset = h - widgeth;
+ if ( j==0 && w > widgetw )
+ alignmentXoffset = w - widgetw;
+ QRect geom( availRect.x() + j * (w + spacing) + spacing + alignmentXoffset + xOffsetFromLastCol,
+ availRect.y() + i * (h + spacing) + spacing + alignmentYoffset,
+ widgetw, widgeth );
+ geometryRects.append(geom);
+
+ // Set the x offset for the next column
+ if (alignmentXoffset==0)
+ xOffsetFromLastCol += widgetw-w;
+ if (maxHeightInRow < widgeth)
+ maxHeightInRow = widgeth;
+ }
+ maxRowHeights.append(maxHeightInRow);
+ }
+
+ it.toFirst();
+ QValueList<QRect>::iterator geomIt = geometryRects.begin();
+ QValueList<int>::iterator maxRowHeightIt = maxRowHeights.begin();
+ int topOffset = 0;
+ for ( int i=0; i<rows; ++i )
+ {
+ // Process columns again
+ for ( int j=0; j<columns; ++j )
+ {
+ KomposeWidget *task;
+ if ( (task = it.current()) == 0)
+ break;
+
+ QRect geom = *geomIt;
+ geom.setY( geom.y() + topOffset );
+// geom.setHeight( geom.height() - topOffset );
+ task->setGeometry( geom );
+ kdDebug() << "KomposeLayout::rearrangeContents() - Put item " << task->className() << " at x: " << geom.x() << " y: " << geom.y() << " with size: " << geom.width() << "x" << geom.height() << endl;
+ ++geomIt;
+ ++it;
+ }
+ if ( *maxRowHeightIt-h > 0 )
+ topOffset += *maxRowHeightIt-h;
+ ++maxRowHeightIt;
+ }
+
+ // Sync cols/rows member vars to current cols/rows
+ if ( setMemberRowsCols )
+ {
+ currentRows = rows;
+ currentColumns = columns;
+ }
+}
+
+
+/*
+ * Search for neighbour (called from outside)
+ */
+KomposeWidget* KomposeLayout::getNeighbour( const KomposeWidget* widget, int direction, int wrap )
+{
+ kdDebug() << "KomposeLayout::getNeighbour() - Called with list.count: " << list.count() << endl;
+
+ if (layoutType==TLAYOUT_TASKCONTAINERS)
+ {
+ KomposeWidget* neighbour = 0;
+ if ( filledContainers.containsRef(widget) )
+ {
+ if ( ( neighbour = getNeighbour( filledContainers, widget, direction, WLAYOUT_HORIZONTAL ) ) == 0 )
+ return emptyContainers.first();
+ }
+ else if ( emptyContainers.containsRef(widget) )
+ {
+ if ( ( neighbour = getNeighbour( emptyContainers, widget, direction, WLAYOUT_HORIZONTAL ) ) == 0 )
+ if ( direction == DLAYOUT_TOP )
+ return filledContainers.last();
+ else
+ return filledContainers.first();
+ }
+ return neighbour;
+ }
+ else if (layoutType==TLAYOUT_GENERIC)
+ return getNeighbour( list, widget, direction, wrap );
+
+ kdDebug() << "KomposeLayout::getNeighbour() - this should never happen!" << endl;
+ return NULL;
+}
+
+
+/*
+ * Search for neighbour in the given list (called from inside)
+ */
+KomposeWidget* KomposeLayout::getNeighbour(
+ QPtrList<KomposeWidget> listToSearch,
+ const KomposeWidget* widget,
+ int direction,
+ int wrap )
+{
+ QPtrListIterator<KomposeWidget> it( listToSearch );
+
+ KomposeWidget *task;
+ KomposeWidget *neighbour;
+ int index = 0;
+
+ if (widget == 0)
+ {
+ kdDebug() << "KomposeLayout::getNeighbour() - NULL startWidget given. using first()" << endl;
+ return listToSearch.first();
+ }
+
+ while ( (task = it.current()) != 0 )
+ {
+ if ( task == widget )
+ {
+ switch ( direction )
+ {
+ case DLAYOUT_RIGHT:
+ ++it;
+ if ( (index)%currentColumns == currentColumns-1 || ( neighbour = it.current() ) == 0 )
+ {
+ if (wrap == WLAYOUT_HORIZONTAL || wrap == WLAYOUT_BOTH )
+ return listToSearch.at(index+1-currentColumns);
+ kdDebug() << "KomposeLayout::getNeighbour() - No valid neighbour available" << endl;
+ return NULL;
+ }
+ return neighbour;
+ case DLAYOUT_LEFT:
+ --it;
+ if ( index%currentColumns == 0 || ( neighbour = it.current() ) == 0 )
+ {
+ if (wrap == WLAYOUT_HORIZONTAL || wrap == WLAYOUT_BOTH )
+ if ( (uint)(index+currentColumns-1) < listToSearch.count() )
+ return listToSearch.at(index+currentColumns-1);
+ else
+ return listToSearch.last();
+ kdDebug() << "KomposeLayout::getNeighbour() - No valid neighbour available" << endl;
+ return NULL;
+ }
+ return neighbour;
+ case DLAYOUT_TOP:
+ if ( index < currentColumns || (neighbour = listToSearch.at( index - currentColumns )) == 0)
+ {
+ if (wrap == WLAYOUT_VERTICAL || wrap == WLAYOUT_BOTH )
+ if ( listToSearch.count()%currentColumns == 0 || listToSearch.count()%currentColumns > (uint)(index) )
+ return listToSearch.at( (currentRows-1)*currentColumns + index );
+ else
+ return listToSearch.at( (currentRows-2)*currentColumns + index );
+ kdDebug() << "KomposeLayout::getNeighbour() - No valid neighbour available" << endl;
+ return NULL;
+ }
+ return neighbour;
+ case DLAYOUT_BOTTOM:
+ if ( listToSearch.count() <= (uint)(index + currentColumns) || (neighbour = listToSearch.at( index + currentColumns )) == 0)
+ {
+ if (wrap == WLAYOUT_VERTICAL || wrap == WLAYOUT_BOTH )
+ return listToSearch.at( index%currentColumns );
+ kdDebug() << "KomposeLayout::getNeighbour() - No valid neighbour available" << endl;
+ return NULL;
+ }
+ return neighbour;
+ }
+ }
+ ++index;
+ ++it;
+ }
+
+ kdDebug() << "KomposeLayout::getNeighbour() - this should never happen!" << endl;
+ return NULL;
+}
+
+
+#include "komposelayout.moc"
diff --git a/src/komposelayout.h b/src/komposelayout.h
new file mode 100644
index 0000000..ebb94bb
--- /dev/null
+++ b/src/komposelayout.h
@@ -0,0 +1,95 @@
+/***************************************************************************
+ * Copyright (C) 2004 by Hans Oischinger *
+ * *
+ * 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. *
+ ***************************************************************************/
+#ifndef KOMPOSELAYOUT_H
+#define KOMPOSELAYOUT_H
+
+#include <qobject.h>
+#include <qptrlist.h>
+
+#include "komposewidget.h"
+
+class QRect;
+
+enum LayoutType { TLAYOUT_GENERIC, // layouts all KomposeWidget classes
+ TLAYOUT_TASKCONTAINERS // layouts containers only
+ };
+
+enum LayoutDirections { DLAYOUT_LEFT, DLAYOUT_RIGHT, DLAYOUT_TOP, DLAYOUT_BOTTOM };
+
+enum WrapDirections { WLAYOUT_NONE, WLAYOUT_HORIZONTAL, WLAYOUT_VERTICAL, WLAYOUT_BOTH };
+
+/**
+The main layout class.
+QLayout just didn't fit :(
+
+@author Hans Oischinger
+*/
+class KomposeLayout : public QObject
+{
+ Q_OBJECT
+public:
+ KomposeLayout( KomposeWidget *parent, int type = TLAYOUT_GENERIC, int dist = 10, const char *name = 0 );
+
+ ~KomposeLayout();
+
+ void add( KomposeWidget *w );
+ void remove( KomposeWidget *w );
+ void setType( int t );
+int getType() { return layoutType; }
+
+ const QPtrList<KomposeWidget> *getManagedWidgets() { return &list; }
+ int getNumofChilds() { return list.count(); }
+ KomposeWidget* getNeighbour( const KomposeWidget* widget,
+ int direction = DLAYOUT_RIGHT,
+ int wrap = WLAYOUT_NONE );
+
+public slots:
+ void arrangeLayout();
+
+protected:
+ KomposeWidget* getNeighbour( QPtrList<KomposeWidget> listToSearch,
+ const KomposeWidget* widget,
+ int direction = DLAYOUT_RIGHT,
+ int wrap = WLAYOUT_NONE );
+ void rearrangeContents();
+ void rearrangeContents( const QRect& availRect,
+ const QPtrList<KomposeWidget> widgets,
+ int rows = -1,
+ int columns = -1,
+ bool setMemberRowsCols = true );
+
+private:
+ // List of all managed childs
+ QPtrList<KomposeWidget> list;
+ // List of container childs seperated by empty/full
+ QPtrList<KomposeWidget> filledContainers;
+ QPtrList<KomposeWidget> emptyContainers;
+
+ QSize currentSize;
+ int layoutType;
+ int spacing;
+ bool widgetsChanged;
+ int currentRows;
+ int currentColumns;
+
+ KomposeWidget* parentWidget;
+};
+
+#endif
diff --git a/src/komposepreferences.cpp b/src/komposepreferences.cpp
new file mode 100644
index 0000000..45dd7f0
--- /dev/null
+++ b/src/komposepreferences.cpp
@@ -0,0 +1,411 @@
+//
+// C++ Implementation: komposepreferences
+//
+// Description:
+//
+//
+// Author: Hans Oischinger <[email protected]>, (C) 2004
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#include "komposepreferences.h"
+
+#include "komposesettings.h"
+#include "komposeglobal.h"
+
+#include <qlayout.h>
+#include <qcheckbox.h>
+#include <qlabel.h>
+#include <kapplication.h>
+#include <qwhatsthis.h>
+#include <qtooltip.h>
+#include <qspinbox.h>
+#include <qgroupbox.h>
+#include <qbuttongroup.h>
+#include <qhbox.h>
+#include <qslider.h>
+#include <qpushbutton.h>
+#include <qgrid.h>
+#include <qvgroupbox.h>
+#include <qradiobutton.h>
+
+#include <kiconloader.h>
+#include <kcolorbutton.h>
+#include <kfontdialog.h>
+
+KomposePreferences::KomposePreferences()
+ : KDialogBase(IconList, i18n("Komposé Preferences"), Ok|Apply|Cancel, Ok)
+{
+ // FIXME: this is the biggest constructor I've EVER written!
+ // How about Qt Designer?!
+ m_hasXinerama = QDesktopWidget().numScreens() > 1;
+
+ QFrame *page1 = addPage( i18n("Behavior"), QString::null, DesktopIcon("winprops", KIcon::SizeMedium) );
+ QFrame *page2 = addPage( i18n("Appearance"), QString::null, DesktopIcon("appearance", KIcon::SizeMedium) );
+ QFrame *page3 = addPage( i18n("Layouts"), QString::null, DesktopIcon("window_list", KIcon::SizeMedium) );
+
+ QVBoxLayout *page1Layout = new QVBoxLayout( page1, 0, KDialog::spacingHint() );
+
+ defaultViewBtnGroup = new QButtonGroup( 2, Horizontal, i18n("Default Layout"), page1 );
+ defaultViewBtnGroup->setExclusive( true );
+ QString defaultViewBtnGroupHelp = i18n("Determines which view should be started by default (e.g. when you click on the systray icon).");
+ QWhatsThis::add( defaultViewBtnGroup, defaultViewBtnGroupHelp );
+ QToolTip::add( defaultViewBtnGroup, defaultViewBtnGroupHelp );
+ defaultViewWorld = new QRadioButton(i18n("Ungrouped"), defaultViewBtnGroup );
+ QString defaultViewWorldHelp = i18n("Fullscreen layout that shows all windows in no specific order");
+ QWhatsThis::add( defaultViewWorld, defaultViewWorldHelp );
+ QToolTip::add( defaultViewWorld, defaultViewWorldHelp );
+ defaultViewVirtualDesks = new QRadioButton(i18n("Grouped by virtual desktops"), defaultViewBtnGroup );
+ QString defaultViewVirtualDesksHelp = i18n("Fullscreen layout that shows a representation of your virtual desktops\n and places the windows inside.");
+ QWhatsThis::add( defaultViewVirtualDesks, defaultViewVirtualDesksHelp );
+ QToolTip::add( defaultViewVirtualDesks, defaultViewVirtualDesksHelp );
+ defaultViewCurrentDesk = new QRadioButton(i18n("Current virtual desktop"), defaultViewBtnGroup );
+ QString defaultViewCurrentDeskHelp = i18n("Fullscreen layout that shows the windows of the desktop you're currently working on.");
+ QWhatsThis::add( defaultViewCurrentDesk, defaultViewCurrentDeskHelp );
+ QToolTip::add( defaultViewCurrentDesk, defaultViewCurrentDeskHelp );
+ page1Layout->addWidget(defaultViewBtnGroup);
+
+ if (m_hasXinerama)
+ {
+ QGroupBox *xineramaGroupBox = new QGroupBox( 2, Vertical, i18n("Xinerama"), page1 );
+
+ QDesktopWidget deskwidget;
+ m_viewScreenAll = new QCheckBox(i18n("Use the whole desktop for Komposé"), xineramaGroupBox);
+
+ QHBox *hLayXineramaGrabDelay = new QHBox(xineramaGroupBox);
+ QLabel *xineramaLabel = new QLabel(i18n("Use screen:"), hLayXineramaGrabDelay);
+ m_viewScreen = new QSpinBox(0, deskwidget.numScreens()-1, 1, hLayXineramaGrabDelay);
+ connect( m_viewScreenAll, SIGNAL(toggled(bool)), m_viewScreen, SLOT(setDisabled(bool)) );
+ xineramaLabel->setBuddy(m_viewScreen);
+ QString xineramaHelp = i18n("Specify the screen where Komposé should appear." );
+ QWhatsThis::add( m_viewScreen, xineramaHelp );
+ QToolTip::add( m_viewScreen, xineramaHelp );
+ QWhatsThis::add( xineramaLabel, xineramaHelp );
+ QToolTip::add( xineramaLabel, xineramaHelp );
+
+ page1Layout->addWidget(xineramaGroupBox);
+ }
+
+#ifdef COMPOSITE
+ QGroupBox *screenshotsGroupBox = new QGroupBox( 4, Vertical, i18n("Screenshots"), page1 );
+
+ useComposite = new QCheckBox(i18n("Use XComposite if available"), screenshotsGroupBox);
+ QString useCompositeHelp = i18n("Making use of the Composite extension of newer X Servers makes the grabbing of screenshots obsolete.\nThe contents of all windows are drawn in back buffers that will be accessed by Komposé\nNote that the Composite implementation of even modern graphic card drivers is still very slow and may make your system pretty unusable.");
+ QWhatsThis::add( useComposite, useCompositeHelp );
+ QToolTip::add( useComposite, useCompositeHelp );
+ connect( useComposite, SIGNAL(toggled(bool)), SLOT(setUseCompositeToggled(bool)) );
+#else
+ QGroupBox *screenshotsGroupBox = new QGroupBox( 3, Vertical, i18n("Screenshots"), page1 );
+#endif
+
+ passiveScreenshots = new QCheckBox(i18n("Passive screenshots"), screenshotsGroupBox);
+ QString passiveScreenshotsHelp = i18n("Create a screenshot whenever you raise or active a window.\nWhen selected the amount the annoying popup-effect before every Komposé activation will be minimized to nearly zero.\nThe drawback is that the screenshots are not so recent and may not display the actual content.");
+ QWhatsThis::add( passiveScreenshots, passiveScreenshotsHelp );
+ QToolTip::add( passiveScreenshots, passiveScreenshotsHelp );
+
+ QHBox *hLayScreenshotGrabDelay = new QHBox(screenshotsGroupBox);
+ QLabel *screenshotGrabDelayLabel = new QLabel(i18n("Delay between screenshots (ms):"), hLayScreenshotGrabDelay);
+ screenshotGrabDelay = new QSpinBox(0, 999, 10, hLayScreenshotGrabDelay);
+ screenshotGrabDelayLabel->setBuddy(screenshotGrabDelay);
+ QString screenshotGrabDelayHelp = i18n("Specifies the time to wait between the activation of a window and the screenshot taking.\nIncrease it when your windows need more time to draw themselves after activation.\nValues below 300ms are not recommended, but may work in some cases." );
+ QWhatsThis::add( screenshotGrabDelay, screenshotGrabDelayHelp );
+ QToolTip::add( screenshotGrabDelay, screenshotGrabDelayHelp );
+ QWhatsThis::add( screenshotGrabDelayLabel, screenshotGrabDelayHelp );
+ QToolTip::add( screenshotGrabDelayLabel, screenshotGrabDelayHelp );
+
+ cacheScaledPixmaps = new QCheckBox(i18n("Cache scaled Screenshots"), screenshotsGroupBox);
+ QString cacheScaledPixmapsHelp = i18n("This may avoid some scaling operations to be called repeatedly when Komposé has been displayed before and the screenshot's size didn't change.\nIt will however increase memory usage quite a bit.");
+ QWhatsThis::add( cacheScaledPixmaps, cacheScaledPixmapsHelp );
+ QToolTip::add( cacheScaledPixmaps, cacheScaledPixmapsHelp );
+
+ page1Layout->addWidget(screenshotsGroupBox);
+
+
+ // Autolock
+ QGroupBox* autoLockGroup = new QGroupBox( 0, Qt::Horizontal, i18n("Autoactivate when mouse moves into"), page1 );
+ QGridLayout* autoLockLayout = new QGridLayout( autoLockGroup->layout(), 5, 2, KDialog::spacingHint() );
+ m_topLeftCorner = new QCheckBox( i18n("Top-left corner"), autoLockGroup);
+ autoLockLayout->addWidget( m_topLeftCorner, 0, 0 );
+ m_topRightCorner = new QCheckBox( i18n("Top-right corner"), autoLockGroup );
+ autoLockLayout->addWidget( m_topRightCorner, 1, 0 );
+ m_bottomLeftCorner = new QCheckBox( i18n("Bottom-left corner"), autoLockGroup );
+ autoLockLayout->addWidget( m_bottomLeftCorner, 2, 0 );
+ m_bottomRightCorner = new QCheckBox( i18n("Bottom-right corner"), autoLockGroup );
+ autoLockLayout->addWidget( m_bottomRightCorner, 3, 0 );
+
+ m_topEdge = new QCheckBox( i18n("Top edge"), autoLockGroup);
+ autoLockLayout->addWidget( m_topEdge, 0, 1 );
+ m_bottomEdge = new QCheckBox( i18n("Bottom edge"), autoLockGroup );
+ autoLockLayout->addWidget( m_bottomEdge, 1, 1 );
+ m_leftEdge = new QCheckBox( i18n("Left edge"), autoLockGroup );
+ autoLockLayout->addWidget( m_leftEdge, 2, 1 );
+ m_rightEdge = new QCheckBox( i18n("Right edge"), autoLockGroup );
+ autoLockLayout->addWidget( m_rightEdge, 3, 1 );
+
+ QHBox *hLayAutoLockDelay = new QHBox(autoLockGroup);
+ QLabel *autoLockDelayLabel = new QLabel(i18n("Delay until activation (ms):"), hLayAutoLockDelay);
+ autoLockDelay = new QSpinBox(0, 5000, 10, hLayAutoLockDelay);
+ autoLockDelayLabel->setBuddy(autoLockDelay);
+ QString autoLockDelayHelp = i18n("Specifies the time in ms for which the mouse pointer must rest in the corner until auto-activation." );
+ QWhatsThis::add( autoLockDelay, autoLockDelayHelp );
+ QToolTip::add( autoLockDelay, autoLockDelayHelp );
+ QWhatsThis::add( autoLockDelayLabel, autoLockDelayHelp );
+ QToolTip::add( autoLockDelayLabel, autoLockDelayHelp );
+ autoLockLayout->addMultiCellWidget( hLayAutoLockDelay, 4, 4, 0, 1 );
+
+ page1Layout->addWidget(autoLockGroup);
+
+ page1Layout->insertStretch(-1);
+
+
+
+ QVBoxLayout *page2Layout = new QVBoxLayout( page2, 0, KDialog::spacingHint() );
+
+ imageEffects = new QCheckBox(i18n("Enable image effects"), page2);
+ QString imageEffectsHelp = i18n("Lighten windows when the mouse moves over it or gray out minimized windows.\nDepending on your system specs this can be a bit slower." );
+ QWhatsThis::add( imageEffects, imageEffectsHelp );
+ QToolTip::add( imageEffects, imageEffectsHelp );
+ page2Layout->addWidget(imageEffects);
+
+ showDesktopNum = new QCheckBox(i18n("Show Desktop number on Systray icon"), page2);
+ QString showDesktopNumHelp = i18n("Displays the number of the currently active Desktop on the Komposé systray icon." );
+ QWhatsThis::add( showDesktopNum, showDesktopNumHelp );
+ QToolTip::add( showDesktopNum, showDesktopNumHelp );
+ page2Layout->addWidget(showDesktopNum);
+
+ QGroupBox *windowTitleGroupBox = new QGroupBox( 3, Vertical, i18n("Window Titles"), page2 );
+
+ QHBox *hBoxWindowTitles = new QHBox(windowTitleGroupBox);
+ showWindowTitles = new QCheckBox(i18n("Show window titles"), hBoxWindowTitles);
+ windowTitleFontBtn = new QPushButton(i18n("Select Font..."), hBoxWindowTitles);
+ QString showWindowTitlesHelp = i18n( "Display the name of every window in Komposé" );
+ QWhatsThis::add( showWindowTitles, showWindowTitlesHelp );
+ QToolTip::add( showWindowTitles, showWindowTitlesHelp );
+ connect( showWindowTitles, SIGNAL(toggled(bool)), windowTitleFontBtn, SLOT(setEnabled(bool)) );
+ connect( windowTitleFontBtn, SIGNAL(clicked()), this, SLOT(showWindowTitleFontDialog()) );
+
+ QGrid *gridWindowTitlesColor = new QGrid(2, windowTitleGroupBox);
+ // windowTitleFontColorLabel = new QLabel(windowTitleFontColor, i18n("Text color: "), gridWindowTitlesColor); // FIXME: How to link to a buddy that doesn't yet exist?
+ windowTitleFontColorLabel = new QLabel(i18n("Text color:"), gridWindowTitlesColor);
+ windowTitleFontColor = new KColorButton(Qt::black, gridWindowTitlesColor);
+ connect( showWindowTitles, SIGNAL(toggled(bool)), windowTitleFontColorLabel, SLOT(setEnabled(bool)) );
+ connect( showWindowTitles, SIGNAL(toggled(bool)), windowTitleFontColor, SLOT(setEnabled(bool)) );
+ showWindowTitleShadow = new QCheckBox(i18n("Shadow color:"), gridWindowTitlesColor);
+ windowTitleFontShadowColor = new KColorButton(Qt::lightGray, gridWindowTitlesColor);
+ connect( showWindowTitles, SIGNAL(toggled(bool)), showWindowTitleShadow, SLOT(setEnabled(bool)) );
+ connect( showWindowTitles, SIGNAL(toggled(bool)), windowTitleFontShadowColor, SLOT(setEnabled(bool)) );
+ connect( showWindowTitleShadow, SIGNAL(toggled(bool)), windowTitleFontShadowColor, SLOT(setEnabled(bool)) );
+
+ page2Layout->addWidget(windowTitleGroupBox);
+
+
+
+ QGroupBox *iconGroupBox = new QGroupBox( 3, Vertical, i18n("Task Icons"), page2 );
+ showIcons = new QCheckBox(i18n("Show icons"), iconGroupBox);
+ iconSize = new QSlider(0, 3, 1, 0, Qt::Horizontal, iconGroupBox);
+ iconSizeDescription = new QLabel( iconSize, "", iconGroupBox);
+ connect( iconSize, SIGNAL( sliderMoved(int) ), this, SLOT( updateIconSliderDesc(int) ) );
+ connect( iconSize, SIGNAL( valueChanged(int) ), this, SLOT( updateIconSliderDesc(int) ) );
+ connect( showIcons, SIGNAL( toggled(bool) ), iconSize, SLOT( setEnabled(bool) ) );
+ connect( showIcons, SIGNAL( toggled(bool) ), iconSizeDescription, SLOT( setEnabled(bool) ) );
+ page2Layout->addWidget(iconGroupBox);
+
+ page2Layout->insertStretch(-1);
+
+
+
+ QVBoxLayout *page3Layout = new QVBoxLayout( page3, 0, KDialog::spacingHint() );
+
+ QVGroupBox *virtDesksLayoutGroupBox = new QVGroupBox( i18n("Grouped by Virtual Desktops"), page3 );
+ dynamicVirtDeskLayout = new QCheckBox(i18n("Layout empty virtual desktops minimized"), virtDesksLayoutGroupBox );
+ QString dynamicVirtDeskLayoutHelp = i18n("Check this if you want empty virtual desktops to take less space on the screen.\nUncheck it if you want them to be arranged statically, each of the same size.");
+ QWhatsThis::add( dynamicVirtDeskLayout, dynamicVirtDeskLayoutHelp );
+ QToolTip::add( dynamicVirtDeskLayout, dynamicVirtDeskLayoutHelp );
+
+ QGrid *desktopColorsGroupBox = new QGrid( 2, virtDesksLayoutGroupBox );
+ desktopColorsGroupBox->setSpacing( 4 );
+ desktopTitleFontColorLabel = new QLabel(i18n("Desktop frame color:"), desktopColorsGroupBox);
+ desktopTitleFontColor = new KColorButton(Qt::black, desktopColorsGroupBox);
+ desktopTitleFontHighlightColorLabel = new QLabel(i18n("Desktop frame highlight color:"), desktopColorsGroupBox);
+ desktopTitleFontHighlightColor = new KColorButton(Qt::black, desktopColorsGroupBox);
+
+ page3Layout->addWidget(virtDesksLayoutGroupBox);
+
+ desktopTitleFontBtn = new QPushButton(i18n("Select Desktop Names Font..."), virtDesksLayoutGroupBox);
+ connect( desktopTitleFontBtn, SIGNAL(clicked()), this, SLOT(showDesktopTitleFontDialog()) );
+
+ page3Layout->insertStretch(-1);
+
+
+ fillPages();
+}
+
+
+KomposePreferences::~KomposePreferences()
+{}
+
+void KomposePreferences::updateIconSliderDesc( int val )
+{
+ switch( val )
+ {
+ case 0:
+ iconSizeDescription->setText( i18n("16x16") );
+ break;
+ case 1:
+ iconSizeDescription->setText( i18n("32x32") );
+ break;
+ case 2:
+ iconSizeDescription->setText( i18n("64x64") );
+ break;
+ case 3:
+ iconSizeDescription->setText( i18n("Don't scale, show as they are (preferably bigger)") );
+ break;
+ }
+}
+
+void KomposePreferences::showWindowTitleFontDialog()
+{
+ KFontDialog::getFont( *windowTitleFont );
+ // if ( result == KFontDialog::Accepted )
+}
+
+void KomposePreferences::showDesktopTitleFontDialog()
+{
+ KFontDialog::getFont( *desktopTitleFont );
+}
+
+void KomposePreferences::fillPages()
+{
+ // Sync Settings to Preferences dialog
+ switch ( KomposeSettings::instance()->getDefaultView() )
+ {
+ case KOMPOSEDISPLAY_VIRTUALDESKS:
+ defaultViewVirtualDesks->setChecked( true );
+ break;
+ case KOMPOSEDISPLAY_WORLD:
+ defaultViewWorld->setChecked( true );
+ break;
+ case KOMPOSEDISPLAY_CURRENTDESK:
+ defaultViewCurrentDesk->setChecked( true );
+ break;
+ }
+
+#ifdef COMPOSITE
+ useComposite->setChecked( KomposeSettings::instance()->getUseComposite() );
+#endif
+ passiveScreenshots->setChecked( KomposeSettings::instance()->getPassiveScreenshots() );
+ screenshotGrabDelay->setValue( KomposeSettings::instance()->getScreenshotGrabDelay() / 1000000 );
+ cacheScaledPixmaps->setChecked( KomposeSettings::instance()->getCacheScaledPixmaps() );
+ dynamicVirtDeskLayout->setChecked( KomposeSettings::instance()->getDynamicVirtDeskLayout() );
+
+ imageEffects->setChecked( KomposeSettings::instance()->getImageEffects() );
+ showDesktopNum->setChecked( KomposeSettings::instance()->getShowDesktopNum() );
+
+ showWindowTitles->setChecked( KomposeSettings::instance()->getShowWindowTitles() );
+ windowTitleFont = new QFont(KomposeSettings::instance()->getWindowTitleFont());
+ windowTitleFontColor->setColor( KomposeSettings::instance()->getWindowTitleFontColor() );
+ windowTitleFontShadowColor->setColor( KomposeSettings::instance()->getWindowTitleFontShadowColor() );
+ showWindowTitleShadow->setChecked( KomposeSettings::instance()->getShowWindowTitleShadow() );
+ // Disable dependant widgets
+ windowTitleFontBtn->setEnabled( KomposeSettings::instance()->getShowWindowTitles() );
+ windowTitleFontColorLabel->setEnabled( KomposeSettings::instance()->getShowWindowTitles() );
+ windowTitleFontColor->setEnabled( KomposeSettings::instance()->getShowWindowTitles() );
+ showWindowTitleShadow->setEnabled( KomposeSettings::instance()->getShowWindowTitles() );
+ windowTitleFontShadowColor->setEnabled( KomposeSettings::instance()->getShowWindowTitles() || KomposeSettings::instance()->getShowWindowTitleShadow() );
+
+ desktopTitleFont = new QFont(KomposeSettings::instance()->getDesktopTitleFont());
+ desktopTitleFontColor->setColor( KomposeSettings::instance()->getDesktopTitleFontColor() );
+ desktopTitleFontHighlightColor->setColor( KomposeSettings::instance()->getDesktopTitleFontHighlightColor() );
+
+ showIcons->setChecked( KomposeSettings::instance()->getShowIcons() );
+ iconSize->setValue( KomposeSettings::instance()->getIconSize() );
+ iconSize->setEnabled( showIcons->isChecked() );
+ iconSizeDescription->setEnabled( showIcons->isChecked() );
+ updateIconSliderDesc( iconSize->value() );
+
+ m_topLeftCorner->setChecked( KomposeSettings::instance()->getActivateOnTopLeftCorner() );
+ m_bottomLeftCorner->setChecked( KomposeSettings::instance()->getActivateOnBottomLeftCorner() );
+ m_topRightCorner->setChecked( KomposeSettings::instance()->getActivateOnTopRightCorner() );
+ m_bottomRightCorner->setChecked( KomposeSettings::instance()->getActivateOnBottomRightCorner() );
+
+ m_topEdge->setChecked( KomposeSettings::instance()->getActivateOnTopEdge() );
+ m_bottomEdge->setChecked( KomposeSettings::instance()->getActivateOnBottomEdge() );
+ m_rightEdge->setChecked( KomposeSettings::instance()->getActivateOnRightEdge() );
+ m_leftEdge->setChecked( KomposeSettings::instance()->getActivateOnLeftEdge() );
+ autoLockDelay->setValue( KomposeSettings::instance()->getAutoLockDelay() );
+
+ if (m_hasXinerama)
+ {
+ m_viewScreenAll->setChecked( KomposeSettings::instance()->getViewScreen() == -1 );
+ if (KomposeSettings::instance()->getViewScreen() >= 0 )
+ m_viewScreen->setValue( KomposeSettings::instance()->getViewScreen() );
+ m_viewScreen->setDisabled( m_viewScreenAll->isChecked() );
+ }
+}
+
+
+
+
+void KomposePreferences::slotApply()
+{
+ KomposeSettings::instance()->setDefaultView( defaultViewBtnGroup->selectedId() );
+
+#ifdef COMPOSITE
+ KomposeSettings::instance()->setUseComposite( useComposite->isChecked() );
+#endif
+
+ KomposeSettings::instance()->setPassiveScreenshots( passiveScreenshots->isChecked() );
+ KomposeSettings::instance()->setScreenshotGrabDelay( screenshotGrabDelay->value() * 1000000 );
+ KomposeSettings::instance()->setCacheScaledPixmaps( cacheScaledPixmaps->isChecked() );
+ KomposeSettings::instance()->setDynamicVirtDeskLayout( dynamicVirtDeskLayout->isChecked() );
+ KomposeSettings::instance()->setImageEffects( imageEffects->isChecked() );
+ KomposeSettings::instance()->setShowDesktopNum( showDesktopNum->isChecked() );
+
+ KomposeSettings::instance()->setShowWindowTitles( showWindowTitles->isChecked() );
+ KomposeSettings::instance()->setWindowTitleFont( *windowTitleFont );
+ KomposeSettings::instance()->setWindowTitleFontColor( windowTitleFontColor->color() );
+ KomposeSettings::instance()->setWindowTitleFontShadowColor( windowTitleFontShadowColor->color() );
+ KomposeSettings::instance()->setShowWindowTitleShadow( showWindowTitleShadow->isChecked() );
+
+ KomposeSettings::instance()->setDesktopTitleFont( *desktopTitleFont );
+ KomposeSettings::instance()->setDesktopTitleFontColor( desktopTitleFontColor->color() );
+ KomposeSettings::instance()->setDesktopTitleFontHighlightColor( desktopTitleFontHighlightColor->color() );
+
+ KomposeSettings::instance()->setShowIcons( showIcons->isChecked() );
+ KomposeSettings::instance()->setIconSize( iconSize->value() );
+
+ KomposeSettings::instance()->setActivateOnTopLeftCorner( m_topLeftCorner->isChecked() );
+ KomposeSettings::instance()->setActivateOnTopRighCorner( m_topRightCorner->isChecked() );
+ KomposeSettings::instance()->setActivateOnBottomLeftCorner( m_bottomLeftCorner->isChecked() );
+ KomposeSettings::instance()->setActivateOnBottomRightCorner( m_bottomRightCorner->isChecked() );
+
+ KomposeSettings::instance()->setActivateOnTopEdge( m_topEdge->isChecked() );
+ KomposeSettings::instance()->setActivateOnRightEdge( m_rightEdge->isChecked() );
+ KomposeSettings::instance()->setActivateOnBottomEdge( m_bottomEdge->isChecked() );
+ KomposeSettings::instance()->setActivateOnLeftEdge( m_leftEdge->isChecked() );
+ KomposeSettings::instance()->setAutoLockDelay( autoLockDelay->value() );
+
+ if (m_hasXinerama)
+ {
+ int viewScreen = m_viewScreen->value();
+ if ( m_viewScreenAll->isChecked() )
+ viewScreen = -1;
+ KomposeSettings::instance()->setViewScreen( viewScreen );
+ }
+
+ KomposeSettings::instance()->writeConfig();
+
+ KDialogBase::slotApply();
+}
+
+void KomposePreferences::slotOk()
+{
+ slotApply();
+ KDialogBase::slotOk();
+}
+
+void KomposePreferences::setUseCompositeToggled( bool )
+{}
+
+#include "komposepreferences.moc"
diff --git a/src/komposepreferences.cpp.orig b/src/komposepreferences.cpp.orig
new file mode 100644
index 0000000..11ef084
--- /dev/null
+++ b/src/komposepreferences.cpp.orig
@@ -0,0 +1,291 @@
+//
+// C++ Implementation: komposepreferences
+//
+// Description:
+//
+//
+// Author: Hans Oischinger <[email protected]>, (C) 2004
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#include "komposepreferences.h"
+
+#include "komposesettings.h"
+
+#include <qlayout.h>
+#include <qcheckbox.h>
+#include <qlabel.h>
+#include <kapplication.h>
+#include <qwhatsthis.h>
+#include <qtooltip.h>
+#include <qspinbox.h>
+#include <qgroupbox.h>
+#include <qbuttongroup.h>
+#include <qhbox.h>
+#include <qslider.h>
+#include <qpushbutton.h>
+#include <qgrid.h>
+#include <qvgroupbox.h>
+#include <qradiobutton.h>
+
+#include <kiconloader.h>
+#include <kcolorbutton.h>
+#include <kfontdialog.h>
+
+KomposePreferences::KomposePreferences()
+ : KDialogBase(IconList, i18n(QString::fromUtf8("Komposé Preferences").utf8()), Ok|Apply|Cancel, Ok)
+{
+ QFrame *page1 = addPage( i18n("Behavior"), QString::null, DesktopIcon("winprops", KIcon::SizeMedium) );
+ QFrame *page2 = addPage( i18n("Appearance"), QString::null, DesktopIcon("appearance", KIcon::SizeMedium) );
+ QFrame *page3 = addPage( i18n("Layouts"), QString::null, DesktopIcon("window_list", KIcon::SizeMedium) );
+
+ QVBoxLayout *page1Layout = new QVBoxLayout( page1, 0, KDialog::spacingHint() );
+
+ defaultViewBtnGroup = new QButtonGroup( 2, Horizontal, i18n("Default Layout"), page1 );
+ defaultViewBtnGroup->setExclusive( true );
+ QString defaultViewBtnGroupHelp = i18n("Determines which view should be started by default (e.g. when you click on the systray icon).");
+ QWhatsThis::add( defaultViewBtnGroup, defaultViewBtnGroupHelp );
+ QToolTip::add( defaultViewBtnGroup, defaultViewBtnGroupHelp );
+ defaultViewWorld = new QRadioButton(i18n("Ungrouped"), defaultViewBtnGroup );
+ QString defaultViewWorldHelp = i18n("Fullscreen layout that shows all windows in no specific order");
+ QWhatsThis::add( defaultViewWorld, defaultViewWorldHelp );
+ QToolTip::add( defaultViewWorld, defaultViewWorldHelp );
+ defaultViewVirtualDesks = new QRadioButton(i18n("Grouped by virtual desktops"), defaultViewBtnGroup );
+ QString defaultViewVirtualDesksHelp = i18n("Fullscreen layout that shows a representation of your virtual desktops\n and places the windows inside.");
+ QWhatsThis::add( defaultViewVirtualDesks, defaultViewVirtualDesksHelp );
+ QToolTip::add( defaultViewVirtualDesks, defaultViewVirtualDesksHelp );
+ page1Layout->addWidget(defaultViewBtnGroup);
+
+
+ QGroupBox *screenshotsGroupBox = new QGroupBox( 3, Vertical, i18n("Screenshots"), page1 );
+
+ passiveScreenshots = new QCheckBox(i18n("Passive screenshots"), screenshotsGroupBox);
+ QString passiveScreenshotsHelp = i18n(QString::fromUtf8("Create a screenshot whenever you raise or active a window.\nWhen selected the amount the annoying popup-effect before every Komposé activation will be minimized to nearly zero.\nThe drawback is that the screenshots are not so recent and may not display the actual content.").utf8());
+ QWhatsThis::add( passiveScreenshots, passiveScreenshotsHelp );
+ QToolTip::add( passiveScreenshots, passiveScreenshotsHelp );
+
+ // onlyOneScreenshot = new QCheckBox(i18n("Only grab a screenshot when none exists"), screenshotsGroupBox);
+ // QString onlyOneScreenshotHelp = i18n("When disabled new screenshots will be taken whenever possible.\nEnabling will only create a screenshot once the application is first activated and will never update it.");
+ // QWhatsThis::add( onlyOneScreenshot, onlyOneScreenshotHelp );
+ // QToolTip::add( onlyOneScreenshot, onlyOneScreenshotHelp );
+
+ QHBox *hLayScreenshotGrabDelay = new QHBox(screenshotsGroupBox);
+ QLabel *screenshotGrabDelayLabel = new QLabel(i18n("Delay between screenshots (ms):"), hLayScreenshotGrabDelay);
+ screenshotGrabDelay = new QSpinBox(0, 2000, 1, hLayScreenshotGrabDelay);
+ screenshotGrabDelayLabel->setBuddy(screenshotGrabDelay);
+ QString screenshotGrabDelayHelp = i18n("Specifies the time to wait between the activation of a window and the screenshot taking.\nIncrease it when your windows need more time to draw themselves after activation.\nValues below 300ms are not recommended, but may work in some cases." );
+ QWhatsThis::add( screenshotGrabDelay, screenshotGrabDelayHelp );
+ QToolTip::add( screenshotGrabDelay, screenshotGrabDelayHelp );
+ QWhatsThis::add( screenshotGrabDelayLabel, screenshotGrabDelayHelp );
+ QToolTip::add( screenshotGrabDelayLabel, screenshotGrabDelayHelp );
+
+ page1Layout->addWidget(screenshotsGroupBox);
+
+ page1Layout->insertStretch(-1);
+
+
+
+ QVBoxLayout *page2Layout = new QVBoxLayout( page2, 0, KDialog::spacingHint() );
+
+ imageEffects = new QCheckBox(i18n("Enable image effects"), page2);
+ QString imageEffectsHelp = i18n("Lighten windows when the mouse moves over it or gray out minimized windows.\nDepending on your system specs this can be a bit slower." );
+ QWhatsThis::add( imageEffects, imageEffectsHelp );
+ QToolTip::add( imageEffects, imageEffectsHelp );
+ page2Layout->addWidget(imageEffects);
+
+
+ QGroupBox *windowTitleGroupBox = new QGroupBox( 3, Vertical, i18n("Window Titles"), page2 );
+
+ QHBox *hBoxWindowTitles = new QHBox(windowTitleGroupBox);
+ showWindowTitles = new QCheckBox(i18n("Show window titles"), hBoxWindowTitles);
+ windowTitleFontBtn = new QPushButton(i18n("Select Font..."), hBoxWindowTitles);
+ QString showWindowTitlesHelp = i18n( QString::fromUtf8("Display the name of every window in Komposé") );
+ QWhatsThis::add( showWindowTitles, showWindowTitlesHelp );
+ QToolTip::add( showWindowTitles, showWindowTitlesHelp );
+ connect( showWindowTitles, SIGNAL(toggled(bool)), windowTitleFontBtn, SLOT(setEnabled(bool)) );
+ connect( windowTitleFontBtn, SIGNAL(clicked()), this, SLOT(showWindowTitleFontDialog()) );
+
+ QGrid *gridWindowTitlesColor = new QGrid(2, windowTitleGroupBox);
+ // windowTitleFontColorLabel = new QLabel(windowTitleFontColor, i18n("Text color: "), gridWindowTitlesColor); // FIXME: How to link to a buddy that doesn't yet exist?
+ windowTitleFontColorLabel = new QLabel(i18n("Text color:"), gridWindowTitlesColor);
+ windowTitleFontColor = new KColorButton(Qt::black, gridWindowTitlesColor);
+ connect( showWindowTitles, SIGNAL(toggled(bool)), windowTitleFontColorLabel, SLOT(setEnabled(bool)) );
+ connect( showWindowTitles, SIGNAL(toggled(bool)), windowTitleFontColor, SLOT(setEnabled(bool)) );
+ showWindowTitleShadow = new QCheckBox(i18n("Shadow color:"), gridWindowTitlesColor);
+ windowTitleFontShadowColor = new KColorButton(Qt::lightGray, gridWindowTitlesColor);
+ connect( showWindowTitles, SIGNAL(toggled(bool)), showWindowTitleShadow, SLOT(setEnabled(bool)) );
+ connect( showWindowTitles, SIGNAL(toggled(bool)), windowTitleFontShadowColor, SLOT(setEnabled(bool)) );
+ connect( showWindowTitleShadow, SIGNAL(toggled(bool)), windowTitleFontShadowColor, SLOT(setEnabled(bool)) );
+
+ page2Layout->addWidget(windowTitleGroupBox);
+
+
+
+ QGroupBox *iconGroupBox = new QGroupBox( 3, Vertical, i18n("Task Icons"), page2 );
+ showIcons = new QCheckBox(i18n("Show icons"), iconGroupBox);
+ iconSize = new QSlider(0, 3, 1, 0, Qt::Horizontal, iconGroupBox);
+ iconSizeDescription = new QLabel( iconSize, "", iconGroupBox);
+ connect( iconSize, SIGNAL( sliderMoved(int) ), this, SLOT( updateIconSliderDesc(int) ) );
+ connect( iconSize, SIGNAL( valueChanged(int) ), this, SLOT( updateIconSliderDesc(int) ) );
+ connect( showIcons, SIGNAL( toggled(bool) ), iconSize, SLOT( setEnabled(bool) ) );
+ connect( showIcons, SIGNAL( toggled(bool) ), iconSizeDescription, SLOT( setEnabled(bool) ) );
+ page2Layout->addWidget(iconGroupBox);
+
+ page2Layout->insertStretch(-1);
+
+
+
+ QVBoxLayout *page3Layout = new QVBoxLayout( page3, 0, KDialog::spacingHint() );
+
+ QVGroupBox *virtDesksLayoutGroupBox = new QVGroupBox( i18n("Grouped by Virtual Desktops"), page3 );
+ dynamicVirtDeskLayout = new QCheckBox(i18n("Layout empty virtual desktops minimized"), virtDesksLayoutGroupBox );
+ QString dynamicVirtDeskLayoutHelp = i18n("Check this if you want empty virtual desktops to take less space on the screen.\nUncheck it if you want them to be arranged statically, each of the same size.");
+ QWhatsThis::add( dynamicVirtDeskLayout, dynamicVirtDeskLayoutHelp );
+ QToolTip::add( dynamicVirtDeskLayout, dynamicVirtDeskLayoutHelp );
+
+ QGrid *desktopColorsGroupBox = new QGrid( 2, virtDesksLayoutGroupBox );
+ desktopColorsGroupBox->setSpacing( 4 );
+ tintVirtDesks = new QCheckBox(i18n("Tint virtual desktop widgets:"), desktopColorsGroupBox);
+ tintVirtDesksColor = new KColorButton(Qt::blue, desktopColorsGroupBox);
+ QString tintVirtDesksHelp = i18n("Colorize the transparent background of the virtual desktop widgets" );
+ QWhatsThis::add( tintVirtDesks, tintVirtDesksHelp );
+ QToolTip::add( tintVirtDesks, tintVirtDesksHelp );
+ QWhatsThis::add( tintVirtDesksColor, tintVirtDesksHelp );
+ QToolTip::add( tintVirtDesksColor, tintVirtDesksHelp );
+ connect( tintVirtDesks, SIGNAL(toggled(bool)), tintVirtDesksColor, SLOT(setEnabled(bool)) );
+ desktopTitleFontColorLabel = new QLabel(i18n("Desktop frame color:"), desktopColorsGroupBox);
+ desktopTitleFontColor = new KColorButton(Qt::black, desktopColorsGroupBox);
+ desktopTitleFontHighlightColorLabel = new QLabel(i18n("Desktop frame highlight color:"), desktopColorsGroupBox);
+ desktopTitleFontHighlightColor = new KColorButton(Qt::black, desktopColorsGroupBox);
+
+ page3Layout->addWidget(virtDesksLayoutGroupBox);
+
+ desktopTitleFontBtn = new QPushButton(i18n("Select Desktop Names Font..."), virtDesksLayoutGroupBox);
+ connect( desktopTitleFontBtn, SIGNAL(clicked()), this, SLOT(showDesktopTitleFontDialog()) );
+
+ page3Layout->insertStretch(-1);
+
+
+ fillPages();
+}
+
+
+KomposePreferences::~KomposePreferences()
+{}
+
+void KomposePreferences::updateIconSliderDesc( int val )
+{
+ switch( val )
+ {
+ case 0:
+ iconSizeDescription->setText( i18n("16x16") );
+ break;
+ case 1:
+ iconSizeDescription->setText( i18n("32x32") );
+ break;
+ case 2:
+ iconSizeDescription->setText( i18n("64x64") );
+ break;
+ case 3:
+ iconSizeDescription->setText( i18n("Don't scale, show as they are (preferably bigger)") );
+ break;
+ }
+}
+
+void KomposePreferences::showWindowTitleFontDialog()
+{
+ KFontDialog::getFont( *windowTitleFont );
+ // if ( result == KFontDialog::Accepted )
+}
+
+void KomposePreferences::showDesktopTitleFontDialog()
+{
+ KFontDialog::getFont( *desktopTitleFont );
+}
+
+void KomposePreferences::fillPages()
+{
+ // Sync Settings to Preferences dialog
+ switch ( KomposeSettings::instance()->getDefaultView() )
+ {
+ case KOMPOSEDISPLAY_VIRTUALDESKS:
+ defaultViewVirtualDesks->setChecked( true );
+ break;
+ case KOMPOSEDISPLAY_WORLD:
+ defaultViewWorld->setChecked( true );
+ break;
+ }
+
+ passiveScreenshots->setChecked( KomposeSettings::instance()->getPassiveScreenshots() );
+ screenshotGrabDelay->setValue( KomposeSettings::instance()->getScreenshotGrabDelay() / 1000000 );
+ dynamicVirtDeskLayout->setChecked( KomposeSettings::instance()->getDynamicVirtDeskLayout() );
+
+ imageEffects->setChecked( KomposeSettings::instance()->getImageEffects() );
+ tintVirtDesks->setChecked( KomposeSettings::instance()->getTintVirtDesks() );
+ tintVirtDesksColor->setColor( KomposeSettings::instance()->getTintVirtDesksColor() );
+ tintVirtDesksColor->setEnabled( KomposeSettings::instance()->getTintVirtDesks() );
+
+ showWindowTitles->setChecked( KomposeSettings::instance()->getShowWindowTitles() );
+ windowTitleFont = new QFont(KomposeSettings::instance()->getWindowTitleFont());
+ windowTitleFontColor->setColor( KomposeSettings::instance()->getWindowTitleFontColor() );
+ windowTitleFontShadowColor->setColor( KomposeSettings::instance()->getWindowTitleFontShadowColor() );
+ showWindowTitleShadow->setChecked( KomposeSettings::instance()->getShowWindowTitleShadow() );
+ // Disable dependant widgets
+ windowTitleFontBtn->setEnabled( KomposeSettings::instance()->getShowWindowTitles() );
+ windowTitleFontColorLabel->setEnabled( KomposeSettings::instance()->getShowWindowTitles() );
+ windowTitleFontColor->setEnabled( KomposeSettings::instance()->getShowWindowTitles() );
+ showWindowTitleShadow->setEnabled( KomposeSettings::instance()->getShowWindowTitles() );
+ windowTitleFontShadowColor->setEnabled( KomposeSettings::instance()->getShowWindowTitles() || KomposeSettings::instance()->getShowWindowTitleShadow() );
+
+ desktopTitleFont = new QFont(KomposeSettings::instance()->getDesktopTitleFont());
+ desktopTitleFontColor->setColor( KomposeSettings::instance()->getDesktopTitleFontColor() );
+ desktopTitleFontHighlightColor->setColor( KomposeSettings::instance()->getDesktopTitleFontHighlightColor() );
+
+ showIcons->setChecked( KomposeSettings::instance()->getShowIcons() );
+ iconSize->setValue( KomposeSettings::instance()->getIconSize() );
+ iconSize->setEnabled( showIcons->isChecked() );
+ iconSizeDescription->setEnabled( showIcons->isChecked() );
+ updateIconSliderDesc( iconSize->value() );
+}
+
+
+
+
+void KomposePreferences::slotApply()
+{
+ KomposeSettings::instance()->setDefaultView( defaultViewBtnGroup->selectedId() );
+
+ KomposeSettings::instance()->setPassiveScreenshots( passiveScreenshots->isChecked() );
+ KomposeSettings::instance()->setScreenshotGrabDelay( screenshotGrabDelay->value() * 1000000 );
+ KomposeSettings::instance()->setDynamicVirtDeskLayout( dynamicVirtDeskLayout->isChecked() );
+ KomposeSettings::instance()->setImageEffects( imageEffects->isChecked() );
+ KomposeSettings::instance()->setTintVirtDesks( tintVirtDesks->isChecked() );
+ KomposeSettings::instance()->setTintVirtDesksColor( tintVirtDesksColor->color() );
+
+ KomposeSettings::instance()->setShowWindowTitles( showWindowTitles->isChecked() );
+ KomposeSettings::instance()->setWindowTitleFont( *windowTitleFont );
+ KomposeSettings::instance()->setWindowTitleFontColor( windowTitleFontColor->color() );
+ KomposeSettings::instance()->setWindowTitleFontShadowColor( windowTitleFontShadowColor->color() );
+ KomposeSettings::instance()->setShowWindowTitleShadow( showWindowTitleShadow->isChecked() );
+
+ KomposeSettings::instance()->setDesktopTitleFont( *desktopTitleFont );
+ KomposeSettings::instance()->setDesktopTitleFontColor( desktopTitleFontColor->color() );
+ KomposeSettings::instance()->setDesktopTitleFontHighlightColor( desktopTitleFontHighlightColor->color() );
+
+ KomposeSettings::instance()->setShowIcons( showIcons->isChecked() );
+ KomposeSettings::instance()->setIconSize( iconSize->value() );
+
+ KomposeSettings::instance()->writeConfig();
+
+ KDialogBase::slotApply();
+}
+
+void KomposePreferences::slotOk()
+{
+ slotApply();
+ KDialogBase::slotOk();
+}
+
+
+#include "komposepreferences.moc"
diff --git a/src/komposepreferences.h b/src/komposepreferences.h
new file mode 100644
index 0000000..f634bfc
--- /dev/null
+++ b/src/komposepreferences.h
@@ -0,0 +1,109 @@
+//
+// C++ Interface: komposepreferences
+//
+// Description:
+//
+//
+// Author: Hans Oischinger <[email protected]>, (C) 2004
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#ifndef KOMPOSEPREFERENCES_H
+#define KOMPOSEPREFERENCES_H
+
+#include <kdialogbase.h>
+
+#include <klocale.h>
+
+class QCheckBox;
+class QFrame;
+class QSpinBox;
+class KColorButton;
+class QButtonGroup;
+class QSlider;
+class QPushButton;
+class QFont;
+class QRadioButton;
+
+/**
+@author Hans Oischinger
+*/
+class KomposePreferences : public KDialogBase
+{
+ Q_OBJECT
+public:
+ KomposePreferences();
+
+ ~KomposePreferences();
+
+
+protected:
+ void fillPages();
+
+protected slots:
+ void slotApply();
+ void slotOk();
+ void updateIconSliderDesc( int );
+ void showDesktopTitleFontDialog();
+ void showWindowTitleFontDialog();
+ void setUseCompositeToggled( bool );
+
+private:
+ bool m_hasXinerama;
+ QFrame *page1;
+ QFrame *page2;
+
+ QButtonGroup *defaultViewBtnGroup;
+ QRadioButton *defaultViewWorld;
+ QRadioButton *defaultViewVirtualDesks;
+ QRadioButton *defaultViewCurrentDesk;
+
+ QCheckBox *useComposite;
+
+ QCheckBox *passiveScreenshots;
+ QCheckBox *dynamicVirtDeskLayout;
+ QCheckBox *cacheScaledPixmaps;
+
+ QCheckBox *imageEffects;
+
+ QSpinBox *screenshotGrabDelay;
+
+ QCheckBox *showIcons;
+ QSlider *iconSize;
+ QLabel *iconSizeDescription;
+
+ QCheckBox *showWindowTitles;
+ QPushButton *windowTitleFontBtn;
+ QFont *windowTitleFont;
+
+ KColorButton *windowTitleFontColor;
+ QCheckBox *showWindowTitleShadow;
+ KColorButton *windowTitleFontShadowColor;
+ QLabel *windowTitleFontColorLabel;
+
+ QPushButton *desktopTitleFontBtn;
+ QLabel *desktopTitleFontColorLabel;
+ QLabel *desktopTitleFontHighlightColorLabel;
+ KColorButton *desktopTitleFontColor;
+ KColorButton *desktopTitleFontHighlightColor;
+ QFont *desktopTitleFont;
+
+ QCheckBox *m_topLeftCorner;
+ QCheckBox *m_bottomLeftCorner;
+ QCheckBox *m_topRightCorner;
+ QCheckBox *m_bottomRightCorner;
+
+ QCheckBox *m_topEdge;
+ QCheckBox *m_bottomEdge;
+ QCheckBox *m_rightEdge;
+ QCheckBox *m_leftEdge;
+ QSpinBox *autoLockDelay;
+
+ QCheckBox *showDesktopNum;
+
+ QSpinBox *m_viewScreen;
+ QCheckBox *m_viewScreenAll;
+};
+
+#endif
diff --git a/src/komposesettings.cpp b/src/komposesettings.cpp
new file mode 100644
index 0000000..d1bacc6
--- /dev/null
+++ b/src/komposesettings.cpp
@@ -0,0 +1,235 @@
+//
+// C++ Implementation: komposesettings
+//
+// Description:
+//
+//
+// Author: Hans Oischinger <[email protected]>, (C) 2004
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#include "komposesettings.h"
+
+#include "komposeviewmanager.h"
+#include "komposetaskmanager.h"
+#include "komposepreferences.h"
+
+#include <qcolor.h>
+
+#include <kglobalaccel.h>
+#include <kapplication.h>
+#include <kconfig.h>
+#include <kglobal.h>
+#include <kiconloader.h>
+#include <kdebug.h>
+
+static KomposeSettings* settingsInstance = 0;
+
+
+/*
+ * KomposeSettings is a singleton
+ */
+KomposeSettings* KomposeSettings::instance()
+{
+ if ( !settingsInstance )
+ {
+ // kdDebug() << "KomposeSettings::instance() - Creating Singleton instance"); // FIXME: How can this apper multiple times??
+ settingsInstance = new KomposeSettings();
+ }
+ return settingsInstance;
+}
+
+
+KomposeSettings::KomposeSettings(QObject *parent, const char *name)
+ : QObject(parent, name),
+ dialogOpen(0),
+ windowTitleFontMetrics(0)
+{
+
+ // Init global shortcut object
+ globalAccel = new KGlobalAccel( this );
+ globalAccel->insert( "showDefaultView", i18n("Show Komposé (default view)"),
+ i18n("Displays the view you have configured as default"),
+ KKey::QtWIN+Key_Tab, KKey::QtWIN+CTRL+SHIFT+Key_Tab,
+ KomposeViewManager::instance(), SLOT(createDefaultView()) );
+ globalAccel->insert( "showWorldView", i18n("Show Komposé (ungrouped)"),
+ i18n("Displays all windows unsorted"),
+ CTRL+SHIFT+Key_J, KKey::QtWIN+CTRL+SHIFT+Key_J,
+ KomposeViewManager::instance(), SLOT(createWorldView()) );
+ globalAccel->insert( "showVirtualDesktopView", i18n("Show Komposé (grouped by virtual desktops)"),
+ i18n("Displays all windows sorted by virtual desktops"),
+ CTRL+SHIFT+Key_I, KKey::QtWIN+CTRL+SHIFT+Key_I,
+ KomposeViewManager::instance(), SLOT(createVirtualDesktopView()) );
+ globalAccel->insert( "showCurrentDesktopView", i18n("Show Komposé (current virtual desktop)"),
+ i18n("Displays all windows on the current desktop"),
+ CTRL+SHIFT+Key_K, KKey::QtWIN+CTRL+SHIFT+Key_K,
+ KomposeViewManager::instance(), SLOT(createCurrentDesktopView()) );
+
+ // read Settings from cfg file
+ readConfig();
+
+ settingsInstance = this;
+}
+
+
+KomposeSettings::~KomposeSettings()
+{
+ delete globalAccel;
+ delete settingsInstance;
+}
+
+
+void KomposeSettings::readConfig()
+{
+ kdDebug() << "KomposeSettings::readConfig()" << endl;
+ // Read Shortcut Settings from config
+ globalAccel->readSettings();
+ globalAccel->updateConnections();
+
+ kapp->config()->setGroup("Main window");
+
+ defaultView = kapp->config()->readNumEntry("defaultView", KOMPOSEDISPLAY_VIRTUALDESKS);
+
+ useComposite = kapp->config()->readBoolEntry("useComposite", false);
+
+ passiveScreenshots = kapp->config()->readBoolEntry("passiveScreenshots", true);
+ screenshotGrabDelay = kapp->config()->readNumEntry("screenshotGrabDelay", 400000000);
+
+ dynamicVirtDeskLayout = kapp->config()->readBoolEntry("dynamicVirtDeskLayout", true);
+
+ imageEffects = kapp->config()->readBoolEntry("imageEffects", true);
+
+ showIcons = kapp->config()->readBoolEntry("showIcons", true);
+ iconSize = kapp->config()->readNumEntry("iconSize", 3);
+
+ showWindowTitles = kapp->config()->readBoolEntry("showWindowTitles", true );
+ windowTitleFont = kapp->config()->readFontEntry("windowTitleFont", new QFont( "arial", 11, QFont::Bold ) );
+ windowTitleFontColor = kapp->config()->readColorEntry("windowTitleFontColor", new QColor(Qt::black) );
+ showWindowTitleShadow = kapp->config()->readBoolEntry("showWindowTitleShadow", true );
+ windowTitleFontShadowColor = kapp->config()->readColorEntry("windowTitleFontShadowColor", new QColor(Qt::lightGray) );
+
+ desktopTitleFont = kapp->config()->readFontEntry("desktopTitleFont", new QFont( "arial", 10 ) );
+ desktopTitleFontColor = kapp->config()->readColorEntry("desktopTitleFontColor", new QColor(Qt::gray) );
+ desktopTitleFontHighlightColor = kapp->config()->readColorEntry("desktopTitleFontHighlightColor", new QColor(Qt::black) );
+
+ cacheScaledPixmaps = kapp->config()->readBoolEntry("cacheScaledPixmaps", true);
+
+ activateOnTopLeftCorner = kapp->config()->readBoolEntry("activateOnTopLeftCorner", false );
+ activateOnTopRightCorner = kapp->config()->readBoolEntry("activateOnTopRightCorner", false );
+ activateOnBottomLeftCorner = kapp->config()->readBoolEntry("activateOnBottomLeftCorner", false );
+ activateOnBottomRightCorner = kapp->config()->readBoolEntry("activateOnBottomRightCorner", false );
+
+ activateOnTopEdge = kapp->config()->readBoolEntry("activateOnTopEdge", false );
+ activateOnBottomEdge = kapp->config()->readBoolEntry("activateOnBottomEdge", false );
+ activateOnLeftEdge = kapp->config()->readBoolEntry("activateOnLeftEdge", false );
+ activateOnRightEdge = kapp->config()->readBoolEntry("activateOnRightEdge", false );
+
+ autoLockDelay = kapp->config()->readNumEntry("autoLockDelay", 1000);
+
+ showDesktopNum = kapp->config()->readBoolEntry("showDesktopNum", false );
+
+ viewScreen = kapp->config()->readNumEntry("viewScreen", -1);
+
+ calcFontMetrics();
+ emit settingsChanged();
+}
+
+void KomposeSettings::writeConfig()
+{
+ kdDebug() << "KomposeSettings::writeConfig()" << endl;
+
+ globalAccel->writeSettings();
+ globalAccel->updateConnections();
+
+ // Read from config file
+ kapp->config()->setGroup("Main window");
+
+ kapp->config()->writeEntry("defaultView", defaultView );
+
+ kapp->config()->writeEntry("useComposite", useComposite );
+
+ kapp->config()->writeEntry("passiveScreenshots", passiveScreenshots );
+ kapp->config()->writeEntry("screenshotGrabDelay", screenshotGrabDelay);
+
+ kapp->config()->writeEntry("dynamicVirtDeskLayout", dynamicVirtDeskLayout);
+
+ kapp->config()->writeEntry("imageEffects", imageEffects);
+
+ kapp->config()->writeEntry("showIcons", showIcons);
+ kapp->config()->writeEntry("iconSize", iconSize);
+
+ kapp->config()->writeEntry("showWindowTitles", showWindowTitles);
+ kapp->config()->writeEntry("windowTitleFont", windowTitleFont);
+ kapp->config()->writeEntry("windowTitleFontColor", windowTitleFontColor);
+ kapp->config()->writeEntry("showWindowTitleShadow", showWindowTitleShadow);
+ kapp->config()->writeEntry("windowTitleFontShadowColor", windowTitleFontShadowColor);
+
+ kapp->config()->writeEntry("desktopTitleFont", desktopTitleFont);
+ kapp->config()->writeEntry("desktopTitleFontColor", desktopTitleFontColor);
+ kapp->config()->writeEntry("desktopTitleFontHighlightColor", desktopTitleFontHighlightColor);
+
+ kapp->config()->writeEntry("cacheScaledPixmaps", cacheScaledPixmaps);
+
+ kapp->config()->writeEntry("activateOnTopLeftCorner", activateOnTopLeftCorner);
+ kapp->config()->writeEntry("activateOnTopRightCorner", activateOnTopRightCorner);
+ kapp->config()->writeEntry("activateOnBottomLeftCorner", activateOnBottomLeftCorner);
+ kapp->config()->writeEntry("activateOnBottomRightCorner", activateOnBottomRightCorner);
+
+ kapp->config()->writeEntry("activateOnTopEdge", activateOnTopEdge);
+ kapp->config()->writeEntry("activateOnBottomEdge", activateOnBottomEdge);
+ kapp->config()->writeEntry("activateOnLeftEdge", activateOnLeftEdge);
+ kapp->config()->writeEntry("activateOnRightEdge", activateOnRightEdge);
+ kapp->config()->writeEntry("autoLockDelay", autoLockDelay);
+
+ kapp->config()->writeEntry("showDesktopNum", showDesktopNum);
+
+ kapp->config()->writeEntry("viewScreen", viewScreen);
+
+ kapp->config()->sync();
+
+ kdDebug() << "KomposeSettings::writeConfig() - Settings saved to cfg file" << endl;
+
+ calcFontMetrics();
+ emit settingsChanged();
+}
+
+
+void KomposeSettings::showPreferencesDlg()
+{
+ dialogOpen = true;
+ // popup preference dialog
+ KomposePreferences *dlg = new KomposePreferences();
+
+ dlg->exec();
+
+ delete dlg;
+ dialogOpen = false;
+}
+
+int KomposeSettings::getIconSizePixels()
+{
+ switch( iconSize )
+ {
+ case 0:
+ return 16;
+ case 1:
+ return 32;
+ case 2:
+ return 64;
+ case 3:
+ return -1;
+ }
+ return 32;
+}
+
+void KomposeSettings::calcFontMetrics()
+{
+ if (windowTitleFontMetrics != 0)
+ delete windowTitleFontMetrics;
+ windowTitleFontMetrics = new QFontMetrics( windowTitleFont );
+ windowTitleFontAscent = windowTitleFontMetrics->ascent();
+ windowTitleFontHeight = windowTitleFontMetrics->height();
+}
+
+#include "komposesettings.moc"
diff --git a/src/komposesettings.h b/src/komposesettings.h
new file mode 100644
index 0000000..4056dd4
--- /dev/null
+++ b/src/komposesettings.h
@@ -0,0 +1,174 @@
+//
+// C++ Interface: komposesettings
+//
+// Description:
+//
+//
+// Author: Hans Oischinger <[email protected]>, (C) 2004
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#ifndef KOMPOSESETTINGS_H
+#define KOMPOSESETTINGS_H
+
+#include <qobject.h>
+#include <qcolor.h>
+#include <qfont.h>
+
+#define MAX_DESKTOPS 16
+
+enum KomposeDisplay { KOMPOSEDISPLAY_WORLD, KOMPOSEDISPLAY_VIRTUALDESKS, KOMPOSEDISPLAY_CURRENTDESK };
+
+class KGlobalAccel;
+class QFontMetrics;
+
+
+/**
+@author Hans Oischinger
+*/
+class KomposeSettings : public QObject
+{
+ Q_OBJECT
+protected:
+ KomposeSettings(QObject *parent = 0, const char *name = 0);
+
+ ~KomposeSettings();
+
+public:
+ static KomposeSettings *instance();
+ void readConfig();
+ void writeConfig();
+
+ bool hasDialogOpen() { return dialogOpen; }
+ KGlobalAccel *getGlobalAccel() const { return globalAccel; }
+
+ bool getUseComposite() const { return useComposite; }
+ void setUseComposite( bool b ) { useComposite = b; }
+
+ bool getPassiveScreenshots() const { return passiveScreenshots; }
+ void setPassiveScreenshots( bool b ) { passiveScreenshots = b; }
+ uint getScreenshotGrabDelay() { return screenshotGrabDelay; }
+ void setScreenshotGrabDelay( uint val ) { screenshotGrabDelay=val; }
+ bool getDynamicVirtDeskLayout() const { return dynamicVirtDeskLayout; }
+ void setDynamicVirtDeskLayout( bool b ) { dynamicVirtDeskLayout = b; }
+ bool getImageEffects() const { return imageEffects; }
+ void setImageEffects( bool b ) { imageEffects = b; }
+
+ int getDefaultView() const { return defaultView; }
+ void setDefaultView( int d ) { defaultView = d; }
+ int getIconSize() { return iconSize; }
+ void setIconSize( int i ) { iconSize = i; }
+ int getShowIcons() { return showIcons; }
+ void setShowIcons( bool b ) { showIcons = b; }
+ int getIconSizePixels();
+
+ void setWindowTitleFont( QFont f ) { windowTitleFont = f; }
+ const QFont& getWindowTitleFont() const { return windowTitleFont; }
+ int getShowWindowTitles() { return showWindowTitles; }
+ void setShowWindowTitles( bool b ) { showWindowTitles = b; }
+ int getShowWindowTitleShadow() { return showWindowTitleShadow; }
+ void setShowWindowTitleShadow( bool b ) { showWindowTitleShadow = b; }
+ const QColor& getWindowTitleFontColor() const { return windowTitleFontColor; }
+ void setWindowTitleFontColor( QColor c ) { windowTitleFontColor = c; }
+ const QColor& getWindowTitleFontShadowColor() const { return windowTitleFontShadowColor; }
+ void setWindowTitleFontShadowColor( QColor c ) { windowTitleFontShadowColor = c; }
+
+ const QFontMetrics* getWindowTitleFontMetrics() { return windowTitleFontMetrics; }
+ int getWindowTitleFontAscent() { return windowTitleFontAscent; }
+ int getWindowTitleFontHeight() { return windowTitleFontHeight; }
+
+ void setDesktopTitleFont( QFont f ) { desktopTitleFont = f; }
+ const QFont& getDesktopTitleFont() const { return desktopTitleFont; }
+ const QColor& getDesktopTitleFontColor() const { return desktopTitleFontColor; }
+ void setDesktopTitleFontColor( QColor c ) { desktopTitleFontColor = c; }
+ const QColor& getDesktopTitleFontHighlightColor() const { return desktopTitleFontHighlightColor; }
+ void setDesktopTitleFontHighlightColor( QColor c ) { desktopTitleFontHighlightColor = c; }
+
+ bool getCacheScaledPixmaps() const { return cacheScaledPixmaps; }
+ void setCacheScaledPixmaps( bool b ) { cacheScaledPixmaps = b; }
+
+ bool getActivateOnTopLeftCorner() const { return activateOnTopLeftCorner; }
+ void setActivateOnTopLeftCorner( bool b ) { activateOnTopLeftCorner = b; }
+ bool getActivateOnTopRightCorner() const { return activateOnTopRightCorner; }
+ void setActivateOnTopRighCorner( bool b ) { activateOnTopRightCorner = b; }
+ bool getActivateOnBottomLeftCorner() const { return activateOnBottomLeftCorner; }
+ void setActivateOnBottomLeftCorner( bool b ) { activateOnBottomLeftCorner = b; }
+ bool getActivateOnBottomRightCorner() const { return activateOnBottomRightCorner; }
+ void setActivateOnBottomRightCorner( bool b ) { activateOnBottomRightCorner = b; }
+
+ bool getActivateOnTopEdge() const { return activateOnTopEdge; }
+ void setActivateOnTopEdge( bool b ) { activateOnTopEdge = b; }
+ bool getActivateOnLeftEdge() const { return activateOnLeftEdge; }
+ void setActivateOnLeftEdge( bool b ) { activateOnLeftEdge= b; }
+ bool getActivateOnBottomEdge() const { return activateOnBottomEdge; }
+ void setActivateOnBottomEdge( bool b ) { activateOnBottomEdge = b; }
+ bool getActivateOnRightEdge() const { return activateOnRightEdge; }
+ void setActivateOnRightEdge( bool b ) { activateOnRightEdge = b; }
+
+ uint getAutoLockDelay() { return autoLockDelay; }
+ void setAutoLockDelay( uint val ) { autoLockDelay=val; }
+
+ void setShowDesktopNum( bool b ) { showDesktopNum = b; }
+ bool getShowDesktopNum() const { return showDesktopNum; }
+
+ void setViewScreen( int screen ) { viewScreen = screen; }
+ int getViewScreen() const { return viewScreen; }
+
+public slots:
+ void showPreferencesDlg();
+
+protected slots:
+ void calcFontMetrics();
+
+signals:
+ void settingsChanged();
+
+private:
+ KGlobalAccel *globalAccel;
+ bool dialogOpen;
+
+ bool useComposite;
+ bool passiveScreenshots;
+ uint screenshotGrabDelay;
+
+ bool dynamicVirtDeskLayout;
+
+ bool imageEffects;
+ int defaultView;
+
+ int iconSize;
+ bool showIcons;
+
+ bool showWindowTitles;
+ QFont windowTitleFont;
+ QFontMetrics *windowTitleFontMetrics;
+ int windowTitleFontAscent;
+ int windowTitleFontHeight;
+ QColor windowTitleFontColor;
+ bool showWindowTitleShadow;
+ QColor windowTitleFontShadowColor;
+
+ QFont desktopTitleFont;
+ QColor desktopTitleFontColor;
+ QColor desktopTitleFontHighlightColor;
+
+ bool cacheScaledPixmaps;
+
+ bool activateOnTopLeftCorner;
+ bool activateOnTopRightCorner;
+ bool activateOnBottomLeftCorner;
+ bool activateOnBottomRightCorner;
+
+ bool activateOnTopEdge;
+ bool activateOnLeftEdge;
+ bool activateOnBottomEdge;
+ bool activateOnRightEdge;
+
+ uint autoLockDelay;
+
+ bool showDesktopNum;
+ int viewScreen;
+};
+
+#endif
diff --git a/src/komposesystray.cpp b/src/komposesystray.cpp
new file mode 100644
index 0000000..41df920
--- /dev/null
+++ b/src/komposesystray.cpp
@@ -0,0 +1,127 @@
+//
+// C++ Implementation: komposesystray
+//
+// Description:
+//
+//
+// Author: Hans Oischinger <[email protected]>, (C) 2004
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#include "komposesystray.h"
+
+#include "komposeviewmanager.h"
+#include "komposefullscreenwidget.h"
+#include "komposesettings.h"
+#include "komposeglobal.h"
+#include "komposetaskmanager.h"
+
+#include <qpixmap.h>
+#include <qbitmap.h>
+#include <qpainter.h>
+
+#include <kapplication.h>
+#include <kaction.h>
+#include <kpopupmenu.h>
+#include <kiconeffect.h>
+#include <kglobalsettings.h>
+
+KomposeSysTray::KomposeSysTray(QWidget *parent, const char *name)
+ : KSystemTray(parent, name)
+{
+ // Create Menu
+ menu = contextMenu();
+ move( -1000, -1000 );
+ // Fill Menu
+ KomposeGlobal::instance()->getActShowWorldView()->plug(menu);
+ KomposeGlobal::instance()->getActShowVirtualDesktopView()->plug(menu);
+ KomposeGlobal::instance()->getActShowCurrentDesktopView()->plug(menu);
+ menu->insertSeparator();
+ KomposeGlobal::instance()->getActPreferencesDialog()->plug(menu);
+ KomposeGlobal::instance()->getActConfigGlobalShortcuts()->plug(menu);
+ KomposeGlobal::instance()->getActAboutDlg()->plug(menu);
+
+ slotConfigChanged();
+ connect( KomposeSettings::instance(), SIGNAL(settingsChanged()), this, SLOT(slotConfigChanged()) );
+}
+
+
+KomposeSysTray::~KomposeSysTray()
+{}
+
+void KomposeSysTray::slotConfigChanged( )
+{
+ // set the icon here
+ QPixmap iconPixmap = loadIcon("kompose");
+ setPixmap(iconPixmap);
+ icon = iconPixmap.convertToImage();
+ currentDesktopChanged(KomposeTaskManager::instance()->getCurrentDesktopNum());
+}
+
+void KomposeSysTray::mouseReleaseEvent (QMouseEvent * )
+{}
+
+void KomposeSysTray::mousePressEvent ( QMouseEvent * e )
+{
+ if ( !rect().contains( e->pos() ) )
+ return;
+
+ switch ( e->button() )
+ {
+ case LeftButton:
+ KomposeViewManager::instance()->createView( KomposeSettings::instance()->getDefaultView() );
+ break;
+ case MidButton:
+ // fall through
+ case RightButton:
+ contextMenuAboutToShow( menu );
+ menu->popup( e->globalPos() );
+ break;
+ default:
+ // nothing
+ break;
+ }
+}
+
+void KomposeSysTray::currentDesktopChanged(int desktop)
+{
+ if (!KomposeSettings::instance()->getShowDesktopNum())
+ return;
+ // update the icon to display the current desktop number
+ // qDebug("Displaying current desktop number on the tray icon....\n");
+
+ // copying from aKregator/src/trayicon.cpp
+ // from KMSystemTray
+ int oldW = pixmap()->size().width();
+ int oldH = pixmap()->size().height();
+
+ QString uStr=QString::number( desktop );
+ QFont f=KGlobalSettings::generalFont();
+ f.setBold(true);
+ f.setItalic(true);
+ float pointSize=f.pointSizeFloat();
+ QFontMetrics fm(f);
+ int w=fm.width(uStr);
+ if( w > (oldW) )
+ {
+ pointSize *= float(oldW) / float(w);
+ f.setPointSizeFloat(pointSize);
+ }
+ QPixmap pix(oldW, oldH);
+ pix.fill(Qt::white);
+ QPainter p(&pix);
+ p.setFont(f);
+ p.setPen(Qt::black);
+ p.drawText(pix.rect(), Qt::AlignCenter, uStr);
+ pix.setMask(pix.createHeuristicMask());
+ QImage img=pix.convertToImage();
+ // overlay
+ QImage overlayImg=icon.copy();
+ KIconEffect::overlay(overlayImg, img);
+ QPixmap newIcon;
+ newIcon.convertFromImage(overlayImg);
+ setPixmap(newIcon);
+}
+
+#include "komposesystray.moc"
diff --git a/src/komposesystray.h b/src/komposesystray.h
new file mode 100644
index 0000000..e649ee1
--- /dev/null
+++ b/src/komposesystray.h
@@ -0,0 +1,47 @@
+//
+// C++ Interface: komposesystray
+//
+// Description:
+//
+//
+// Author: Hans Oischinger <[email protected]>, (C) 2004
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#ifndef KOMPOSESYSTRAY_H
+#define KOMPOSESYSTRAY_H
+
+#include <ksystemtray.h>
+
+#include <qimage.h>
+
+class KAction;
+class KGlobalAccel;
+class KPopupMenu;
+
+/**
+@author Hans Oischinger
+*/
+class KomposeSysTray : public KSystemTray
+{
+ Q_OBJECT
+public:
+ KomposeSysTray(QWidget *parent = 0, const char *name = 0);
+ ~KomposeSysTray();
+
+ void currentDesktopChanged(int desktop);
+
+protected:
+ void mouseReleaseEvent (QMouseEvent *);
+ void mousePressEvent (QMouseEvent *);
+
+protected slots:
+ void slotConfigChanged();
+
+private:
+ KPopupMenu *menu;
+ QImage icon;
+};
+
+#endif
diff --git a/src/komposetask.cpp b/src/komposetask.cpp
new file mode 100644
index 0000000..54b3fd1
--- /dev/null
+++ b/src/komposetask.cpp
@@ -0,0 +1,357 @@
+/***************************************************************************
+ * Copyright (C) 2004 by Hans Oischinger *
+ * *
+ * 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 "komposetask.h"
+
+#include "komposetaskmanager.h"
+#include "komposesettings.h"
+#include "komposeglobal.h"
+
+#include <qobject.h>
+#include <qimage.h>
+#include <qapplication.h>
+#include <qtimer.h>
+#include <qpixmap.h>
+#include <kpixmapio.h>
+
+#include <kwinmodule.h>
+#include <klocale.h>
+#include <kdebug.h>
+
+#include <netwm.h>
+#include <time.h>
+
+// Last include as it's Xlibs includes conflict with qt includes
+#include "komposetaskvisualizer.h"
+#include <X11/Xlib.h>
+
+KomposeTask::KomposeTask(WId win, KWinModule *kwinmod, QObject *parent, const char *name)
+ : QObject(parent, name),
+ kwinmodule(kwinmod),
+ windowID(win),
+ blockDamageEvents(false)
+{
+ findWmFrame();
+
+ // Initial refresh
+ refresh();
+
+ // Create visualizer object
+ visualizer = new KomposeTaskVisualizer( this );
+}
+
+
+KomposeTask::~KomposeTask()
+{
+ emit closed();
+ visualizer->deleteLater();
+}
+
+void KomposeTask::findWmFrame()
+{
+ Window target_win, parent, root;
+ Window *children;
+ uint status, nchildren;
+
+ target_win = windowID;
+ for (;;)
+ {
+ status = XQueryTree(QPaintDevice::x11AppDisplay(), target_win, &root, &parent, &children, &nchildren);
+ if (!status)
+ break;
+ if (children)
+ XFree(children);
+
+ if (!parent || parent == root)
+ break;
+ else
+ target_win = parent;
+ }
+
+ wmframeID = target_win;
+}
+
+void KomposeTask::slotActivated()
+{
+ visualizer->slotTaskActivated();
+}
+
+void KomposeTask::slotUpdateScreenshot()
+{
+ visualizer->slotUpdateScreenshot();
+}
+
+bool KomposeTask::isOnTop() const
+{
+ return KomposeTaskManager::instance()->isOnTop( this );
+}
+
+
+bool KomposeTask::isActive() const
+{
+ if ( kwinmodule->activeWindow() == windowID )
+ return true;
+ else
+ return false;
+}
+
+bool KomposeTask::isMaximized() const
+{
+ return (windowInfo.state() & NET::Max);
+}
+
+bool KomposeTask::isIconified() const
+{
+ // return (windowInfo.mappingState == NET::Iconic);
+ return windowInfo.isMinimized();
+}
+
+bool KomposeTask::isAlwaysOnTop() const
+{
+ return (windowInfo.state() & NET::StaysOnTop);
+}
+
+bool KomposeTask::isShaded() const
+{
+ return (windowInfo.state() & NET::Shaded);
+}
+
+bool KomposeTask::isOnCurrentDesktop() const
+{
+ return (windowInfo.onAllDesktops() || windowInfo.desktop() == KWin::currentDesktop());
+}
+
+int KomposeTask::onDesktop() const
+{
+ return windowInfo.desktop();
+}
+
+bool KomposeTask::isOnAllDesktops() const
+{
+ return windowInfo.onAllDesktops();
+}
+
+
+bool KomposeTask::isModified() const
+{
+ static QString modStr = QString::fromUtf8("[") + i18n("modified") + QString::fromUtf8("]");
+ int modStrPos = windowInfo.visibleName().find(modStr);
+
+ return ( modStrPos != -1 );
+}
+
+
+void KomposeTask::maximize()
+{
+ NETWinInfo ni( qt_xdisplay(), windowID, qt_xrootwin(), NET::WMState);
+ ni.setState( NET::Max, NET::Max );
+
+ if (windowInfo.mappingState() == NET::Iconic)
+ activate();
+}
+
+void KomposeTask::restore()
+{
+ KWin::deIconifyWindow( windowID, false );
+ // NETWinInfo ni( qt_xdisplay(), windowID, qt_xrootwin(), NET::WMState);
+ // ni.setState( 0, NET::Max );
+ //
+ // if (windowInfo.mappingState == NET::Iconic)
+ // activate();
+}
+
+void KomposeTask::iconify()
+{
+ //XIconifyWindow( qt_xdisplay(), windowID, qt_xscreen() );
+ KWin::iconifyWindow( windowID, false );
+}
+
+void KomposeTask::close()
+{
+ NETRootInfo ri( qt_xdisplay(), NET::CloseWindow );
+ ri.closeWindowRequest( windowID );
+}
+
+void KomposeTask::raise()
+{
+ // kdDebug(1210) << "Task::raise(): " << name() << endl;
+ XRaiseWindow( qt_xdisplay(), windowID );
+}
+
+void KomposeTask::lower()
+{
+ // kdDebug(1210) << "Task::lower(): " << name() << endl;
+ XLowerWindow( qt_xdisplay(), windowID );
+}
+
+
+void KomposeTask::activate()
+{
+ KWin::forceActiveWindow(windowID);
+}
+
+// void KomposeTask::activateOrRaise()
+// {
+// if ( !isActive() || isIconified() )
+// {
+// activate();
+// }
+// else if ( !isOnTop() )
+// {
+// raise();
+// }
+// }
+
+void KomposeTask::minimizeOrRestore()
+{
+ if ( isIconified() )
+ {
+ restore();
+ }
+ else
+ {
+ iconify();
+ }
+}
+
+void KomposeTask::toDesktop(int desk)
+{
+ NETWinInfo ni(qt_xdisplay(), windowID, qt_xrootwin(), NET::WMDesktop);
+ if (desk == 0)
+ {
+ ni.setDesktop(NETWinInfo::OnAllDesktops);
+ return;
+ }
+ //ni.setDesktop(desk+1);
+ KWin::setOnDesktop( windowID, desk );
+}
+
+void KomposeTask::toCurrentDesktop()
+{
+ toDesktop(kwinmodule->currentDesktop());
+}
+
+void KomposeTask::setAlwaysOnTop(bool stay)
+{
+ NETWinInfo ni( qt_xdisplay(), windowID, qt_xrootwin(), NET::WMState);
+ if(stay)
+ ni.setState( NET::StaysOnTop, NET::StaysOnTop );
+ else
+ ni.setState( 0, NET::StaysOnTop );
+}
+
+void KomposeTask::toggleAlwaysOnTop()
+{
+ setAlwaysOnTop( !isAlwaysOnTop() );
+}
+
+void KomposeTask::setShaded(bool shade)
+{
+ NETWinInfo ni( qt_xdisplay(), windowID, qt_xrootwin(), NET::WMState);
+ if(shade)
+ ni.setState( NET::Shaded, NET::Shaded );
+ else
+ ni.setState( 0, NET::Shaded );
+}
+
+void KomposeTask::toggleShaded()
+{
+ setShaded( !isShaded() );
+}
+
+/*
+ * Update Info data
+ */
+void KomposeTask::refresh()
+{
+ //kdDebug() << "KomposeTask::refresh() (WId %d) - Window parameters have changed or initial refresh", windowID);
+
+ windowInfo = KWin::windowInfo(windowID);
+
+ if ( !windowInfo.valid() )
+ {
+ kdDebug() << "KomposeTask::refresh() (WId " << windowID << ") - Invalid window Info. window closed?!" << endl;
+ // TODO: Find out what I have todo when this happens ( it does! )
+ return;
+ }
+
+ emit stateChanged(); //TODO: Only emit this when state has really changed
+}
+
+
+/**
+ * This has to be called by x11EventFilter whenever ConfigureNotify for this win occurs
+ * sorta hacky but x11EventFilter can only be implemented in a kapp object which redirects it
+ * to the taskmanager, that picks out the right task by winId and notifies us :(
+ */
+void KomposeTask::slotX11ConfigureNotify()
+{
+ emit x11ConfigureNotify();
+}
+
+/**
+ * This has to be called by x11EventFilter whenever DamageNotify for this win occurs
+ * sorta hacky but x11EventFilter can only be implemented in a kapp object which redirects it
+ * to the taskmanager, that picks out the right task by winId and notifies us :(
+ */
+void KomposeTask::slotX11DamageNotify()
+{
+ if ( blockDamageEvents )
+ return;
+
+ blockDamageEvents = true;
+ emit x11DamageNotify();
+ QTimer::singleShot( 1000, this, SLOT( unBlockDamageEvents() ) );
+}
+
+int KomposeTask::getHeightForWidth ( int w ) const
+{
+ return (int)(((double)w / (double)getGeometry().width()) * (double)getGeometry().height());
+}
+
+int KomposeTask::getWidthForHeight ( int h ) const
+{
+ return (int)(((double)h / (double)getGeometry().height()) * (double)getGeometry().width());
+}
+
+double KomposeTask::getAspectRatio()
+{
+ return (double)(getGeometry().width()) / (double)(getGeometry().height());
+}
+
+QPixmap KomposeTask::getIcon( int size )
+{
+ // Cache the icons???
+ // if ( pm_icon.isNull() || pm_icon.width() != size )
+ // {
+ // if (size == -1)
+ // pm_icon = KWin::icon( windowID );
+ // else
+ // pm_icon = KWin::icon( windowID, size, size, true );
+ // }
+ //
+ // return pm_icon;
+ if (size == -1)
+ return KWin::icon( windowID );
+ else
+ return KWin::icon( windowID, size, size, true );
+}
+
+
+#include "komposetask.moc"
diff --git a/src/komposetask.h b/src/komposetask.h
new file mode 100644
index 0000000..710ca83
--- /dev/null
+++ b/src/komposetask.h
@@ -0,0 +1,118 @@
+/***************************************************************************
+ * Copyright (C) 2004 by Hans Oischinger *
+ * *
+ * 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. *
+ ***************************************************************************/
+#ifndef KOMPOSETASK_H
+#define KOMPOSETASK_H
+
+#include <qobject.h>
+#include <qrect.h>
+#include <kwin.h>
+
+class KWinModule;
+class KomposeTaskVisualizer;
+
+/**
+@author Hans Oischinger
+*/
+class KomposeTask : public QObject
+{
+ Q_OBJECT
+public:
+ KomposeTask(WId win, KWinModule *kwinmod, QObject *parent = 0, const char *name = 0);
+
+ ~KomposeTask();
+
+public:
+ // state
+ bool isMaximized() const;
+ bool isIconified() const;
+ bool isShaded() const;
+ bool isOnTop() const;
+ int onDesktop() const;
+ bool isOnCurrentDesktop() const;
+ bool isOnAllDesktops() const;
+ bool isAlwaysOnTop() const;
+ bool isActive() const;
+ bool isModified() const;
+ bool isValid() const { return windowInfo.valid(); }
+
+ WId window() const { return windowID; }
+ WId wmFrame() const { return wmframeID; }
+ QString name() const { return windowInfo.name(); }
+ QString visibleName() const { return windowInfo.visibleName(); }
+ QString visibleNameWithState() const { return windowInfo.visibleNameWithState(); }
+ QRect getGeometry() const { return windowInfo.geometry(); }
+ QRect getFrameGeometry() const { return windowInfo.frameGeometry(); }
+
+ QPixmap getIcon( int size );
+ double getAspectRatio();
+ int getHeightForWidth( int w ) const;
+ int getWidthForHeight( int h ) const;
+
+ KomposeTaskVisualizer* getVisualizer() { return visualizer; }
+
+protected:
+ void paintEvent ( QPaintEvent * );
+ void mouseReleaseEvent ( QMouseEvent * e );
+ void findWmFrame();
+
+signals:
+ void stateChanged();
+ void x11ConfigureNotify();
+ void x11DamageNotify();
+ void closed();
+
+public slots:
+ void maximize();
+ void restore();
+ void iconify();
+ void close();
+ void raise();
+ void lower();
+ void activate();
+ // void activateOrRaise();
+ void minimizeOrRestore();
+
+ void toDesktop(int desk);
+ void toCurrentDesktop();
+ void setAlwaysOnTop(bool stay);
+ void toggleAlwaysOnTop();
+ void setShaded(bool shade);
+ void toggleShaded();
+
+ void refresh();
+ void slotX11ConfigureNotify();
+ void slotX11DamageNotify();
+ void slotActivated();
+ void slotUpdateScreenshot();
+
+protected slots:
+ void unBlockDamageEvents() { blockDamageEvents = false; }
+
+private:
+ KWinModule* kwinmodule;
+ WId windowID;
+ WId wmframeID;
+ KWin::WindowInfo windowInfo;
+
+ bool blockDamageEvents;
+ KomposeTaskVisualizer* visualizer;
+};
+
+#endif
diff --git a/src/komposetaskcontainerwidget.cpp b/src/komposetaskcontainerwidget.cpp
new file mode 100644
index 0000000..2899b5b
--- /dev/null
+++ b/src/komposetaskcontainerwidget.cpp
@@ -0,0 +1,254 @@
+//
+// C++ Implementation: komposetaskcontainerwidget
+//
+// Description:
+//
+//
+// Author: Hans Oischinger <[email protected]>, (C) 2004
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#include "komposetaskcontainerwidget.h"
+#include "komposetaskmanager.h"
+#include "komposeviewmanager.h"
+#include "komposelayout.h"
+#include "komposesettings.h"
+#include "komposetaskwidget.h"
+
+#include <qobjectlist.h>
+#include <qwidget.h>
+#include <qtimer.h>
+#include <kdebug.h>
+
+static bool controlHold = false; // is the control key pressed
+
+KomposeTaskContainerWidget::KomposeTaskContainerWidget( int desk, QWidget *parent, KomposeLayout *l, const char *name)
+ : KomposeWidget(parent, l, name),
+ desktop( desk )
+{
+ connect(KomposeTaskManager::instance(), SIGNAL(taskDesktopChanged(KomposeTask*, int, int )),
+ SLOT(reparentTaskWidget(KomposeTask*, int, int )) );
+}
+
+
+KomposeTaskContainerWidget::~KomposeTaskContainerWidget()
+{}
+
+void KomposeTaskContainerWidget::reparentTaskWidget( KomposeTask* task, int fromDesktop, int toDesktop )
+{
+ // noops
+ if ( (fromDesktop==-1 && ((toDesktop==-1) || desktop == toDesktop-1)) || desktop==-2)
+ return;
+
+ kdDebug() << "KomposeTaskContainerWidget::reparentTaskWidget()" << endl;
+
+ // Delete from current
+ if ( (toDesktop!= -1) && (desktop == fromDesktop-1 || fromDesktop==-1) )
+ {
+ KomposeTaskWidget *child;
+ QPtrListIterator<KomposeWidget> it( *(layout->getManagedWidgets()));
+ while ( (child = dynamic_cast<KomposeTaskWidget*>(it.current()) ) != 0 )
+ {
+ ++it;
+ if (child->getTask() == task)
+ {
+ removeChild( task );
+ layout->remove(child);
+ //child->deleteLater();
+ child->close(true);
+ return;
+ }
+ }
+ }
+
+ // Add to new
+ if ( desktop == toDesktop -1 || (toDesktop == -1 && fromDesktop-1!=desktop) )
+ {
+ createTaskWidget( task, true );
+ //QTimer::singleShot( 200, layout, SLOT( arrangeLayout() ) );
+ // layout->arrangeLayout();
+ }
+}
+
+void KomposeTaskContainerWidget::keyPressEvent ( QKeyEvent * e )
+{
+ if ( e->key() == Qt::Key_Control )
+ {
+ controlHold = true;
+ e->accept();
+ }
+}
+
+void KomposeTaskContainerWidget::keyReleaseEvent ( QKeyEvent * e )
+{
+ if ( e->key() == Qt::Key_Control )
+ {
+ controlHold = false;
+ e->accept();
+ return;
+ }
+
+ if ( e->key() == Qt::Key_Right || e->key() == Qt::Key_D || e->key() == Qt::Key_H ||
+ e->key() == Qt::Key_Left || e->key() == Qt::Key_A || e->key() == Qt::Key_J ||
+ e->key() == Qt::Key_Up || e->key() == Qt::Key_W || e->key() == Qt::Key_K ||
+ e->key() == Qt::Key_Down || e->key() == Qt::Key_S || e->key() == Qt::Key_L )
+ {
+ if ( controlHold && desktop != -1 )
+ {
+ e->ignore();
+ return;
+ }
+
+ kdDebug() << "KomposeTaskContainerWidget::keyReleaseEvent - " << className() << ", Movement key pressed" << endl;
+ // Map keys to directions
+ int direction = DLAYOUT_RIGHT;
+ switch( e->key() )
+ {
+ case Qt::Key_Right:
+ direction = DLAYOUT_RIGHT;
+ break;
+ case Qt::Key_D:
+ direction = DLAYOUT_RIGHT;
+ break;
+ case Qt::Key_L:
+ direction = DLAYOUT_RIGHT;
+ break;
+ case Qt::Key_Left:
+ direction = DLAYOUT_LEFT;
+ break;
+ case Qt::Key_A:
+ direction = DLAYOUT_LEFT;
+ break;
+ case Qt::Key_H:
+ direction = DLAYOUT_LEFT;
+ break;
+ case Qt::Key_Up:
+ direction = DLAYOUT_TOP;
+ break;
+ case Qt::Key_W:
+ direction = DLAYOUT_TOP;
+ break;
+ case Qt::Key_K:
+ direction = DLAYOUT_TOP;
+ break;
+ case Qt::Key_Down:
+ direction = DLAYOUT_BOTTOM;
+ break;
+ case Qt::Key_S:
+ direction = DLAYOUT_BOTTOM;
+ break;
+ case Qt::Key_J:
+ direction = DLAYOUT_BOTTOM;
+ break;
+ }
+
+ focusNeighbourChild( direction );
+ e->accept();
+
+ return;
+ }
+
+ e->ignore();
+}
+
+
+bool KomposeTaskContainerWidget::focusNeighbourChild( int direction )
+{
+ bool successfull = false;
+ if ( !children()->containsRef(focusWidget()) )
+ {
+ kdDebug() << "KomposeTaskContainerWidget::keyReleaseEvent - No widget focussed. Focussing first" << endl;
+ const QObjectList *lst = children();
+
+ if ( lst )
+ {
+ QObjectListIterator it( *lst );
+ QWidget *widget;
+ while ( (widget = (QWidget*)it.current() ) )
+ {
+ if (widget->inherits("KomposeTaskWidget") || widget->inherits("KomposeDesktopWidget"))
+ {
+ kdDebug() << "KomposeTaskContainerWidget::keyReleaseEvent - Focussing " << widget->className() << endl;
+ widget->setFocus();
+ successfull = true;
+ break;
+ }
+ ++it;
+ }
+ }
+ }
+ else
+ {
+ KomposeWidget *widget;
+ if ( ( widget = layout->getNeighbour( dynamic_cast<KomposeWidget*>(focusWidget()), direction, WLAYOUT_BOTH ) ) != 0 )
+ {
+ kdDebug() << "KomposeTaskContainerWidget::keyReleaseEvent - Focussing " << widget->className() << endl;
+ widget->setFocus();
+ successfull = true;
+ }
+ }
+
+ return successfull;
+}
+
+
+void KomposeTaskContainerWidget::createTaskWidgets()
+{
+ TaskList tl = KomposeTaskManager::instance()->getTasks();
+ QPtrListIterator<KomposeTask> it( tl );
+ KomposeTask *task;
+ while ( (task = it.current()) != 0 )
+ {
+ ++it;
+ Q_CHECK_PTR(task);
+ createTaskWidget( task);
+ }
+}
+
+
+void KomposeTaskContainerWidget::createTaskWidget( KomposeTask* task, bool manualShow )
+{
+ if ( desktop == -1 || desktop == task->onDesktop()-1 || task->onDesktop()==-1)
+ {
+ kdDebug() << "KomposeTaskContainerWidget::createTaskWidget() (Container: " << this->className() << ", WId: " << task->window() << ", onDesktop: " << task->onDesktop() << ")" << endl;
+ KomposeTaskWidget *taskwidget = new KomposeTaskWidget( task, this );
+ if (manualShow)
+ taskwidget->show();
+ connect( taskwidget, SIGNAL(requestRemoval(KomposeWidget*)), SLOT(requestRemoval(KomposeWidget*)) );
+ }
+}
+
+int KomposeTaskContainerWidget::getHeightForWidth( int ) const
+{
+ return -1;
+}
+
+int KomposeTaskContainerWidget::getWidthForHeight( int ) const
+{
+ return -1;
+}
+
+double KomposeTaskContainerWidget::getAspectRatio()
+{
+ return -1;
+}
+
+void KomposeTaskContainerWidget::requestRemoval( KomposeWidget *obj )
+{
+ layout->remove(obj);
+ // removeChild( obj ); // FIXME: This causes segfaults although it would
+ // be the correct way (ChildRemoveEvents to rearrange the layout...)
+ !obj->close(true);
+ layout->arrangeLayout();
+}
+
+void KomposeTaskContainerWidget::childEvent( QChildEvent * ce)
+{
+ KomposeWidget::childEvent(ce);
+ // ReLayout when we are in a active view and a new window appeared somewhere
+ if ( KomposeViewManager::instance()->hasActiveView() )
+ layout->arrangeLayout();
+}
+
+#include "komposetaskcontainerwidget.moc"
diff --git a/src/komposetaskcontainerwidget.h b/src/komposetaskcontainerwidget.h
new file mode 100644
index 0000000..816d487
--- /dev/null
+++ b/src/komposetaskcontainerwidget.h
@@ -0,0 +1,58 @@
+//
+// C++ Interface: komposetaskcontainerwidget
+//
+// Description:
+//
+//
+// Author: Hans Oischinger <[email protected]>, (C) 2004
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#ifndef KOMPOSETASKCONTAINERWIDGET_H
+#define KOMPOSETASKCONTAINERWIDGET_H
+
+#include "komposewidget.h"
+#include "komposetask.h"
+#include "komposelayout.h"
+
+/**
+ * This abstract class contains some functions only usable for
+ * Widgets that display task widgets
+ * (so I won't have to double the code for the createTaskWidgets() funxtion :) )
+ *
+ * @author Hans Oischinger
+ */
+class KomposeTaskContainerWidget : public KomposeWidget
+{
+ Q_OBJECT
+public:
+ KomposeTaskContainerWidget( int desk = 0, QWidget *parent = 0, KomposeLayout *l = 0, const char *name = 0);
+
+ virtual ~KomposeTaskContainerWidget();
+
+ virtual int getHeightForWidth( int w ) const;
+ virtual int getWidthForHeight( int h ) const;
+ virtual double getAspectRatio();
+
+ void setDesktop( int desk ) { desktop = desk; }
+ int getDesktop() { return desktop; }
+
+public slots:
+ void requestRemoval( KomposeWidget *obj );
+
+protected slots:
+ void createTaskWidgets();
+ void createTaskWidget( KomposeTask* task, bool manualShow=true );
+ void reparentTaskWidget( KomposeTask* task, int fromDesktop, int toDesktop );
+ bool focusNeighbourChild( int direction );
+
+protected:
+ void keyReleaseEvent ( QKeyEvent * e );
+ void keyPressEvent ( QKeyEvent * e );
+ void childEvent( QChildEvent * ce);
+
+ int desktop;
+};
+
+#endif
diff --git a/src/komposetaskmanager.cpp b/src/komposetaskmanager.cpp
new file mode 100644
index 0000000..d33e1ae
--- /dev/null
+++ b/src/komposetaskmanager.cpp
@@ -0,0 +1,387 @@
+/***************************************************************************
+ * Copyright (C) 2004 by Hans Oischinger *
+ * *
+ * 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 "komposetaskmanager.h"
+
+#include "komposelayout.h"
+#include "komposedesktopwidget.h"
+#include "komposesettings.h"
+#include "komposetaskwidget.h"
+#include "komposeglobal.h"
+#include "komposetask.h"
+#include "komposeviewmanager.h"
+
+#include <qtimer.h>
+#include <qimage.h>
+#include <qpixmap.h>
+#include <qwidget.h>
+
+#include <kapplication.h>
+#include <kwinmodule.h>
+#include <netwm.h>
+#include <kwin.h>
+#include <kapplication.h>
+#include <kdebug.h>
+
+#ifdef COMPOSITE
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+#include <X11/extensions/Xcomposite.h>
+#include <X11/extensions/Xdamage.h>
+#include <X11/extensions/Xrender.h>
+#endif
+
+static KomposeTaskManager* taskManagerInstance = 0;
+
+
+/**
+ * Taskmanager is a singleton
+ */
+KomposeTaskManager* KomposeTaskManager::instance()
+{
+ if ( !taskManagerInstance )
+ {
+ kdDebug() << "KomposeTaskManager::instance() - Creating Singleton instance" << endl;
+ taskManagerInstance = new KomposeTaskManager();
+ }
+ return taskManagerInstance;
+}
+
+
+KomposeTaskManager::KomposeTaskManager()
+ : QObject()
+{
+ taskManagerInstance = this;
+ kwin_module = new KWinModule();
+ numDesks = KWin::numberOfDesktops();
+
+ callCompositeRedirect();
+
+ // Listeners for KWinmodule signals
+ connect( kwin_module, SIGNAL(windowAdded(WId)), this, SLOT(slotWindowAdded(WId)) );
+ connect( kwin_module, SIGNAL(windowRemoved(WId)), this, SLOT(slotWindowRemoved(WId)) );
+ connect( kwin_module, SIGNAL(numberOfDesktopsChanged(int)), this, SLOT(slotDesktopCountChanged(int)) );
+ connect( kwin_module, SIGNAL(currentDesktopChanged(int)), this, SLOT(slotCurrentDesktopChanged(int)) );
+
+ connect( KomposeSettings::instance(), SIGNAL(settingsChanged()), this, SLOT(slotStartWindowListeners()) );
+ connect( KomposeSettings::instance(), SIGNAL(settingsChanged()), this, SLOT(callCompositeRedirect()) );
+
+ // register existing windows
+ const QValueList<WId> windows = kwin_module->windows();
+ for (QValueList<WId>::ConstIterator it = windows.begin(); it != windows.end(); ++it )
+ slotWindowAdded(*it);
+
+ connect( kwin_module, SIGNAL(activeWindowChanged(WId)), this, SLOT(slotTaskActivated(WId)) );
+ slotStartWindowListeners();
+}
+
+KomposeTaskManager::~KomposeTaskManager()
+{
+ delete kwin_module;
+}
+
+/**
+ * Redirect or unredirect all root windows to offscreen buffers
+ */
+void KomposeTaskManager::callCompositeRedirect()
+{
+#ifdef COMPOSITE
+ if ( KomposeGlobal::instance()->hasXcomposite() )
+ {
+ Display *dpy = QPaintDevice::x11AppDisplay();
+ if ( KomposeSettings::instance()->getUseComposite() )
+ {
+ // Redirect
+ for ( int i = 0; i < ScreenCount( dpy ); i++ )
+ XCompositeRedirectSubwindows( dpy, RootWindow( dpy, i ), CompositeRedirectAutomatic );
+ }
+ else if ( !KomposeSettings::instance()->getUseComposite() )
+ {
+ // Unredirect
+ for ( int i = 0; i < ScreenCount( dpy ); i++ )
+ XCompositeUnredirectSubwindows( dpy, RootWindow( dpy, i ), CompositeRedirectAutomatic );
+ }
+ }
+#endif
+}
+
+/**
+ * Helper function that finds a KomposeTask object by it's window id
+ * @param w WindowID of the Task
+ * @return Corresponding KomposeTask object
+ */
+KomposeTask* KomposeTaskManager::findTask(WId w, bool wmFrameIds )
+{
+ for (KomposeTask* t = tasklist.first(); t != 0; t = tasklist.next())
+ if ((!wmFrameIds && t->window() == w) || (wmFrameIds && t->wmFrame() == w) )
+ return t;
+ return 0;
+}
+
+void KomposeTaskManager::slotStartWindowListeners()
+{
+ disconnect( kwin_module, SIGNAL(windowChanged( WId, unsigned int )), this,
+ SLOT(slotWindowChanged( WId, unsigned int )) );
+ connect( kwin_module, SIGNAL(windowChanged( WId, unsigned int )), this,
+ SLOT(slotWindowChanged( WId, unsigned int )) );
+}
+
+
+void KomposeTaskManager::slotWindowChanged( WId w, unsigned int dirty)
+{
+ if( dirty & NET::WMState )
+ {
+ NETWinInfo info ( qt_xdisplay(), w, qt_xrootwin(), NET::WMState );
+ if ( (info.state() & NET::SkipTaskbar) != 0 )
+ {
+ slotWindowRemoved( w );
+ return;
+ }
+ else
+ {
+ if( !findTask( w ))
+ slotWindowAdded( w );
+ }
+ }
+
+ // check if any state we are interested in is marked dirty
+ if(!(dirty & (NET::WMVisibleName|NET::WMVisibleIconName|NET::WMName|NET::WMState|NET::WMIcon|NET::XAWMState|NET::WMDesktop)) )
+ return;
+
+ // find task
+ KomposeTask* t = findTask( w );
+ if (!t) return;
+
+ int oldTaskDesktop = t->onDesktop();
+ // TODO: Instead of one refresh() method we could implement specific method for names and geometry, etc...
+ // checked like this: if(dirty & (NET::WMDesktop|NET::WMState|NET::XAWMState))
+ t->refresh();
+
+ // Finally check if the window has been moved to a different virtual desktop
+ if( (dirty & NET::WMDesktop ) && ( oldTaskDesktop != t->onDesktop() ) )
+ emit taskDesktopChanged( t, oldTaskDesktop, t->onDesktop() );
+}
+
+
+void KomposeTaskManager::slotWindowRemoved(WId w )
+{
+ // find task
+ KomposeTask* task = findTask( w );
+ if (!task) return;
+
+ //kdDebug() << "KomposeTaskManager::slotWindowRemoved(WId w ) - Removing task %s", task->visibleNameWithState());
+ tasklist.remove( task );
+ delete task;
+}
+
+void KomposeTaskManager::slotWindowAdded(WId w )
+{
+ // ignore myself
+ if ( QWidget::find(w) != 0 )
+ return;
+ // if ( KomposeViewManager::instance()->hasActiveView() && w == KomposeViewManager::instance()->getViewWidget()->winId() )
+ // {
+ // return;
+ // }
+
+ KWin::WindowInfo info = KWin::windowInfo(w);
+
+ // ignore NET::Tool and other special window types
+ NET::WindowType mytype = info.windowType(NET::NormalMask | NET::DesktopMask | NET::DockMask |
+ NET::ToolbarMask | NET::MenuMask | NET::DialogMask | NET::OverrideMask
+ | NET::TopMenuMask | NET::UtilityMask | NET::SplashMask);
+ if (mytype != NET::Normal && mytype != NET::Override && mytype != NET::Unknown && mytype != NET::Dialog)
+ return;
+
+ // ignore windows that want to be ignored by the taskbar
+ if ((info.state() & NET::SkipTaskbar) != 0)
+ {
+ return;
+ }
+
+ if ( !info.valid() )
+ return;
+
+ kdDebug() << "KomposeTaskManager::slotWindowAdded(WId " << w <<" ) - Adding KomposeTask" << endl;
+ KomposeTask* t = new KomposeTask(w, kwin_module, this);
+ tasklist.append(t);
+
+ emit newTask( t );
+}
+
+
+/**
+ * Called when Komposé requires screenshots of all tasks
+ */
+void KomposeTaskManager::slotUpdateScreenshots( bool switchDesktops )
+{
+ kdDebug() << "KomposeTaskManager::slotUpdateScreenshots()" << endl;
+
+ QPtrListIterator<KomposeTask> it( tasklist );
+ KomposeTask *task;
+
+ // Iterate through tasks sorted by desktops (this minimizes desktop switching if necessary)
+ for ( int desk = -1; desk <= numDesks; ++desk )
+ {
+ // Desk == 0 should not be possible, however -1 means on all desks
+ if (desk==0 || ( !switchDesktops && desk != KomposeViewManager::instance()->getDesktopBeforeSnaps()+1 ) )
+ continue;
+
+ it.toFirst();
+ while ( (task = it.current()) != 0 )
+ {
+ ++it;
+ if ( task->onDesktop() == desk )
+ task->slotUpdateScreenshot();
+ }
+ }
+}
+
+
+/**
+ * simulates a window activated event for the currently active window (no forcing of screenshots)
+ */
+void KomposeTaskManager::simulatePasvScreenshotEvent()
+{
+ kdDebug() << "KomposeTaskManager::simulatePasvScreenshotEvent()" << endl;
+ slotTaskActivated( kwin_module->activeWindow() );
+}
+
+/**
+ * Signals the task object that it's window has been activated
+ */
+void KomposeTaskManager::slotTaskActivated(WId winId)
+{
+ kdDebug() << "KomposeTaskManager::slotTaskActivated ( " << winId << " )" << endl;
+ QPtrListIterator<KomposeTask> it( tasklist );
+ KomposeTask *task;
+ while ( (task = it.current()) != 0 )
+ {
+ ++it;
+ if ( winId == task->window() )
+ {
+ task->slotActivated();
+ return;
+ }
+ }
+}
+
+
+void KomposeTaskManager::slotDesktopCountChanged(int d)
+{
+ numDesks = d;
+}
+
+bool KomposeTaskManager::isOnTop(const KomposeTask* task)
+{
+ if(!task) return false;
+
+ for (QValueList<WId>::ConstIterator it = kwin_module->stackingOrder().fromLast();
+ it != kwin_module->stackingOrder().end(); --it )
+ {
+ for (KomposeTask* t = tasklist.first(); t != 0; t = tasklist.next() )
+ {
+ if ( (*it) == t->window() )
+ {
+ if ( t == task )
+ return true;
+ if ( !t->isIconified() && (t->isAlwaysOnTop() == task->isAlwaysOnTop()) )
+ return false;
+ break;
+ }
+ }
+ }
+ return false;
+}
+
+QString KomposeTaskManager::getDesktopName(int desk) const
+{
+ return kwin_module->desktopName(desk);
+}
+
+
+/**
+ * The kapp x11EventFilter method redirect to this method
+ * @param event
+ * @return
+ */
+bool KomposeTaskManager::processX11Event( XEvent *event )
+{
+#ifdef COMPOSITE
+ if ( KomposeGlobal::instance()->hasXcomposite() && KomposeSettings::instance()->getUseComposite() )
+ {
+ if ( event->type == ConfigureNotify )
+ {
+ XConfigureEvent *e = &event->xconfigure;
+
+ KomposeTask* t = findTask( e->window, true );
+ if (!t)
+ return false;
+ t->slotX11ConfigureNotify();
+ return true;
+ }
+ else if ( event->type == KomposeGlobal::instance()->getDamageEvent() + XDamageNotify )
+ {
+ XDamageNotifyEvent *e = reinterpret_cast<XDamageNotifyEvent*>( event );
+ // e->drawable is the window ID of the damaged window
+ // e->geometry is the geometry of the damaged window
+ // e->area is the bounding rect for the damaged area
+ // e->damage is the damage handle returned by XDamageCreate()
+
+ // Subtract all the damage, repairing the window.
+ XDamageSubtract( QPaintDevice::x11AppDisplay(), e->damage, None, None );
+ if ( !KomposeViewManager::instance()->hasActiveView() )
+ return true;
+
+ // FIXME: too many damage events are called. block findTask here...
+ // FIXME: Don't try XDamage with KAsteroids! Do something to avoid 100% cpu usage
+ KomposeTask* t = findTask( e->drawable );
+ if (!t)
+ return false;
+ t->slotX11DamageNotify();
+ return true;
+ }
+ }
+#endif
+ return false;
+}
+
+void KomposeTaskManager::slotCurrentDesktopChanged(int d)
+{
+#ifdef COMPOSITE
+ if ( KomposeGlobal::instance()->hasXcomposite() && KomposeSettings::instance()->getUseComposite() )
+ {
+ // Strangely a ConfigureNotify is only sent when I click on a window on the new desktop
+ // and not when I cahnge the desktop, although the windows get mapped at this point.
+ // Is this a X bug? However the following hack helps:
+ // Do as if we received a ConfigureNotify event to update all backing pixmaps
+ for (KomposeTask* t = tasklist.first(); t != 0; t = tasklist.next())
+ if ( t->onDesktop() == d )
+ t->slotX11ConfigureNotify();
+ }
+#endif
+}
+
+int KomposeTaskManager::getCurrentDesktopNum()
+{
+ return kwin_module->currentDesktop();
+}
+
+#include "komposetaskmanager.moc"
diff --git a/src/komposetaskmanager.h b/src/komposetaskmanager.h
new file mode 100644
index 0000000..3b43a2a
--- /dev/null
+++ b/src/komposetaskmanager.h
@@ -0,0 +1,86 @@
+/***************************************************************************
+ * Copyright (C) 2004 by Hans Oischinger *
+ * *
+ * 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. *
+ ***************************************************************************/
+#ifndef KOMPOSETASKMANAGER_H
+#define KOMPOSETASKMANAGER_H
+
+#include <qobject.h>
+#include <qptrlist.h>
+
+
+class KWinModule;
+class KomposeTaskManager;
+class KomposeTask;
+
+typedef QPtrList<KomposeTask> TaskList;
+
+
+/**
+@author Hans Oischinger
+*/
+class KomposeTaskManager : public QObject
+{
+ Q_OBJECT
+protected:
+ KomposeTaskManager();
+
+ ~KomposeTaskManager();
+
+public:
+ static KomposeTaskManager *instance();
+
+ bool isOnTop(const KomposeTask* task );
+
+ int getNumDesktops() const { return numDesks; }
+ QString getDesktopName(int desk) const;
+ int getCurrentDesktopNum();
+
+ TaskList getTasks() const { return tasklist; }
+
+public slots:
+ bool processX11Event( XEvent *event );
+ void slotUpdateScreenshots( bool switchDesktops=true );
+ void simulatePasvScreenshotEvent();
+
+ void slotStartWindowListeners();
+
+protected slots:
+ void slotTaskActivated(WId);
+ void slotWindowAdded( WId w );
+ void slotWindowRemoved( WId w );
+ void slotWindowChanged( WId, unsigned int );
+ void slotDesktopCountChanged(int);
+ void slotCurrentDesktopChanged(int);
+ void callCompositeRedirect();
+
+signals:
+ void newTask( KomposeTask* task );
+ void taskDesktopChanged( KomposeTask* task, int fromDesktop, int toDesktop );
+
+protected:
+ KomposeTask* findTask(WId w, bool wmFrameIds = false);
+
+private:
+ KWinModule* kwin_module;
+ TaskList tasklist; // list of tasks handled by the WM
+
+ int numDesks; // total num of desks
+};
+
+#endif
diff --git a/src/komposetaskprefswidget.cpp b/src/komposetaskprefswidget.cpp
new file mode 100644
index 0000000..9bb862b
--- /dev/null
+++ b/src/komposetaskprefswidget.cpp
@@ -0,0 +1,54 @@
+//
+// C++ Implementation: komposetaskprefswidget
+//
+// Description:
+//
+//
+// Author: Hans Oischinger <[email protected]>, (C) 2004
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#include "komposetaskprefswidget.h"
+
+#include "komposetaskwidget.h"
+#include "komposetask.h"
+#include "komposetaskprefswidget.h"
+#include "komposesettings.h"
+
+#include <ktoolbar.h>
+#include <ktoolbarbutton.h>
+#include <kactioncollection.h>
+#include <kaction.h>
+#include <kshortcut.h>
+#include <klocale.h>
+
+#include <qiconset.h>
+
+KomposeTaskPrefsWidget::KomposeTaskPrefsWidget(KomposeTaskWidget *parent, const char *name)
+ : QDockArea(Qt::Horizontal , QDockArea::Normal, parent, name)
+{
+ KToolBar* pToolBar = new KToolBar( this, i18n("Task Actions") );
+ pToolBar->setLabel(i18n("Task"));
+ pToolBar->setResizeEnabled ( false );
+ pToolBar->setMovingEnabled ( false );
+ pToolBar->setHorizontallyStretchable ( false );
+ pToolBar->setVerticallyStretchable ( false );
+ pToolBar->setIconSize( 16 );
+
+ parent->getActMinimizeRestoreTask()->plug(pToolBar);
+ parent->getActCloseTask()->plug(pToolBar);
+
+ lineUp(false);
+
+ resize(pToolBar->size());
+}
+
+
+KomposeTaskPrefsWidget::~KomposeTaskPrefsWidget()
+{
+}
+
+
+
+#include "komposetaskprefswidget.moc"
diff --git a/src/komposetaskprefswidget.h b/src/komposetaskprefswidget.h
new file mode 100644
index 0000000..558fe5e
--- /dev/null
+++ b/src/komposetaskprefswidget.h
@@ -0,0 +1,32 @@
+//
+// C++ Interface: komposetaskprefswidget
+//
+// Description:
+//
+//
+// Author: Hans Oischinger <[email protected]>, (C) 2004
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#ifndef KOMPOSETASKPREFSWIDGET_H
+#define KOMPOSETASKPREFSWIDGET_H
+
+#include <qdockarea.h>
+
+class KomposeTaskWidget;
+
+/**
+@author Hans Oischinger
+*/
+class KomposeTaskPrefsWidget : public QDockArea
+{
+ Q_OBJECT
+public:
+ KomposeTaskPrefsWidget(KomposeTaskWidget *parent = 0, const char *name = 0);
+
+ ~KomposeTaskPrefsWidget();
+
+};
+
+#endif
diff --git a/src/komposetaskvisualizer.cpp b/src/komposetaskvisualizer.cpp
new file mode 100644
index 0000000..a3930aa
--- /dev/null
+++ b/src/komposetaskvisualizer.cpp
@@ -0,0 +1,458 @@
+//
+// C++ Implementation: %{MODULE}
+//
+// Description:
+//
+//
+// Author: %{AUTHOR} <%{EMAIL}>, (C) %{YEAR}
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#include "komposeglobal.h"
+#include "komposesettings.h"
+#include "komposeviewmanager.h"
+#include "komposetaskmanager.h"
+
+#include <qpixmap.h>
+#include <qtimer.h>
+#include <kwin.h>
+#include <netwm.h>
+#include <qapplication.h>
+#include <kdebug.h>
+
+#include <time.h>
+
+#include "komposetaskvisualizer.h"
+
+
+KomposeTaskVisualizer::KomposeTaskVisualizer(KomposeTask *parent, const char *name)
+ : QObject(parent, name),
+ task(parent),
+ scaledScreenshotDirty(false),
+ screenshotSuspended(false),
+ screenshotBlocked(false),
+ lasteffect( IEFFECT_NONE )
+{
+#ifdef COMPOSITE
+ validBackingPix = false;
+ compositeInit = false;
+#endif
+
+ screenshot.setOptimization( QPixmap::BestOptim );
+ scaledScreenshot.setOptimization( QPixmap::BestOptim );
+
+ // Create highlight color modifier
+ cmHighlight = imlib_create_color_modifier();
+ imlib_context_set_color_modifier(cmHighlight);
+ imlib_modify_color_modifier_brightness(0.13);
+
+ cmMinimized = imlib_create_color_modifier();
+ imlib_context_set_color_modifier(cmMinimized);
+ imlib_modify_color_modifier_brightness(-0.13);
+ imlib_context_set_color_modifier(0);
+
+ if ( !KomposeSettings::instance()->getCacheScaledPixmaps() )
+ {
+ // clear cached pixmaps on viewclose
+ connect( KomposeViewManager::instance(), SIGNAL(viewClosed()), this, SLOT(clearCached()) );
+ }
+
+ initXComposite();
+ connect( KomposeSettings::instance(), SIGNAL(settingsChanged()), this, SLOT(initXComposite()) );
+}
+
+KomposeTaskVisualizer::~KomposeTaskVisualizer()
+{
+#ifdef COMPOSITE
+ if ( compositeInit )
+ XDamageDestroy( dpy, damage);
+#endif
+ scaledScreenshot.resize(0,0);
+ screenshot.resize(0,0);
+}
+
+
+/**
+ * Called from outside to retrieve a screenshot
+ * @param pix The pixmap the screenshot will be rendered onto
+ */
+void KomposeTaskVisualizer::renderOnPixmap(QPixmap* pix, int effect)
+{
+ if ( scaledScreenshotDirty || scaledScreenshot.isNull() || scaledScreenshot.size() != pix->size() ||
+ KomposeSettings::instance()->getImageEffects() && (lasteffect != effect ) )
+ {
+ lasteffect = effect;
+ renderScaledScreenshot( pix->size() );
+ }
+
+ copyBlt ( pix, 0, 0, &scaledScreenshot, 0, 0, pix->width(), pix->height() );
+
+ // QPainter p( pix );
+ // p.drawPixmap(0 ,0 , *scaledScreenshot, 0, 0, pix->width(), pix->height() );
+ // p.end();
+}
+
+
+/**
+ * Renders a scaled version of screenshot and stores it as scaledScreenshot
+ * @param newSize
+ */
+void KomposeTaskVisualizer::renderScaledScreenshot( QSize newSize )
+{
+ kdDebug() << "KomposeTaskVisualizer::renderScaledScreenshot() (" << task->window() << ") " << newSize.width() << "x" << newSize.height() << endl;
+
+ scaledScreenshot.resize( newSize );
+
+ if ( KomposeGlobal::instance()->hasXcomposite() && KomposeSettings::instance()->getUseComposite() )
+ {
+#ifdef COMPOSITE
+ if ( !validBackingPix )
+ {
+ // When we get here we have never referenced a backingpix...
+ // FIXME: Currently it seems that there is no way to retrieve unmapped backing pixmaps,
+ // even switching desktops won't work due to the latency of XComposite :(
+ // Return a empty pixmap
+ scaledScreenshot.fill(white);
+ return;
+ }
+
+ // Create a Screenshot qpixmap
+ screenshot.resize( task->getGeometry().size() );
+
+ Picture picture = XRenderCreatePicture( dpy, windowBackingPix, format, CPSubwindowMode, &pa );
+ XRenderComposite( dpy,
+ hasAlpha ? PictOpOver : PictOpSrc,
+ picture,
+ None,
+ screenshot.x11RenderHandle(),
+ task->getGeometry().x() - task->getFrameGeometry().x(),
+ task->getGeometry().y() - task->getFrameGeometry().y(),
+ 0, 0, 0, 0,
+ screenshot.width(), screenshot.height() );
+ XRenderFreePicture (dpy, picture);
+#endif
+
+ }
+ /* if ( KomposeGlobal::instance()->hasXcomposite() && KomposeSettings::instance()->getUseComposite() )
+ {
+ // The XComposite way
+ #ifdef COMPOSITE
+ Picture picture = XRenderCreatePicture( dpy, windowBackingPix, format, CPSubwindowMode, &pa );
+ QRect geom = task->getGeometry();
+
+ double scale = (double)pix->width() / (double)geom.width();
+ XRenderSetPictureFilter( dpy, picture, FilterBilinear, 0, 0 );
+ // Scaling matrix
+ XTransform xform = {{
+ { XDoubleToFixed( 1 ), XDoubleToFixed( 0 ), XDoubleToFixed( 0 ) },
+ { XDoubleToFixed( 0 ), XDoubleToFixed( 1 ), XDoubleToFixed( 0 ) },
+ { XDoubleToFixed( 0 ), XDoubleToFixed( 0 ), XDoubleToFixed( scale ) }
+ }};
+
+ XRenderSetPictureTransform( dpy, picture, &xform );
+
+ XRenderComposite( QPaintDevice::x11AppDisplay(),
+ hasAlpha ? PictOpOver : PictOpSrc,
+ picture,
+ None,
+ pix->x11RenderHandle(),
+ 0, 0, 0, 0,
+ 0, 0, pix->width(), pix->height() );
+ #endif
+
+ }
+ else
+ {*/
+ // Scale and render screenshot on scaledScreenshot
+ imlib_context_set_anti_alias(1);
+ imlib_context_set_drawable( screenshot.handle() );
+ Imlib_Image imgOrig = imlib_create_image_from_drawable((Pixmap)0, 0, 0, screenshot.width(), screenshot.height(), 1);
+ imlib_context_set_image( imgOrig );
+ Imlib_Image img = imlib_create_cropped_scaled_image(0, 0, screenshot.width(), screenshot.height(), newSize.width(), newSize.height());
+ imlib_free_image();
+ imlib_context_set_image( img );
+ applyEffect();
+ imlib_context_set_drawable( scaledScreenshot.handle() );
+ imlib_render_image_on_drawable_at_size(0, 0, newSize.width(), newSize.height());
+ imlib_free_image();
+ // }
+ scaledScreenshotDirty = false;
+}
+
+
+
+/**
+ * Called whenever the Window has been activated
+ */
+void KomposeTaskVisualizer::slotTaskActivated()
+{
+ if ( KomposeGlobal::instance()->hasXcomposite() && KomposeSettings::instance()->getUseComposite() )
+ {
+ return;
+ }
+
+ if ( KomposeViewManager::instance()->getBlockScreenshots() && !screenshotSuspended )
+ {
+ // Retry 1 sec later
+ screenshotSuspended = true;
+ QTimer::singleShot( 500, this, SLOT( slotTaskActivated() ) );
+ }
+ screenshotSuspended = false;
+
+ // Grab a Passive Screenshot
+ if ( KomposeSettings::instance()->getPassiveScreenshots() &&
+ !KomposeViewManager::instance()->hasActiveView() &&
+ !KomposeViewManager::instance()->getBlockScreenshots() )
+ {
+ kdDebug() << "KomposeTaskVisualizer::slotTaskActivated() (WId " << task->window() << ") - Screenshot already exists, but passive mode on - Grabbing new one." << endl;
+ // Use a timer to make task switching feel more responsive
+ QTimer::singleShot( 300, this, SLOT( captureScreenshot_GrabWindow() ) );
+ //captureScreenshot_GrabWindow();
+ }
+}
+
+
+/**
+ * Called whenever Kompose needs a screenshot to display (normally before a view is shown)
+ */
+void KomposeTaskVisualizer::slotUpdateScreenshot()
+{
+#ifdef COMPOSITE
+ if ( KomposeGlobal::instance()->hasXcomposite() && KomposeSettings::instance()->getUseComposite() )
+ {
+ if ( !validBackingPix )
+ {
+ kdDebug() << "KomposeTaskVisualizer::slotUpdateScreenshot() (WId " << task->window() << ") - No backing pixmap referenced. Bad :(" << endl;
+ // When we get here we have never referenced a backingpix...
+ // FIXME: Currently it seems that there is no way to retrieve unmapped backing pixmaps,
+ // even switching desktops won't work due to the latency of XComposite :(
+ }
+ return;
+ }
+#endif
+
+ // If no screenshot exists grab one via activate/raise & capture
+ if ( screenshot.isNull() )
+ {
+ bool iconifyLater = false;
+
+ if ( task->isIconified() == true )
+ {
+ kdDebug() << "KomposeTaskVisualizer::slotUpdateScreenshot() (WId " << task->window() << ") - Window iconified... we have to raise it and iconify it again later." << endl;
+ iconifyLater = true;
+ }
+
+ kdDebug() << "KomposeTaskVisualizer::slotUpdateScreenshot() (WId " << task->window() << ") - Forcing activation (no screenshot exists)" << endl;
+
+ task->activate();
+ QApplication::flushX();
+ QApplication::syncX();
+
+ // Wait until window is fully redrawn
+ struct timespec req, rem;
+ req.tv_sec = 0;
+ req.tv_nsec = KomposeSettings::instance()->getScreenshotGrabDelay();
+ while(nanosleep(&req, &rem))
+ req = rem;
+
+ QApplication::flushX();
+ //task->refresh();
+
+ // Finally capture!
+ screenshot = QPixmap::grabWindow( task->window() );
+ //captureScreenshot_GrabWindow();
+
+ // Restore if formerly iconified
+ if ( iconifyLater )
+ QTimer::singleShot( 1000, task, SLOT( iconify() ) );
+
+ scaledScreenshotDirty = true;
+ }
+}
+
+
+/**
+ * This should be called whenever the window is unmapped as XComposite will reallocate
+ * or the backing pixmap (on resize, minimize, virt desk change, etc)
+ */
+void KomposeTaskVisualizer::updateXCompositeNamedPixmap()
+{
+#ifdef COMPOSITE
+ if ( compositeInit &&
+ KomposeGlobal::instance()->hasXcomposite() && KomposeSettings::instance()->getUseComposite())
+ {
+ if( !task->isOnCurrentDesktop() )
+ {
+ kdDebug() << "KomposeTaskVisualizer::updateXCompositeNamedPixmap() (WId " << task->window() << ") - Not reallocationg (unmapped)" << endl;
+ return;
+ }
+
+ kdDebug() << "KomposeTaskVisualizer::updateXCompositeNamedPixmap() (WId " << task->window() << ") - Reallocating backing pixmap" << endl;
+ if ( validBackingPix )
+ XFreePixmap(dpy, windowBackingPix);
+
+ windowBackingPix = XCompositeNameWindowPixmap(dpy, task->wmFrame() );
+
+ validBackingPix = true;
+ scaledScreenshotDirty = true;
+ }
+#endif
+}
+
+
+/**
+ * Initialise Composite backing store for this window
+ */
+void KomposeTaskVisualizer::initXComposite()
+{
+#ifdef COMPOSITE
+ if ( !compositeInit && KomposeGlobal::instance()->hasXcomposite() && KomposeSettings::instance()->getUseComposite())
+ {
+ dpy = QPaintDevice::x11AppDisplay();
+
+ connect( task, SIGNAL(x11ConfigureNotify()), this, SLOT(updateXCompositeNamedPixmap()));
+ XSelectInput( dpy, task->wmFrame(), StructureNotifyMask );
+ connect( task, SIGNAL( x11DamageNotify() ), SLOT( setScaledScreenshotDirty() ) );
+
+ XWindowAttributes attr;
+ XGetWindowAttributes( dpy, task->wmFrame(), &attr );
+ format = XRenderFindVisualFormat( dpy, attr.visual );
+ hasAlpha = ( format->type == PictTypeDirect && format->direct.alphaMask ); //FIXME: move this to komposetask
+ // int x = attr.x;
+ // int y = attr.y;
+ // int width = attr.width;
+ // int height = attr.height;
+ pa.subwindow_mode = IncludeInferiors; // Don't clip child widgets
+ compositeInit = true;
+ updateXCompositeNamedPixmap();
+
+ kdDebug() << "KomposeTaskVisualizer::initXComposite() (WId " << task->window() << ") - Setting up Damage extension" << endl;
+ // Create a damage handle for the window, and specify that we want an event whenever the
+ // damage state changes from not damaged to damaged.
+ damage = XDamageCreate( dpy, task->window(), XDamageReportNonEmpty );
+ }
+ else
+ {
+ disconnect( task, SIGNAL(x11ConfigureNotify()), this, SLOT(updateXCompositeNamedPixmap()));
+ disconnect( task, SIGNAL( x11DamageNotify() ), this, SLOT( setScaledScreenshotDirty() ) );
+ if ( compositeInit )
+ {
+ XDamageDestroy( dpy, damage);
+ compositeInit = false;
+ }
+ }
+#endif
+}
+
+
+/**
+ * Grabs a screenshot the old fashioned way
+ */
+void KomposeTaskVisualizer::captureScreenshot_GrabWindow()
+{
+ if ( screenshotBlocked || ( !(task->isActive() && task->isOnTop()) ) )
+ {
+ kdDebug() << "KomposeTaskVisualizer::captureScreenshot_GrabWindow() (WId " << task->window() << ") - Could not grab screenshot." << endl;
+ return;
+ }
+ //task->activate();
+
+
+ // QWidget *rootWin = qApp->desktop();
+ // screenshot = QPixmap::grabWindow( rootWin->winId(), geom.x(), geom.y(), geom.width(), geom.height() );
+
+ screenshot = QPixmap::grabWindow( task->window() );
+ scaledScreenshotDirty = true;
+
+ // We've just grabbed a screenshot and don't want this to happen again in the next 3?! seconds
+ screenshotBlocked = true;
+ QTimer::singleShot( 3000, this, SLOT( enablePasvScreenshots() ) );
+
+ kdDebug() << "KomposeTaskVisualizer::captureScreenshot_GrabWindow() (WId " << task->window() << ") - Grabbed screenshot." << endl;
+
+ // Code to create a screenshot directly as an Imlib image
+
+ // QRect geom = windowInfo.geometry();
+ // Display *disp;
+ // Visual *vis;
+ // Colormap cm;
+ // int screen;
+ //
+ // //get display information
+ // disp = XOpenDisplay(0);
+ // screen = DefaultScreen(disp);
+ // vis = DefaultVisual(disp, screen);
+ // cm = DefaultColormap(disp, screen);
+ //
+ // //set imlib properties
+ // imlib_context_set_display(disp);
+ // imlib_context_set_visual(vis);
+ // imlib_context_set_colormap(cm);
+ // imlib_context_set_drawable(RootWindow(disp, screen));
+ // imlib_context_set_anti_alias(1);
+ // imlib_context_set_blend(0);
+ //
+ // Imlib_Image img = imlib_create_image_from_drawable((Pixmap)0,geom.x(), geom.y(), geom.width(), geom.height(),1);
+ //
+ //
+ // screenshot->setImage( img );
+ //
+ // XCloseDisplay(disp);
+
+ //kdDebug() << "KomposeTaskVisualizer::captureScreenshot() - Created Screenshot: x:%d y:%d size:%dx%d", geom.x(), geom.y(), screenshot->originalWidth(), screenshot->originalHeight() );
+}
+
+void KomposeTaskVisualizer::enablePasvScreenshots()
+{
+ screenshotBlocked = false;
+}
+
+void KomposeTaskVisualizer::clearCached()
+{
+ scaledScreenshot.resize(0,0);
+}
+
+
+void KomposeTaskVisualizer::applyEffect()
+{
+ imlib_context_set_color_modifier(0);
+
+ if ( lasteffect == IEFFECT_MINIMIZED || lasteffect == IEFFECT_MINIMIZED_AND_TITLE )
+ {
+ //FIXME: maybe there is a faster tint filter?!
+ imlib_context_set_color_modifier(cmMinimized);
+ }
+
+ if ( lasteffect == IEFFECT_HIGHLIGHT )
+ {
+ //FIXME: maybe there is a faster tint filter?!
+ imlib_context_set_color_modifier(cmHighlight);
+ }
+
+ if ( lasteffect == IEFFECT_TITLE || lasteffect == IEFFECT_MINIMIZED_AND_TITLE )
+ {
+ /* we can blend stuff now */
+ imlib_context_set_blend(1);
+ /* our color range */
+ Imlib_Color_Range range;
+
+ /* draw a gradient on top of things at the top left of the window */
+ /* create a range */
+ range = imlib_create_color_range();
+ imlib_context_set_color_range(range);
+ imlib_context_set_color(255, 255, 255, 0);
+ imlib_add_color_to_color_range(0);
+ imlib_context_set_color(255, 255, 255, 255);
+ imlib_add_color_to_color_range(1000);
+ /* draw the range */
+ //imlib_context_set_image(myIm);
+ imlib_image_fill_color_range_rectangle(0, 0, scaledScreenshot.width(), KomposeSettings::instance()->getWindowTitleFontAscent() * 3, -180.0);
+ /* free it */
+ imlib_free_color_range();
+ }
+
+}
+
+#include "komposetaskvisualizer.moc"
diff --git a/src/komposetaskvisualizer.h b/src/komposetaskvisualizer.h
new file mode 100644
index 0000000..73419f4
--- /dev/null
+++ b/src/komposetaskvisualizer.h
@@ -0,0 +1,87 @@
+//
+// C++ Interface: %{MODULE}
+//
+// Description:
+//
+//
+// Author: %{AUTHOR} <%{EMAIL}>, (C) %{YEAR}
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#ifndef KOMPOSETASKVISUALIZER_H
+#define KOMPOSETASKVISUALIZER_H
+
+#include <qobject.h>
+
+#include "komposetask.h"
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <Imlib2.h>
+
+#ifdef COMPOSITE
+#include <X11/Xatom.h>
+#include <X11/extensions/Xcomposite.h>
+#include <X11/extensions/Xdamage.h>
+#include <X11/extensions/Xrender.h>
+#endif
+
+enum ImageEffect { IEFFECT_NONE, IEFFECT_TITLE, IEFFECT_MINIMIZED, IEFFECT_MINIMIZED_AND_TITLE, IEFFECT_HIGHLIGHT };
+
+class QPixmap;
+class QSize;
+
+/**
+@author Hans Oischinger
+*/
+class KomposeTaskVisualizer : public QObject
+{
+ Q_OBJECT
+public:
+ KomposeTaskVisualizer(KomposeTask *parent, const char *name = 0);
+ ~KomposeTaskVisualizer();
+
+ void renderOnPixmap( QPixmap* pix, int effect );
+
+protected:
+ void applyEffect();
+
+protected slots:
+ void initXComposite();
+ void captureScreenshot_GrabWindow();
+ void updateXCompositeNamedPixmap();
+ void renderScaledScreenshot( QSize size );
+
+ void setScaledScreenshotDirty() { scaledScreenshotDirty = true; }
+ void clearCached();
+ void enablePasvScreenshots();
+
+public slots:
+ void slotTaskActivated();
+ void slotUpdateScreenshot();
+
+private:
+ KomposeTask *task;
+ QPixmap screenshot;
+ QPixmap scaledScreenshot;
+ bool scaledScreenshotDirty;
+ bool screenshotSuspended; // suspend pasv screenshots for this task
+ bool screenshotBlocked; // dis/enable pasv screenshots for this task
+
+ Imlib_Color_Modifier cmHighlight, cmMinimized;
+ int lasteffect; // the effect that has been applied to scaledScreenshot
+
+#ifdef COMPOSITE
+ Pixmap windowBackingPix;
+ bool validBackingPix;
+ Display *dpy;
+ XRenderPictFormat *format;
+ XRenderPictureAttributes pa;
+ bool hasAlpha;
+ Damage damage;
+ bool compositeInit; // true if composite&damage has been initialised
+#endif
+};
+
+#endif
diff --git a/src/komposetaskwidget.cpp b/src/komposetaskwidget.cpp
new file mode 100644
index 0000000..3d4abfe
--- /dev/null
+++ b/src/komposetaskwidget.cpp
@@ -0,0 +1,427 @@
+/***************************************************************************
+ * Copyright (C) 2004 by Hans Oischinger *
+ * *
+ * 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 "komposetaskwidget.h"
+
+#include "komposetaskmanager.h"
+#include "komposeviewmanager.h"
+#include "komposetask.h"
+#include "komposetaskcontainerwidget.h"
+#include "komposetaskprefswidget.h"
+#include "komposesettings.h"
+#include "komposeglobal.h"
+#include "komposesettings.h"
+
+#include <qpixmap.h>
+#include <qimage.h>
+#include <qpainter.h>
+#include <qdragobject.h>
+#include <qapplication.h>
+#include <qtooltip.h>
+#include <qiconset.h>
+#include <qtimer.h>
+#include <qcolor.h>
+#include <qfont.h>
+
+#include <kcursor.h>
+#include <klocale.h>
+#include <kpopupmenu.h>
+#include <kactioncollection.h>
+#include <kaction.h>
+#include <kapplication.h>
+#include <kiconloader.h>
+#include <kdebug.h>
+
+#include "komposetaskvisualizer.h"
+
+KomposeTaskWidget::KomposeTaskWidget(KomposeTask *t, QWidget *parent, KomposeLayout *l, const char *name)
+ : KomposeWidget(parent, l, name),
+ highlight(false),
+ task(t)
+{
+ setWFlags( WStaticContents | WRepaintNoErase | WResizeNoErase ); // avoid redraw errors
+ setBackgroundMode( Qt::NoBackground ); // avoid flickering
+
+ QToolTip::add( this, task->visibleNameWithState() );
+
+ pm_dbBackground.setOptimization( QPixmap::BestOptim );
+ setBackgroundMode( Qt::NoBackground );
+ //setBackgroundPixmap(pm_dbBackground);
+
+ initActions();
+ initMenu();
+ prefWidget = new KomposeTaskPrefsWidget( this, "Task prefs" );
+ prefWidget->hide();
+ setActionIcons();
+
+ //connect( t, SIGNAL( destroyed() ), this, SLOT( slotTaskDestroyed() ) );
+ connect( t, SIGNAL( closed() ), this, SLOT( slotTaskDestroyed() ) );
+ connect( t, SIGNAL( stateChanged() ), this, SLOT( drawWidgetAndRepaint() ) );
+ connect( t, SIGNAL( stateChanged() ), this, SLOT( reInitMenu() ) );
+
+#ifdef COMPOSITE
+ if ( KomposeGlobal::instance()->hasXcomposite() && KomposeSettings::instance()->getUseComposite() )
+ {
+ connect( t, SIGNAL( x11DamageNotify() ), this, SLOT( drawWidgetAndRepaint() ) );
+ }
+#endif
+ //setFocusPolicy(QWidget::ClickFocus);
+ setFocusPolicy(QWidget::StrongFocus);
+
+ initFonts();
+}
+
+
+KomposeTaskWidget::~KomposeTaskWidget()
+{
+ prefWidget->deleteLater();
+ menu->deleteLater();
+
+ delete actMinimizeRestoreTask;
+ delete actCloseTask;
+ delete taskActionCollection;
+}
+
+void KomposeTaskWidget::reInitMenu()
+{
+ delete menu;
+ initMenu();
+}
+
+void KomposeTaskWidget::initFonts()
+{
+ titleFont = KomposeSettings::instance()->getWindowTitleFont();
+}
+
+void KomposeTaskWidget::slotTaskDestroyed()
+{
+ disconnect( task, SIGNAL( closed() ), this, SLOT( slotTaskDestroyed() ) );
+ disconnect( task, SIGNAL( stateChanged() ), this, SLOT( drawWidgetAndRepaint() ) );
+
+ //if (KomposeViewManager::instance()->hasActiveView())
+ emit requestRemoval(this);
+}
+void KomposeTaskWidget::resizeEvent ( QResizeEvent * e )
+{
+ if ( e->oldSize() != e->size())
+ {
+ prefWidget->move(width() - prefWidget->width() - 3, 3);
+ drawWidgetAndRepaint();
+ }
+ KomposeWidget::resizeEvent( e );
+}
+
+
+void KomposeTaskWidget::paintEvent ( QPaintEvent * )
+{
+ if (size().height() < 40 ) // small hack that will prevent drawing on init
+ return;
+
+ if ( pm_dbBackground.isNull() )
+ drawWidget();
+ bitBlt( this, 0, 0, &pm_dbBackground, 0, 0, width(), height() );
+}
+
+void KomposeTaskWidget::drawWidgetAndRepaint()
+{
+ if (size().height() < 40 ) // small hack that will prevent drawing on init
+ return;
+
+ drawWidget();
+ repaint();
+}
+
+void KomposeTaskWidget::drawWidget()
+{
+ if ( !KomposeViewManager::instance()->hasActiveView() || !isShown() )
+ return;
+
+ pm_dbBackground.resize( width(), height() );
+ //pm_dbBackground.fill(white);
+
+ QPainter p( &pm_dbBackground );
+
+ int effect = IEFFECT_NONE;
+
+ if ( KomposeSettings::instance()->getShowWindowTitles() && !task->isIconified() )
+ effect = IEFFECT_TITLE;
+ if ( KomposeSettings::instance()->getShowWindowTitles() && task->isIconified() )
+ effect = IEFFECT_MINIMIZED_AND_TITLE;
+ if ( !KomposeSettings::instance()->getShowWindowTitles() && task->isIconified() )
+ effect = IEFFECT_MINIMIZED;
+ // if ( highlight ) // I hate it, so I disable it!
+ // effect = IEFFECT_HIGHLIGHT;
+
+ task->getVisualizer()->renderOnPixmap(&pm_dbBackground, effect);
+
+ // Icon
+ QPoint titleTextPos( 6, KomposeSettings::instance()->getWindowTitleFontHeight() + 1);
+ if ( KomposeSettings::instance()->getShowIcons() )
+ {
+ QPixmap icon = task->getIcon( KomposeSettings::instance()->getIconSizePixels() );
+
+ // Place the icon left or under the text, according to it's size
+ if ( KomposeSettings::instance()->getIconSize() < 2 || icon.height() < 50 )
+ {
+ // Medium sized or tiny Icon
+ p.drawPixmap( QPoint(5, 5), icon );
+ titleTextPos.setX(icon.width() + 10);
+ }
+ else
+ {
+ // Big Icon
+ p.drawPixmap( QPoint(5, 5), icon );
+ // titleTextPos.setX(icon.width());
+ }
+ }
+
+ // Title
+ if ( KomposeSettings::instance()->getShowWindowTitles() )
+ {
+ p.setFont(titleFont);
+ if ( KomposeSettings::instance()->getShowWindowTitleShadow() )
+ {
+ p.setPen( KomposeSettings::instance()->getWindowTitleFontShadowColor() );
+ p.drawText( titleTextPos, task->visibleNameWithState() );
+ }
+ p.setPen( KomposeSettings::instance()->getWindowTitleFontColor() );
+ p.drawText( QPoint( titleTextPos.x()-2, titleTextPos.y()-2 ), task->visibleNameWithState() );
+ }
+
+ // Border
+ if (!highlight)
+ {
+ QPen pen( gray, 1, Qt::SolidLine );
+ p.setPen( pen );
+ p.drawRect(rect());
+ }
+ else
+ {
+ QPen pen( black, 2, Qt::DotLine );
+ p.setPen( pen );
+ p.drawRect( QRect( 1, 1, rect().width()-1, rect().height()-1 ) );
+ }
+
+ p.end();
+}
+
+void KomposeTaskWidget::mouseReleaseEvent ( QMouseEvent * e )
+{
+ if ( !rect().contains( e->pos() ) )
+ return;
+ KomposeViewManager::instance()->activateTask( task );
+}
+
+void KomposeTaskWidget::mouseMoveEvent ( QMouseEvent * e )
+{
+ if ( e->state() == Qt::LeftButton )
+ startDrag();
+}
+
+// void KomposeTaskWidget::mouseDoubleClickEvent ( QMouseEvent * e )
+// {
+// if ( !rect().contains( e->pos() ) )
+// return;
+// KomposeTaskManager::instance()->activateTask( task );
+// }
+
+void KomposeTaskWidget::keyReleaseEvent ( QKeyEvent * e )
+{
+ if ( e->key() == Qt::Key_Return || e->key() == Qt::Key_Space )
+ {
+ kdDebug() << "KomposeTaskWidget::keyReleaseEvent - activating Task!" << endl;
+ e->accept();
+ KomposeViewManager::instance()->activateTask( task );
+ return;
+ }
+ else if ( e->key() == Qt::Key_C )
+ {
+ kdDebug() << "KomposeTaskWidget::keyReleaseEvent - closing Task!" << endl;
+ task->close();
+ e->accept();
+ }
+ else if ( e->key() == Qt::Key_M )
+ {
+ kdDebug() << "KomposeTaskWidget::keyReleaseEvent - toggling state!" << endl;
+ task->minimizeOrRestore();
+ e->accept();
+ }
+ else
+ {
+ kdDebug() << "KomposeTaskWidget::keyReleaseEvent - ignored..." << endl;
+ e->ignore();
+ }
+ KomposeWidget::keyReleaseEvent(e);
+}
+
+void KomposeTaskWidget::leaveEvent ( QEvent * )
+{
+ highlight = false;
+ unsetCursor();
+// drawWidgetAndRepaint();
+
+ prefWidget->hide();
+ if ( parentWidget() )
+ parentWidget()->setFocus();
+}
+
+void KomposeTaskWidget::enterEvent ( QEvent * )
+{
+ setFocus();
+ setCursor( KCursor::handCursor() );
+ highlight = true;
+// drawWidgetAndRepaint();
+
+ prefWidget->show();
+}
+
+void KomposeTaskWidget::focusInEvent ( QFocusEvent * )
+{
+ highlight = true;
+ drawWidgetAndRepaint();
+}
+
+void KomposeTaskWidget::focusOutEvent ( QFocusEvent * )
+{
+ highlight = false;
+ drawWidgetAndRepaint();
+}
+
+int KomposeTaskWidget::getHeightForWidth ( int w ) const
+{
+ //kdDebug() << "KomposeTaskWidget::getHeightForWidth()");
+ return task->getHeightForWidth(w);
+}
+
+int KomposeTaskWidget::getWidthForHeight ( int h ) const
+{
+ //kdDebug() << "KomposeTaskWidget::getWidthForHeight()");
+ return task->getWidthForHeight(h);
+}
+
+double KomposeTaskWidget::getAspectRatio()
+{
+ //kdDebug() << "KomposeTaskWidget::getAspectRatio()");
+ return task->getAspectRatio();
+}
+
+void KomposeTaskWidget::startDrag()
+{
+ // The text is just a dummy
+ // FIXME: Maybe we should us a "Task"-Mimetype
+ QDragObject *d = new QTextDrag( "toDesktop()", this );
+ d->dragCopy();
+}
+
+void KomposeTaskWidget::setGeometry( const QRect &rect )
+{
+ int width = task->getGeometry().width();
+ int height = task->getGeometry().height();
+
+ // Don't scale images bigger than they actually are
+ if ( rect.width() > width || rect.height() > height )
+ {
+ QWidget::setGeometry( QRect( rect.left(), rect.top(), width, height ) );
+ }
+ else
+ QWidget::setGeometry( rect );
+}
+
+void KomposeTaskWidget::initActions()
+{
+ taskActionCollection = new KActionCollection( this );
+
+ actCloseTask = new KAction( i18n("Close"), "fileclose", Key_Delete , task,
+ SLOT( close() ), taskActionCollection, "closeTask" );
+ actCloseTask->setToolTip(i18n("Close"));
+ actMinimizeRestoreTask = new KAction( i18n("Minimize/Restore"), "", KShortcut() , this,
+ SLOT( slotMinimizeRestoreToggled() ), taskActionCollection, "minimizeRestoreTask" );
+}
+
+void KomposeTaskWidget::initMenu()
+{
+ menu = new KPopupMenu();
+
+ actMinimizeRestoreTask->plug(menu);
+
+ // toDesktop menu
+ QPopupMenu* m = new QPopupMenu( this );
+ m->setCheckable( true );
+
+ int id = m->insertItem( i18n("&All Desktops"), task, SLOT( toDesktop(int) ) );
+ m->setItemParameter( id, 0 ); // 0 means all desktops
+ m->setItemChecked( id, task->isOnAllDesktops() );
+
+ m->insertSeparator();
+
+ for( int i = 1; i <= KomposeTaskManager::instance()->getNumDesktops(); i++ )
+ {
+ QString name = QString( "&%1 %2" ).arg( i ).arg( KomposeTaskManager::instance()->getDesktopName( i ).replace( '&', "&&" ) );
+ id = m->insertItem( name, task, SLOT( toDesktop(int) ) );
+ m->setItemParameter( id, i );
+ m->setItemChecked( id, !task->isOnAllDesktops() && task->onDesktop() == i );
+ }
+ menu->insertItem(i18n("To &Desktop"), m);
+
+ menu->insertSeparator();
+ actCloseTask->plug(menu);
+
+}
+
+/**
+ * Set the toggle icons for some actions
+ *
+ * The inverse flag is a hack to allow toggling of the icons when the minimized/restored event
+ * hasn't yet reached the Task object ( which is the case on buttonpress)
+ */
+void KomposeTaskWidget::setActionIcons( bool inverse )
+{
+ if ( ( task->isIconified() && !inverse ) || ( !task->isIconified() && inverse ) )
+ actMinimizeRestoreTask->setIconSet( kapp->iconLoader()->loadIconSet ( "up", KIcon::NoGroup, 16 ) );
+ else
+ actMinimizeRestoreTask->setIconSet( kapp->iconLoader()->loadIconSet ( "bottom", KIcon::NoGroup, 16 ) );
+}
+
+void KomposeTaskWidget::slotMinimizeRestoreToggled()
+{
+ setActionIcons( true );
+ task->minimizeOrRestore();
+}
+
+void KomposeTaskWidget::mousePressEvent ( QMouseEvent * e )
+{
+ if ( !rect().contains( e->pos() ) )
+ return;
+
+ switch ( e->button() )
+ {
+ case LeftButton:
+ break;
+ case MidButton:
+ // fall through
+ case RightButton:
+ menu->popup( e->globalPos() );
+ break;
+ default:
+ // nothing
+ break;
+ }
+}
+
+#include "komposetaskwidget.moc"
diff --git a/src/komposetaskwidget.h b/src/komposetaskwidget.h
new file mode 100644
index 0000000..ab1a1a9
--- /dev/null
+++ b/src/komposetaskwidget.h
@@ -0,0 +1,100 @@
+/***************************************************************************
+ * Copyright (C) 2004 by Hans Oischinger *
+ * *
+ * 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. *
+ ***************************************************************************/
+#ifndef KOMPOSETASKWIDGET_H
+#define KOMPOSETASKWIDGET_H
+
+#include "komposewidget.h"
+#include "komposetaskprefswidget.h"
+
+#include <qimage.h>
+#include <qpixmap.h>
+
+
+class KomposeTask;
+class KomposeLayout;
+class KPopupMenu;
+class KAction;
+class KActionCollection;
+
+/**
+@author Hans Oischinger
+*/
+class KomposeTaskWidget : public KomposeWidget
+{
+ Q_OBJECT
+public:
+ KomposeTaskWidget(KomposeTask *t, QWidget *parent = 0, KomposeLayout *l = 0, const char *name = 0);
+
+ ~KomposeTaskWidget();
+
+ int getHeightForWidth( int w ) const;
+ int getWidthForHeight( int h ) const;
+ double getAspectRatio();
+
+ KomposeTask* getTask() const { return task; };
+ KAction* getActMinimizeRestoreTask() { return actMinimizeRestoreTask; }
+ KAction* getActCloseTask() { return actCloseTask; }
+
+signals:
+ void requestRemoval(KomposeWidget*);
+
+protected:
+ void paintEvent ( QPaintEvent * );
+ void mouseReleaseEvent ( QMouseEvent * e );
+ void mousePressEvent ( QMouseEvent * e );
+ void mouseMoveEvent ( QMouseEvent * e );
+ void leaveEvent ( QEvent * );
+ void enterEvent ( QEvent * );
+ void resizeEvent ( QResizeEvent * );
+ void focusInEvent ( QFocusEvent * );
+ void focusOutEvent ( QFocusEvent * );
+ void keyReleaseEvent ( QKeyEvent * e );
+
+ void startDrag();
+ void initActions();
+ void initMenu();
+
+protected slots:
+ void slotTaskDestroyed();
+ void drawWidget();
+ void drawWidgetAndRepaint();
+ void initFonts();
+ void setGeometry( const QRect &rect );
+ void reInitMenu();
+
+ void slotMinimizeRestoreToggled();
+ void setActionIcons( bool inverse=false );
+
+private:
+ QPixmap pm_dbBackground;
+
+ bool highlight; // Highlight widget?
+ QFont titleFont;
+
+ KomposeTask* task;
+ KomposeTaskPrefsWidget *prefWidget;
+ KPopupMenu *menu;
+
+ KActionCollection *taskActionCollection;
+ KAction *actMinimizeRestoreTask;
+ KAction *actCloseTask;
+};
+
+#endif
diff --git a/src/komposeui.rc b/src/komposeui.rc
new file mode 100644
index 0000000..899375f
--- /dev/null
+++ b/src/komposeui.rc
@@ -0,0 +1,8 @@
+<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
+<kpartgui name="kompose" version="1">
+<MenuBar>
+ <Menu name="custom"><text>C&amp;ustom</text>
+ <Action name="custom_action" />
+ </Menu>
+</MenuBar>
+</kpartgui>
diff --git a/src/komposeviewmanager.cpp b/src/komposeviewmanager.cpp
new file mode 100644
index 0000000..57359d3
--- /dev/null
+++ b/src/komposeviewmanager.cpp
@@ -0,0 +1,258 @@
+//
+// C++ Implementation: %{MODULE}
+//
+// Description:
+//
+//
+// Author: %{AUTHOR} <%{EMAIL}>, (C) %{YEAR}
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#include "komposeviewmanager.h"
+
+#include "komposetaskmanager.h"
+#include "komposeglobal.h"
+#include "komposesettings.h"
+#include "komposesystray.h"
+
+#include <qtimer.h>
+#include <qcursor.h>
+#include <qapplication.h>
+#include <qptrlist.h>
+#include <qwidgetlist.h>
+#include <qdesktopwidget.h>
+
+#include <kwin.h>
+#include <kapplication.h>
+#include <kdebug.h>
+
+
+static KomposeViewManager* viewManagerInstance = 0;
+
+/**
+ * Viewmanager is a singleton
+ */
+KomposeViewManager* KomposeViewManager::instance()
+{
+ if ( !viewManagerInstance )
+ {
+ kdDebug() << "KomposeViewManager::instance() - Creating Singleton instance" << endl;
+ viewManagerInstance = new KomposeViewManager();
+ }
+ return viewManagerInstance;
+}
+
+KomposeViewManager::KomposeViewManager():
+ DCOPObject( "KomposeDcopIface" ),
+ QObject(),
+ viewWidget(),
+ activeView(0),
+ blockScreenshots(0)
+{
+ viewManagerInstance = this;
+
+ // Setup cursorupdate timer to check for mouse moves into corner
+ cursorUpdateTimer = new QTimer();
+ slotStartCursorUpdateTimer();
+
+ // dirty hack. see uglyQtHackInitFunction()
+ QTimer::singleShot( 500, this, SLOT( uglyQtHackInitFunction() ) );
+}
+
+
+KomposeViewManager::~KomposeViewManager()
+{
+ delete cursorUpdateTimer;
+}
+
+
+/**
+ * This is a hack that should be called by a timer as this connect won't work in the constructor
+ */
+void KomposeViewManager::uglyQtHackInitFunction()
+{
+ connect( KomposeSettings::instance(), SIGNAL( settingsChanged() ), SLOT( slotStartCursorUpdateTimer() ) );
+}
+
+/**
+ * Starts the corner check timer which polls QCursor::pos() every second
+ @see checkCursorPos()
+ */
+void KomposeViewManager::slotStartCursorUpdateTimer()
+{
+ disconnect( cursorUpdateTimer, SIGNAL( timeout() ), this, SLOT( checkCursorPos() ) );
+
+ if ( KomposeSettings::instance()->getActivateOnBottomLeftCorner() ||
+ KomposeSettings::instance()->getActivateOnBottomRightCorner() ||
+ KomposeSettings::instance()->getActivateOnTopLeftCorner() ||
+ KomposeSettings::instance()->getActivateOnTopRightCorner() ||
+ KomposeSettings::instance()->getActivateOnTopEdge() ||
+ KomposeSettings::instance()->getActivateOnBottomEdge() ||
+ KomposeSettings::instance()->getActivateOnLeftEdge() ||
+ KomposeSettings::instance()->getActivateOnRightEdge() )
+ {
+ kdDebug() << "KomposeViewManager::slotStartCursorUpdateTimer() - QCursor::pos() checks enabled" << endl;
+ QRect deskRect = QApplication::desktop()->screenGeometry();
+
+ topLeftCorner = deskRect.topLeft();
+ topRightCorner = deskRect.topRight();
+ bottomLeftCorner = deskRect.bottomLeft();
+ bottomRightCorner = deskRect.bottomRight();
+
+ connect( cursorUpdateTimer, SIGNAL( timeout() ), SLOT( checkCursorPos() ) );
+ cursorUpdateTimer->start( 200, false ); // TODO: Find out why even an interval of 1ms doesn't hit performance!
+ }
+}
+
+
+/**
+ * Checks if cursor hovered over a corner that activates Kompose
+ */
+void KomposeViewManager::checkCursorPos()
+{
+ if (
+ ( KomposeSettings::instance()->getActivateOnTopLeftCorner() &&
+ !activeView && QCursor::pos() == topLeftCorner ) ||
+ ( KomposeSettings::instance()->getActivateOnTopRightCorner() &&
+ !activeView && QCursor::pos() == topRightCorner ) ||
+ ( KomposeSettings::instance()->getActivateOnBottomLeftCorner() &&
+ !activeView && QCursor::pos() == bottomLeftCorner ) ||
+ ( KomposeSettings::instance()->getActivateOnBottomRightCorner() &&
+ !activeView && QCursor::pos() == bottomRightCorner ) ||
+ ( KomposeSettings::instance()->getActivateOnTopEdge() &&
+ !activeView && QCursor::pos().y() == topLeftCorner.y() ) ||
+ ( KomposeSettings::instance()->getActivateOnBottomEdge() &&
+ !activeView && QCursor::pos().y() == bottomLeftCorner.y() ) ||
+ ( KomposeSettings::instance()->getActivateOnLeftEdge() &&
+ !activeView && QCursor::pos().x() == topLeftCorner.x() ) ||
+ ( KomposeSettings::instance()->getActivateOnRightEdge() &&
+ !activeView && QCursor::pos().x() == topRightCorner.x() )
+ )
+ {
+ //cursorUpdateTimer->stop();
+ QTimer::singleShot( KomposeSettings::instance()->getAutoLockDelay(), this, SLOT( reCheckCursorPos() ) );
+ }
+}
+
+/**
+ * Called after the cursor was in a hotspot to check if it's still there
+ */
+void KomposeViewManager::reCheckCursorPos()
+{
+ if (
+ ( KomposeSettings::instance()->getActivateOnTopLeftCorner() &&
+ !activeView && QCursor::pos() == topLeftCorner ) ||
+ ( KomposeSettings::instance()->getActivateOnTopRightCorner() &&
+ !activeView && QCursor::pos() == topRightCorner ) ||
+ ( KomposeSettings::instance()->getActivateOnBottomLeftCorner() &&
+ !activeView && QCursor::pos() == bottomLeftCorner ) ||
+ ( KomposeSettings::instance()->getActivateOnBottomRightCorner() &&
+ !activeView && QCursor::pos() == bottomRightCorner ) ||
+ ( KomposeSettings::instance()->getActivateOnTopEdge() &&
+ !activeView && QCursor::pos().y() == topLeftCorner.y() ) ||
+ ( KomposeSettings::instance()->getActivateOnBottomEdge() &&
+ !activeView && QCursor::pos().y() == bottomLeftCorner.y() ) ||
+ ( KomposeSettings::instance()->getActivateOnLeftEdge() &&
+ !activeView && QCursor::pos().x() == topLeftCorner.x() ) ||
+ ( KomposeSettings::instance()->getActivateOnRightEdge() &&
+ !activeView && QCursor::pos().x() == topRightCorner.x() )
+ )
+ {
+ cursorUpdateTimer->stop();
+ createView();
+ }
+}
+
+
+void KomposeViewManager::createView( int type )
+{
+ if (KomposeSettings::instance()->hasDialogOpen() ||
+ KomposeGlobal::instance()->hasAboutDialogOpen())
+ {
+ kdDebug() << "KomposeViewManager::createView() - Another Kompose Dialog is open... close it first" << endl;
+ return;
+ }
+
+ if (type == -1)
+ type = KomposeSettings::instance()->getDefaultView();
+
+ kdDebug() << "KomposeViewManager::createView( type " << type << " )" << endl;
+
+ if ( !activeView )
+ {
+ // Remember current desktop
+ deskBeforeSnaps = KWin::currentDesktop();
+ kdDebug() << "KomposeViewManager::createView() - Remembering desktop " << deskBeforeSnaps << endl;
+ // Update screenshot of the current window to be more up2date
+ // KomposeTaskManager::instance()->simulatePasvScreenshotEvent();
+ // Update all other
+ blockScreenshots = true;
+ if ( type == KOMPOSEDISPLAY_CURRENTDESK )
+ KomposeTaskManager::instance()->slotUpdateScreenshots( false );
+ else
+ KomposeTaskManager::instance()->slotUpdateScreenshots();
+ blockScreenshots = false;
+ }
+
+ if ( !activeView )
+ viewWidget = new KomposeFullscreenWidget( type );
+ else
+ viewWidget->setType( type );
+
+ viewWidget->show();
+ KWin::forceActiveWindow( viewWidget->winId() );
+
+ activeView = true;
+}
+
+
+void KomposeViewManager::closeCurrentView()
+{
+ if ( !activeView )
+ return;
+
+ blockScreenshots = true;
+ activeView = false;
+
+ //viewWidget->setUpdatesEnabled( false );
+ //viewWidget->hide();
+ viewWidget->close();
+ viewWidget->deleteLater();
+ //viewWidget = 0;
+
+ emit viewClosed();
+
+ if ( KomposeGlobal::instance()->getSingleShot() )
+ kapp->quit();
+
+ // Reset old Desktop
+ KWin::setCurrentDesktop( deskBeforeSnaps );
+
+ // A short delay until we allow screenshots again (would cause overlapping else
+ QTimer::singleShot( 400, this, SLOT( toggleBlockScreenshots() ) );
+
+ // Restart Timer for corner checks
+ slotStartCursorUpdateTimer();
+}
+
+void KomposeViewManager::toggleBlockScreenshots()
+{
+ blockScreenshots = !blockScreenshots;
+}
+
+void KomposeViewManager::setCurrentDesktop( int desknum )
+{
+ closeCurrentView();
+ KWin::setCurrentDesktop(desknum+1);
+}
+
+void KomposeViewManager::activateTask( KomposeTask *task )
+{
+ closeCurrentView();
+ task->activate();
+}
+
+
+
+#include "komposeviewmanager.moc"
diff --git a/src/komposeviewmanager.h b/src/komposeviewmanager.h
new file mode 100644
index 0000000..8117f6d
--- /dev/null
+++ b/src/komposeviewmanager.h
@@ -0,0 +1,79 @@
+//
+// C++ Interface: %{MODULE}
+//
+// Description:
+//
+//
+// Author: %{AUTHOR} <%{EMAIL}>, (C) %{YEAR}
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#ifndef KOMPOSEVIEWMANAGER_H
+#define KOMPOSEVIEWMANAGER_H
+
+#include <qpoint.h>
+#include <dcopobject.h>
+
+#include "komposedcopiface.h"
+#include "komposefullscreenwidget.h"
+
+class KomposeTask;
+class QTimer;
+
+/**
+@author Hans Oischinger
+*/
+class KomposeViewManager : public QObject, virtual public KomposeDcopIface
+{
+ Q_OBJECT
+protected:
+ KomposeViewManager();
+ ~KomposeViewManager();
+
+public:
+ static KomposeViewManager *instance();
+
+ KomposeFullscreenWidget* getViewWidget() { return viewWidget; }
+
+public slots:
+ void createView( int type = -1 ); // -1 means the user's default
+ void createVirtualDesktopView() { createView( KOMPOSEDISPLAY_VIRTUALDESKS ); }
+ void createCurrentDesktopView() { createView( KOMPOSEDISPLAY_CURRENTDESK ); }
+ void createWorldView() { createView( KOMPOSEDISPLAY_WORLD ); }
+ void createDefaultView() { createView(); }
+
+ void closeCurrentView();
+ bool hasActiveView() { return activeView; }
+ bool getBlockScreenshots() { return blockScreenshots; }
+ int getDesktopBeforeSnaps() { return deskBeforeSnaps - 1; }
+
+ void setCurrentDesktop( int desknum );
+ void activateTask( KomposeTask* task );
+
+protected slots:
+ void toggleBlockScreenshots();
+ void checkCursorPos();
+ void reCheckCursorPos();
+
+ void uglyQtHackInitFunction();
+ void slotStartCursorUpdateTimer();
+
+signals:
+ void viewClosed();
+
+private:
+ KomposeFullscreenWidget *viewWidget; // the widget where all action takes place
+ bool activeView; // used to check if a view is active
+ bool blockScreenshots; // no screenshots when true
+ int deskBeforeSnaps; // the virtual desk we were on befor screenshots were taken
+
+ QTimer *cursorUpdateTimer;
+ // The 4 corners
+ QPoint topLeftCorner;
+ QPoint topRightCorner;
+ QPoint bottomLeftCorner;
+ QPoint bottomRightCorner;
+};
+
+#endif
diff --git a/src/komposewidget.cpp b/src/komposewidget.cpp
new file mode 100644
index 0000000..80d9ef4
--- /dev/null
+++ b/src/komposewidget.cpp
@@ -0,0 +1,94 @@
+/***************************************************************************
+ * Copyright (C) 2004 by Hans Oischinger *
+ * *
+ * 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 "komposewidget.h"
+#include "komposelayout.h"
+
+#include <qtimer.h>
+#include <kdebug.h>
+
+/*
+ * The constructor accepts a custom layout, if none is specified a defaultlayout is used
+ */
+KomposeWidget::KomposeWidget(QWidget *parent, KomposeLayout *l, const char *name)
+ : QWidget(parent, name)
+{
+ if (!l)
+ layout = new KomposeLayout( this );
+ else
+ layout = l;
+}
+
+
+KomposeWidget::~KomposeWidget()
+{
+ delete layout;
+}
+
+
+/*
+ * Whenever a child is added to the widget it's also added to the layout
+ */
+void KomposeWidget::childEvent ( QChildEvent * ce)
+{
+ KomposeWidget* kwChild = 0;
+ kwChild = ::qt_cast<KomposeWidget*>(ce->child());
+ if ( !kwChild )
+ return;
+
+ if ( ce->inserted() )
+ {
+ kdDebug() << "KomposeWidget::childEvent : Added widget " << ce->child()->className() << " to " << className() << endl;
+ layout->add( kwChild );
+ }
+ else if ( ce->removed() )
+ {
+ kdDebug() << "KomposeWidget::childEvent : Removed widget " << ce->child()->className() << " from " << className() << endl;
+ layout->remove( kwChild );
+ }
+ layout->arrangeLayout();
+}
+
+/*
+ * Whenever a resize occurs rearrange the layout
+ */
+void KomposeWidget::resizeEvent ( QResizeEvent * e )
+{
+ kdDebug() << "KomposeWidget(" << className() << ")::resizeEvent - Size:" << e->size().width() << "x"<< e->size().height() << endl;
+ layout->arrangeLayout();
+}
+
+
+KomposeWidget* KomposeWidget::getParentWidget() const
+{
+ if ( QWidget::parent()->inherits("KomposeWidget") )
+ return (KomposeWidget*)QWidget::parent();
+ else
+ {
+ kdDebug() << "KomposeWidget::getParentWidget() - QWidget::parent() does not inherit (KomposeWidget)" << endl;
+ return NULL;
+ }
+}
+
+int KomposeWidget::getNumofChilds()
+{
+ return layout->getNumofChilds();
+}
+
+#include "komposewidget.moc"
diff --git a/src/komposewidget.h b/src/komposewidget.h
new file mode 100644
index 0000000..7bb14d0
--- /dev/null
+++ b/src/komposewidget.h
@@ -0,0 +1,56 @@
+/***************************************************************************
+ * Copyright (C) 2004 by Hans Oischinger *
+ * *
+ * 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. *
+ ***************************************************************************/
+#ifndef KOMPOSEWIDGET_H
+#define KOMPOSEWIDGET_H
+
+#include <qwidget.h>
+
+class KomposeLayout;
+
+/**
+This base class for all Kompose Widgets glues the Layout and the widget together:
+@author Hans Oischinger
+*/
+class KomposeWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ KomposeWidget( QWidget *parent = 0, KomposeLayout *l = 0, const char *name = 0);
+
+ virtual ~KomposeWidget();
+
+ // KomposeWidgetInterface:
+ virtual KomposeWidget* getParentWidget() const;
+ virtual int getHeightForWidth( int w ) const = 0;
+ virtual int getWidthForHeight( int h ) const = 0;
+ virtual double getAspectRatio() = 0;
+
+ KomposeLayout* getLayout() { return layout; }
+ int getNumofChilds();
+
+protected:
+ void childEvent( QChildEvent * ce);
+ void resizeEvent ( QResizeEvent * e );
+
+protected:
+ KomposeLayout *layout;
+};
+
+#endif
diff --git a/src/main.cpp b/src/main.cpp
new file mode 100644
index 0000000..0af9472
--- /dev/null
+++ b/src/main.cpp
@@ -0,0 +1,94 @@
+/***************************************************************************
+ * Copyright (C) 2004 by Hans Oischinger *
+ * *
+ * 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 "kompose.h"
+#include "komposeglobal.h"
+
+#include <stdlib.h>
+
+#include <kaboutdata.h>
+#include <kcmdlineargs.h>
+#include <klocale.h>
+
+
+static const char description[] =
+ I18N_NOOP("A fullscreen task manager for KDE");
+
+static const char version[] = "0.5.3";
+
+static KCmdLineOptions options[] =
+ {
+ { "nosystray", I18N_NOOP( "Do not show the systray icon" ), 0 },
+ { "singleshot", I18N_NOOP( "Display the default view and exit (non daemon mode)" ), 0 },
+ KCmdLineLastOption
+ };
+
+void myMessageOutput( QtMsgType type, const char *msg )
+{
+ return;
+ switch ( type )
+ {
+ case QtDebugMsg:
+ fprintf( stderr, "Debug: %s\n", msg );
+ break;
+ case QtWarningMsg:
+ fprintf( stderr, "Warning: %s\n", msg );
+ break;
+ case QtFatalMsg:
+ fprintf( stderr, "Fatal: %s\n", msg );
+ abort(); // deliberately core dump
+ }
+}
+
+int main(int argc, char **argv)
+{
+// qInstallMsgHandler( myMessageOutput );
+
+ KAboutData about("kompose", I18N_NOOP("Kompose"), version, description,
+ KAboutData::License_GPL, "(C) 2005 Hans Oischinger", "", "http://developer.berlios.de/projects/kompose", "[email protected]");
+ about.addAuthor( "Hans Oischinger", 0, "[email protected]" );
+ KCmdLineArgs::init(argc, argv, &about);
+ KCmdLineArgs::addCmdLineOptions( options );
+
+ Kompose *app = new Kompose();
+
+ // no session.. just start up normally
+ KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
+
+ if ( !args->isSet("systray") )
+ {
+ KomposeGlobal::instance()->setHideSystray(true);
+ }
+ if ( args->isSet("singleshot") )
+ {
+ KomposeGlobal::instance()->setHideSystray(true);
+ KomposeGlobal::instance()->setSingleShot(true);
+ }
+
+ KomposeGlobal::instance()->initGui();
+
+ //app.setMainWidget( mainWin );
+
+ args->clear();
+
+ // mainWin has WDestructiveClose flag by default, so it will delete itself.
+ return app->exec();
+}
+