[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kwin
Subject:    Re: __GL_YIELD
From:       Lubos Lunak <l.lunak () suse ! cz>
Date:       2007-05-04 13:27:13
Message-ID: 200705041527.14210.l.lunak () suse ! cz
[Download RAW message or body]

On Thursday 03 of May 2007, Rivo Laks wrote:
> Ühel kenal päeval (kolmapäev 02 mai 2007) kirjutas Lubos Lunak:
> > On Wednesday 02 of May 2007, Rivo Laks wrote:
> > > Experimenting shows that setting  __GL_YIELD="NOTHING"  really does
> > > improve (visible) performance. Especially animations feel a lot
> > > snappier with it, possibly because window repaints are more delayed
> > > towards the end of animation. So while the animation (e.g. desktop
> > > switch) is in progress, you mostly see just a white/grey window
> > > background and usually the window repaint is completed only at the end
> > > of the animation.
> >
> >  Ok. It doesn't seem to make any visible difference here, but maybe
> > that's just me. If it helps, we probably should include it. However, if
> > I'm getting it right, this needs to be set before the app is even
> > launched (which is why Beryl restarts). That however doesn't work with
> > KWin and kdeinit. We would probably have to load openGL dynamically
> > instead of linking against it :-/.
>
> We did that in Boson (dlopen()ing libGL) and IIRC it wasn't very
> pretty/easy, so I'd avoid it if possible.

 I'd expect it to be in theory just handling all OpenGL functions like we 
handle extensions now, but I guess practice differs from theory then?

> Can't we just start KWin without using kdeinit in case that variable has to
> be set?

 Kdeinit has its benefits too, so I'd prefer keeping it too. Besides, if 
there's code which would know when to avoid kdeinit then that code could 
simply set the variable. I think there could be a way to solve this somehow, 
probably some ugly hack like a static constructor in a library that'd be 
linked to before libGL or something. I've noted it down in the TODO for now.

> > > BTW, can't we just keep the window texture around (window mapped or
> > > whatever the correct term is) instead of repainting it every time it's
> > > shown (e.g. on desktop switch)?
> >
> >  You mean keeping the window contents even when the window is hidden
> > (minimized/on another virtual desktop/whatever)? I have an experimental
> > patch for that but there are still some problems.
>
> Yep, that's what I mean.
> Are those problems resolvable in the near future?

 Good question :-/. Attached is a hackish version, but the problem is that you 
want both the windows to be there (i.e. be mapped) and not be there (i.e. 
avoid any possible interaction). The choices I see are:

- restack them at the bottom - that's the attached patch, the problem is that 
e.g. desktop grid doesn't show windows from inactive virtual desktops because 
they're restacked below the desktop window

- just map the window - remove the changes the patch does in layers.cpp, the 
problem is that if you have two windows in the same position on two different 
virtual desktops, then the inactive one may cover the active one (so it'd 
e.g. get mouse clicks instead of the active one)

- move "hidden" windows out of the screen - then e.g. pages would get the 
positions wrong, among other things (I expect some, mostly lame, apps 
wouldn't be happy about it either)

- wait for input redirection in X - this probably could work, but there's 
the "wait" and this maybe still could break some cases where something 
searches windows from top on a certain position

 All of them have their problems and at least some of them could be probably 
good enough, it's just about picking the poison. I think I could try to 
improve the restacking so that it works right, changing the X stacking order 
but internally always using the "visual" stacking order (stacking of deleted 
windows needs to be fixed anyway), there's still a minor chance something 
searches the X stacking and gets it wrong.

-- 
Lubos Lunak
KDE developer
--------------------------------------------------------------
SUSE LINUX, s.r.o.   e-mail: l.lunak@suse.cz , l.lunak@kde.org
Lihovarska 1060/12   tel: +420 284 028 972
190 00 Prague 9      fax: +420 284 028 951
Czech Republic       http//www.suse.cz

["kwin.patch" (text/x-diff)]

--- kwin/client.h.sav	2007-04-30 14:41:04.000000000 +0200
+++ kwin/client.h	2007-05-04 14:23:57.000000000 +0200
@@ -47,6 +47,7 @@ class Client
     {
     Q_OBJECT
     public:
+        int mappingState() const;
         Client( Workspace *ws );
         Window wrapperId() const;
         Window decorationId() const;
@@ -309,7 +310,6 @@ class Client
     private:
     // ICCCM 4.1.3.1, 4.1.4 , NETWM 2.5.1
         void setMappingState( int s );
-        int mappingState() const;
         bool isIconicState() const;
         bool isNormalState() const;
         bool isManaged() const; // returns false if this client is not yet managed
--- kwin/client.cpp.sav	2007-05-02 14:47:36.000000000 +0200
+++ kwin/client.cpp	2007-05-04 14:23:57.000000000 +0200
@@ -41,6 +41,7 @@ License. See the file "COPYING" for the 
 namespace KWin
 {
 
+extern bool hack_changed;
 /*
 
  Creating a client:
@@ -857,8 +858,10 @@ void Client::rawShow()
     // XComposite invalidates backing pixmaps on unmap (minimize, different
     // virtual desktop, etc.).  We kept the last known good pixmap around
     // for use in effects, but now we want to have access to the new pixmap
-    if( compositing() )
-        discardWindowPixmap();
+//    if( compositing() )
+//        discardWindowPixmap();
+    hack_changed = true;
+    StackingUpdatesBlocker blocker( workspace());
     }
 
 /*!
@@ -876,13 +879,15 @@ void Client::rawHide()
 // will be missed is also very minimal, so I don't think it's needed to grab the server
 // here.
     XSelectInput( display(), wrapper, ClientWinMask ); // avoid getting UnmapNotify
-    XUnmapWindow( display(), frameId());
-    XUnmapWindow( display(), wrapper );
-    XUnmapWindow( display(), client );
+//    XUnmapWindow( display(), frameId());
+//    XUnmapWindow( display(), wrapper );
+//    XUnmapWindow( display(), client );
     XSelectInput( display(), wrapper, ClientWinMask | SubstructureNotifyMask );
-    if( decoration != NULL )
-        decoration->widget()->hide(); // not really necessary, but let it know the state
+//    if( decoration != NULL )
+//        decoration->widget()->hide(); // not really necessary, but let it know the state
     workspace()->clientHidden( this );
+    hack_changed = true;
+    StackingUpdatesBlocker blocker( workspace());
     }
 
 void Client::sendClientMessage(Window w, Atom a, Atom protocol, long data1, long data2, long data3)
--- kwin/manage.cpp.sav	2007-04-30 11:38:32.000000000 +0200
+++ kwin/manage.cpp	2007-05-04 14:23:57.000000000 +0200
@@ -471,6 +471,7 @@ bool Client::manage( Window w, bool isMa
         if( isOnCurrentDesktop() && !isMapped && !allow && (!session || session->stackingOrder < 0 ))
             workspace()->restackClientUnderActive( this );
 
+        rawShow();
         updateVisibility();
 
         if( !isMapped )
@@ -490,6 +491,7 @@ bool Client::manage( Window w, bool isMa
         }
     else if( !doNotShow ) // if( !isShown( true ) && !doNotShow )
         {
+        rawShow();
         updateVisibility();
         }
     else // doNotShow
--- kwin/layers.cpp.sav	2007-04-30 11:38:32.000000000 +0200
+++ kwin/layers.cpp	2007-05-04 14:32:37.000000000 +0200
@@ -77,6 +77,8 @@ License. See the file "COPYING" for the 
 namespace KWin
 {
 
+bool hack_changed = false;
+
 //*******************************
 // Workspace
 //*******************************
@@ -105,6 +107,8 @@ void Workspace::updateStackingOrder( boo
         }
     ClientList new_stacking_order = constrainedStackingOrder();
     bool changed = ( new_stacking_order != stacking_order );
+    if( hack_changed )
+        changed = true;
     stacking_order = new_stacking_order;
 #if 0
     kDebug() << "stacking:" << changed << endl;
@@ -150,8 +154,10 @@ void Workspace::propagateClients( bool p
         if( electric_windows[ i ] != None )
             new_stack[ pos++ ] = electric_windows[ i ];
     int topmenu_space_pos = 1; // not 0, that's supportWindow !!!
-	for ( int i = stacking_order.size() - 1; i >= 0; i-- )
+    for ( int i = stacking_order.size() - 1; i >= 0; i-- )
         {
+        if( stacking_order.at( i )->mappingState() != NormalState )
+            continue;
         new_stack[ pos++ ] = stacking_order.at( i )->frameId();
         if( stacking_order.at( i )->belongsToLayer() >= DockLayer )
             topmenu_space_pos = pos;
@@ -165,6 +171,14 @@ void Workspace::propagateClients( bool p
         new_stack[ topmenu_space_pos ] = topmenu_space->winId();
         ++pos;
         }
+    for ( int i = stacking_order.size() - 1; i >= 0; i-- )
+        {
+        if( stacking_order.at( i )->mappingState() == NormalState )
+            continue;
+        new_stack[ pos++ ] = stacking_order.at( i )->frameId();
+        if( stacking_order.at( i )->belongsToLayer() >= DockLayer )
+            topmenu_space_pos = pos;
+        }
     // TODO isn't it too inefficient to restack always all clients?
     // TODO don't restack not visible windows?
     assert( new_stack[ 0 ] == supportWindow->winId());


_______________________________________________
Kwin mailing list
Kwin@kde.org
https://mail.kde.org/mailman/listinfo/kwin


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic