summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kwin/kcmkwin/kwinoptions/windows.cpp11
-rw-r--r--kwin/kcmkwin/kwinoptions/windows.h1
-rw-r--r--kwin/kompmgr/kompmgr.c116
-rw-r--r--kwin/workspace.cpp68
4 files changed, 145 insertions, 51 deletions
diff --git a/kwin/kcmkwin/kwinoptions/windows.cpp b/kwin/kcmkwin/kwinoptions/windows.cpp
index 69041c702..b5039b43c 100644
--- a/kwin/kcmkwin/kwinoptions/windows.cpp
+++ b/kwin/kcmkwin/kwinoptions/windows.cpp
@@ -1616,6 +1616,8 @@ void KTranslucencyConfig::save( void )
kapp->dcopClient()->attach();
kapp->dcopClient()->send("kwin*", "", "reconfigure()", TQString(""));
}
+ if (useTranslucency->isChecked())
+ startKompmgr();
emit KCModule::changed(false);
}
@@ -1669,6 +1671,15 @@ bool KTranslucencyConfig::kompmgrAvailable()
return ret;
}
+void KTranslucencyConfig::startKompmgr()
+{
+ bool ret;
+ KProcess proc;
+ proc << "kompmgr";
+ ret = proc.start(KProcess::DontCare, KProcess::AllOutput);
+ proc.detach();
+}
+
void KTranslucencyConfig::showWarning(bool alphaActivated)
{
// if (alphaActivated)
diff --git a/kwin/kcmkwin/kwinoptions/windows.h b/kwin/kcmkwin/kwinoptions/windows.h
index 83dc70b66..338860efe 100644
--- a/kwin/kcmkwin/kwinoptions/windows.h
+++ b/kwin/kcmkwin/kwinoptions/windows.h
@@ -283,6 +283,7 @@ private:
bool alphaActivated;
bool resetKompmgr_;
bool kompmgrAvailable();
+ void startKompmgr();
bool kompmgrAvailable_;
KProcess *kompmgr;
diff --git a/kwin/kompmgr/kompmgr.c b/kwin/kompmgr/kompmgr.c
index f65586be4..83feb271e 100644
--- a/kwin/kompmgr/kompmgr.c
+++ b/kwin/kompmgr/kompmgr.c
@@ -23,12 +23,22 @@
*/
-/* Modified by Matthew Hawn. I don't know what to say here so follow what it
+/* Modified by Matthew Hawn. I don't know what to say here so follow what it
says above. Not that I can really do anything about it
*/
/* Modified by Dan Doel*/
+/* Modified by Timothy Pearson
+ *
+ * CHANGELOG:
+ * http://patchwork.freedesktop.org/patch/1049/ [Add default background color option] 08/11/2011
+ * http://patchwork.freedesktop.org/patch/1052/ [Prevent flicker on root pixmap change] 08/11/2011
+ *
+ * TODO:
+ * http://patchwork.freedesktop.org/patch/1053/ [Fix window mapping with re-used window ids]
+*/
+
/*
Version 2.x of xcompmgr, kompmgr changes by Thomas L�bking and Heiko Przybyl
check baghira.sf.net for more infos
@@ -54,7 +64,7 @@ check baghira.sf.net for more infos
#define HAS_NAME_WINDOW_PIXMAP 1
#endif
-#define CAN_DO_USABLE 0
+#define CAN_DO_USABLE 1
#define _TOPHEIGHT_(x) ((x >> 24) & 0xff)
#define _RIGHTWIDTH_(x) ((x >> 16) & 0xff)
@@ -141,6 +151,7 @@ Bool clipChanged;
#if HAS_NAME_WINDOW_PIXMAP
Bool hasNamePixmap;
#endif
+XRenderColor fill_color;
int root_height, root_width;
ignore *ignore_head, **ignore_tail = &ignore_head;
int xfixes_event, xfixes_error;
@@ -149,6 +160,7 @@ int composite_event, composite_error;
int render_event, render_error;
Bool synchronize;
int composite_opcode;
+Bool screen_damaged = False;
Bool disable_argb = False;
int tqshapeEvent;
@@ -176,8 +188,8 @@ Atom winNormalAtom;
#define SHADOW_PROP "_KDE_WM_WINDOW_SHADOW"
#define SHADE_PROP "_KDE_WM_WINDOW_SHADE"
#define SHAPABLE_PROP "_KDE_WM_WINDOW_SHAPABLE"
-#define DECOHASH_PROP "_KDE_WM_WINDOW_DECOHASH"
-#define DIM_PROP "_KDE_WM_WINDOW_DIM"
+#define DECOHASH_PROP "_KDE_WM_WINDOW_DECOHASH"
+#define DIM_PROP "_KDE_WM_WINDOW_DIM"
#define DESKCHANGE_PROP "_KDE_WM_DESKTOP_CHANGE"
#define TRANSLUCENT 0xe0000000
@@ -825,7 +837,7 @@ static char *backgroundProps[] = {
0,
};
- static Picture
+static Picture
root_tile (Display *dpy)
{
Picture picture;
@@ -865,17 +877,13 @@ root_tile (Display *dpy)
CPRepeat, &pa);
if (fill)
{
- XRenderColor c;
-
- c.red = c.green = c.blue = 0x8080;
- c.alpha = 0xffff;
- XRenderFillRectangle (dpy, PictOpSrc, picture, &c,
+ XRenderFillRectangle (dpy, PictOpSrc, picture, &fill_color,
0, 0, 1, 1);
}
return picture;
}
- static void
+static void
paint_root (Display *dpy)
{
if (!rootTile)
@@ -886,7 +894,7 @@ paint_root (Display *dpy)
0, 0, 0, 0, 0, 0, root_width, root_height);
}
- static XserverRegion
+static XserverRegion
win_extents (Display *dpy, win *w)
{
XRectangle r;
@@ -1070,7 +1078,7 @@ paint_all (Display *dpy, XserverRegion region)
continue;
#endif
/* never painted, ignore it */
- if (!w->damaged)
+ if ((!screen_damaged) && (!w->damaged))
continue;
/* skip invisible windows */
@@ -1339,9 +1347,10 @@ paint_all (Display *dpy, XserverRegion region)
XRenderComposite (dpy, PictOpSrc, rootBuffer, None, rootPicture,
0, 0, 0, 0, 0, 0, root_width, root_height);
}
+ screen_damaged = False;
}
- static void
+static void
add_damage (Display *dpy, XserverRegion damage)
{
if (allDamage)
@@ -1353,7 +1362,7 @@ add_damage (Display *dpy, XserverRegion damage)
allDamage = damage;
}
- static void
+static void
repair_win (Display *dpy, win *w)
{
XserverRegion parts;
@@ -1389,7 +1398,7 @@ repair_win (Display *dpy, win *w)
static unsigned int
get_opacity_prop(Display *dpy, win *w, unsigned int def);
- static void
+static void
map_win (Display *dpy, Window id, unsigned long sequence, Bool fade)
{
win *w = find_win (dpy, id);
@@ -1412,7 +1421,7 @@ map_win (Display *dpy, Window id, unsigned long sequence, Bool fade)
set_fade (dpy, w, 0, get_opacity_prop(dpy, w, OPAQUE)*1.0/OPAQUE, fade_in_step, 0, False, True, True, True);
}
- static void
+static void
finish_unmap_win (Display *dpy, win *w)
{
w->damaged = 0;
@@ -1480,14 +1489,14 @@ finish_unmap_win (Display *dpy, win *w)
}
#if HAS_NAME_WINDOW_PIXMAP
- static void
+static void
unmap_callback (Display *dpy, win *w, Bool gone)
{
finish_unmap_win (dpy, w);
}
#endif
- static void
+static void
unmap_win (Display *dpy, Window id, Bool fade)
{
win *w = find_win (dpy, id);
@@ -1499,7 +1508,7 @@ unmap_win (Display *dpy, Window id, Bool fade)
set_fade (dpy, w, w->opacity*1.0/OPAQUE, 0.0, fade_out_step, unmap_callback, False, False, True, True);
else
#endif
- finish_unmap_win (dpy, w);
+ finish_unmap_win (dpy, w);
}
/* Get the opacity prop from window
@@ -2155,7 +2164,23 @@ damage_win (Display *dpy, XDamageNotifyEvent *de)
repair_win (dpy, w);
}
- static int
+static void
+damage_screen (Display *dpy)
+{
+ XserverRegion region;
+ XRectangle r;
+
+ r.x = 0;
+ r.y = 0;
+ r.width = root_width;
+ r.height = root_height;
+
+ region = XFixesCreateRegion (dpy, &r, 1);
+ add_damage (dpy, region);
+ screen_damaged = True;
+}
+
+static int
error (Display *dpy, XErrorEvent *ev)
{
int o;
@@ -2478,6 +2503,7 @@ usage (char *program)
fprintf (stderr, " -o opacity\n Specifies the translucency for client-side shadows. (default .75)\n");
fprintf (stderr, " -l left-offset\n Specifies the left offset for client-side shadows. (default -15)\n");
fprintf (stderr, " -t top-offset\n Specifies the top offset for clinet-side shadows. (default -15)\n");
+ fprintf (stderr, " -b color\n Specifies the background color to use if no root pixmap is set. (default is a gray)\n");
fprintf (stderr, " -I fade-in-step\n Specifies the opacity change between steps while fading in. (default 0.028)\n");
fprintf (stderr, " -O fade-out-step\n Specifies the opacity change between steps while fading out. (default 0.03)\n");
fprintf (stderr, " -D fade-delta-time\n Specifies the time between steps in a fade in milliseconds. (default 10)\n");
@@ -2529,6 +2555,7 @@ main (int argc, char **argv)
int composite_major, composite_minor;
int o;
+ char *fill_color_name = NULL;
char **res = NULL;
shadowColor.red = 0;
@@ -2537,7 +2564,7 @@ main (int argc, char **argv)
loadConfig(NULL); /*we do that before cmdline-parsing, so config-values can be overridden*/
/*used for shadow colors*/
- while ((o = getopt (argc, argv, "D:I:O:d:r:o:l:t:scnfFCaSx:vh")) != -1)
+ while ((o = getopt (argc, argv, "D:I:O:d:r:o:l:t:b:scnfFCaSx:vh")) != -1)
{
switch (o) {
case 'd':
@@ -2594,6 +2621,9 @@ main (int argc, char **argv)
case 't':
shadowOffsetY = atoi (optarg);
break;
+ case 'b':
+ fill_color_name = optarg;
+ break;
case 'x':
if( compMode != CompClientShadows ){
fprintf(stderr, "sorry, but we need ClientShadows (-c) for coloring to work properly!\ndefaulting to black...\n");
@@ -2679,10 +2709,35 @@ main (int argc, char **argv)
presum_gaussian (gaussianMap);
}
+ if (fill_color_name)
+ {
+ XColor c;
+ if (! XParseColor (dpy, DefaultColormap (dpy, scr),
+ fill_color_name, &c))
+ {
+ fprintf (stderr, "Could not parse fill color.\n");
+ exit (1);
+ }
+ if (! XAllocColor (dpy, DefaultColormap (dpy, scr), &c))
+ {
+ fprintf (stderr, "Could not allocate color.\n");
+ exit (1);
+ }
+
+ fill_color.red = c.red;
+ fill_color.green = c.green;
+ fill_color.blue = c.blue;
+ }
+ else
+ {
+ fill_color.red = fill_color.green = fill_color.blue = 0x8080;
+ }
+ fill_color.alpha = 0xffff;
+
root_width = DisplayWidth (dpy, scr);
root_height = DisplayHeight (dpy, scr);
- rootPicture = XRenderCreatePicture (dpy, root,
+ rootPicture = XRenderCreatePicture (dpy, root,
sXRenderFindVisualFormat (dpy,
DefaultVisual (dpy, scr)),
CPSubwindowMode,
@@ -2699,7 +2754,7 @@ main (int argc, char **argv)
{
int dummy;
XCompositeRedirectSubwindows (dpy, root, CompositeRedirectManual);
- XSelectInput (dpy, root,
+ XSelectInput (dpy, root,
SubstructureNotifyMask|
ExposureMask|
StructureNotifyMask|
@@ -2804,9 +2859,9 @@ main (int argc, char **argv)
{
if (rootTile)
{
- XClearArea (dpy, root, 0, 0, 0, 0, True);
XRenderFreePicture (dpy, rootTile);
rootTile = None;
+ damage_screen (dpy);
break;
}
}
@@ -2976,10 +3031,10 @@ main (int argc, char **argv)
XFixesDestroyRegion( dpy, w->extents );
w->extents = win_extents (dpy, w);
}
-#endif
- /*this is hardly efficient, but a current workaraound
+#endif
+ /*this is hardly efficient, but a current workaraound
shaping support isn't that good so far (e.g. we lack tqshaped shadows)
- IDEA: use XRender to scale/shift a copy of the window and then blurr it*/
+ IDEA: use XRender to scale/shift a copy of the window and then blur it*/
#if 1
if (w->picture)
{
@@ -2994,12 +3049,13 @@ main (int argc, char **argv)
} while (QLength (dpy));
if (allDamage && !autoRedirect)
{
- /*static int paint;*/
paint_all (dpy, allDamage);
- /*paint++;*/
XSync (dpy, False);
allDamage = None;
clipChanged = False;
}
}
+
+ XClearArea (dpy, root, 0, 0, 0, 0, True);
+ XSync (dpy, False);
}
diff --git a/kwin/workspace.cpp b/kwin/workspace.cpp
index 16efb606d..acd3387da 100644
--- a/kwin/workspace.cpp
+++ b/kwin/workspace.cpp
@@ -1239,22 +1239,45 @@ bool Workspace::setCurrentDesktop( int new_desktop )
current_desktop = new_desktop; // change the desktop (so that Client::updateVisibility() works)
- for ( ClientList::ConstIterator it = stacking_order.begin(); it != stacking_order.end(); ++it)
- if ( !(*it)->isOnDesktop( new_desktop ) && (*it) != movingClient )
+ bool desktopHasCompositing = kapp->isCompositionManagerAvailable(); // Technically I should call isX11CompositionAvailable(), but it isn't initialized via my kapp constructir, and in this case it doesn't really matter anyway....
+ if (!desktopHasCompositing) {
+ // If composition is not in use then we can hide the old windows before showing the new ones
+ for ( ClientList::ConstIterator it = stacking_order.begin(); it != stacking_order.end(); ++it) {
+ if ( !(*it)->isOnDesktop( new_desktop ) && (*it) != movingClient )
{
- if( (*it)->isShown( true ) && (*it)->isOnDesktop( old_desktop ))
- obs_wins.create( *it );
- (*it)->updateVisibility();
+ if( (*it)->isShown( true ) && (*it)->isOnDesktop( old_desktop )) {
+ obs_wins.create( *it );
+ }
+ (*it)->updateVisibility();
}
+ }
+ }
rootInfo->setCurrentDesktop( current_desktop ); // now propagate the change, after hiding, before showing
if( movingClient && !movingClient->isOnDesktop( new_desktop ))
movingClient->setDesktop( new_desktop );
- for ( ClientList::ConstIterator it = stacking_order.fromLast(); it != stacking_order.end(); --it)
- if ( (*it)->isOnDesktop( new_desktop ) )
+ for ( ClientList::ConstIterator it = stacking_order.fromLast(); it != stacking_order.end(); --it) {
+ if ( (*it)->isOnDesktop( new_desktop ) ) {
(*it)->updateVisibility();
+ }
+ }
+
+ if (desktopHasCompositing) {
+ // If composition is in use then we cannot hide the old windows before showing the new ones,
+ // unless you happen to like the "flicker annoyingly to desktop" effect... :-P
+ XSync( qt_xdisplay(), false); // Make absolutely certain all new windows are shown before hiding the old ones
+ for ( ClientList::ConstIterator it = stacking_order.begin(); it != stacking_order.end(); ++it) {
+ if ( !(*it)->isOnDesktop( new_desktop ) && (*it) != movingClient )
+ {
+ if( (*it)->isShown( true ) && (*it)->isOnDesktop( old_desktop )) {
+ obs_wins.create( *it );
+ }
+ (*it)->updateVisibility();
+ }
+ }
+ }
--block_showing_desktop;
if( showingDesktop()) // do this only after desktop change to avoid flicker
@@ -2547,16 +2570,16 @@ void Workspace::startKompmgr()
if (!kompmgr || kompmgr->isRunning())
return;
if (!kompmgr->start(KProcess::OwnGroup, KProcess::Stderr))
- {
+ {
options->useTranslucency = FALSE;
KProcess proc;
proc << "kdialog" << "--error"
<< i18n("The Composite Manager could not be started.\\nMake sure you have \"kompmgr\" in a $PATH directory.")
<< "--title" << "Composite Manager Failure";
proc.start(KProcess::DontCare);
- }
+ }
else
- {
+ {
delete kompmgr_selection;
char selection_name[ 100 ];
sprintf( selection_name, "_NET_WM_CM_S%d", DefaultScreen( qt_xdisplay()));
@@ -2571,8 +2594,8 @@ void Workspace::startKompmgr()
TQDataStream arg(ba, IO_WriteOnly);
arg << "";
kapp->dcopClient()->emitDCOPSignal("default", "kompmgrStarted()", ba);
- }
- if (popup){ delete popup; popup = 0L; } // to add/remove opacity slider
+ }
+ if (popup){ delete popup; popup = 0L; } // to add/remove opacity slider
}
void Workspace::stopKompmgr()
@@ -2604,9 +2627,11 @@ void Workspace::unblockKompmgrRestart()
void Workspace::restartKompmgr( KProcess *proc )
// this is for inernal purpose (crashhandling) only, usually you want to use workspace->stopKompmgr(); TQTimer::singleShot(200, workspace, TQT_SLOT(startKompmgr()));
{
- if (proc->signalled()) { // looks like kompmgr crashed
- if (!allowKompmgrRestart) // uh oh, it crashed recently already
- {
+ if (proc->signalled()) { // looks like kompmgr may have crashed
+ int exit_signal_number = proc->exitSignal();
+ if ( (exit_signal_number == SIGILL) || (exit_signal_number == SIGTRAP) || (exit_signal_number == SIGABRT) || (exit_signal_number == SIGSYS) || (exit_signal_number == SIGFPE) || (exit_signal_number == SIGBUS) || (exit_signal_number == SIGSEGV) ) {
+ if (!allowKompmgrRestart) // uh oh, it crashed recently already
+ {
delete kompmgr_selection;
kompmgr_selection = NULL;
options->useTranslucency = FALSE;
@@ -2616,8 +2641,9 @@ void Workspace::restartKompmgr( KProcess *proc )
<< "--title" << i18n("Composite Manager Failure");
proc.start(KProcess::DontCare);
return;
- }
- if (!kompmgr)
+ }
+ }
+ if (!kompmgr)
return;
// this should be useless, i keep it for maybe future need
// if (!kcompmgr)
@@ -2628,7 +2654,7 @@ void Workspace::restartKompmgr( KProcess *proc )
// }
// -------------------
if (!kompmgr->start(KProcess::NotifyOnExit, KProcess::Stderr))
- {
+ {
delete kompmgr_selection;
kompmgr_selection = NULL;
options->useTranslucency = FALSE;
@@ -2637,12 +2663,12 @@ void Workspace::restartKompmgr( KProcess *proc )
<< i18n("The Composite Manager could not be started.\\nMake sure you have \"kompmgr\" in a $PATH directory.")
<< "--title" << i18n("Composite Manager Failure");
proc.start(KProcess::DontCare);
- }
+ }
else
- {
+ {
allowKompmgrRestart = FALSE;
TQTimer::singleShot( 60000, this, TQT_SLOT(unblockKompmgrRestart()) );
- }
+ }
}
}