From 4f1f76a2d336f560ddc6aa5c01f67ceb42ddcbee Mon Sep 17 00:00:00 2001 From: tpearson Date: Thu, 11 Aug 2011 20:48:28 +0000 Subject: Fix kompmgr in the following ways: 1. Repair spurious crash dialog 2. Make kompmgr start if enabled when Apply is clicked in KCM 3. Fix flickering and general graphical ickiness on desktop switch 4. Fix flickering on root pixmap change git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdebase@1246518 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- kwin/kcmkwin/kwinoptions/windows.cpp | 11 ++++ kwin/kcmkwin/kwinoptions/windows.h | 1 + kwin/kompmgr/kompmgr.c | 116 ++++++++++++++++++++++++++--------- kwin/workspace.cpp | 68 +++++++++++++------- 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()) ); - } + } } } -- cgit v1.2.1