Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 342282

Summary: Provide a flag to disable tree twistie animation and hiding
Product: [Eclipse Project] Platform Reporter: Benjamin Pasero <benjamin_pasero>
Component: SWTAssignee: Platform-SWT-Inbox <platform-swt-inbox>
Status: RESOLVED FIXED QA Contact:
Severity: normal    
Priority: P3 CC: bpasero, chris, daniel_megert, davidms, deepakazad, eclipse.felipe, M8R-sgiphk, marcel, markus.kell.r, numeralnathan, remy.suen, Silenio_Quarti, t.orf
Version: 3.7   
Target Milestone: 3.8 M3   
Hardware: PC   
OS: Windows 7   
Whiteboard:
Attachments:
Description Flags
Patch none

Description Benjamin Pasero CLA 2011-04-08 09:17:52 EDT
The Windows 7/Vista default tree expando animation and hiding has issues. For one, its reducing usability of trees because you can not easily see if a tree node has child elements or not without giving focus to the tree. And I also see performance issues. In once case, the UI thread was busy doing things until the twistie animation has finished until async runnables on the display thread would allow to execute (up to 1 second delays).

Attached is a patch to introduce a new system property to control this.
Comment 1 Benjamin Pasero CLA 2011-04-08 09:18:39 EDT
Created attachment 192827 [details]
Patch
Comment 2 Markus Keller CLA 2011-04-08 09:37:42 EDT
+1. The animations are really annoying, and the loss of information is bad.
Comment 3 Remy Suen CLA 2011-04-08 16:45:25 EDT
I hate hidden twisties.
Comment 4 Remy Suen CLA 2011-05-20 08:46:20 EDT
*** Bug 346664 has been marked as a duplicate of this bug. ***
Comment 5 John CLA 2011-05-20 09:01:16 EDT
awesome patch! is it done integrated yet? gimme gimme, enable it! engageeee :)
Comment 6 Markus Keller CLA 2011-05-20 09:42:39 EDT
BTW: It would also be fine if SWT just disabled the fading globally out of the box. Compared to other platforms, there's currently information loss in trees on Vista and Windows 7, so disabling the fading on Windows would improve API consistency.

Platform consistency on Windows is also not a strong argument in favor of the fading. This is a normal flag that applications can set or not, so it's not working against the platform if SWT decides not to fade. E.g. the Computer Management console also doesn't let expandos fade away.
Comment 7 John CLA 2011-05-20 09:52:57 EDT
//File->New->Project->Visual C#->Windows->Console Application
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Automation;

namespace ConsoleApplication1
{
  class Program
  {
    public const uint TVM_SETEXTENDEDSTYLE = 4396;
    public static IntPtr TVS_EX_FADEINOUTEXPANDOS = (IntPtr)0x40;
    public const long TVS_HASLINES = 0x02;
    public const int GWL_STYLE=-16;
    public const int GWL_EXSTYLE=-20;


    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);

    [DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
    static extern IntPtr FindWindowByCaption(IntPtr ZeroOnly, string lpWindowName);

    [DllImport( "uxtheme", ExactSpelling = true, CharSet = CharSet.Unicode )]
    public extern static Int32 SetWindowTheme( IntPtr hWnd, String textSubAppName, String textSubIdList );

    // This static method is required because legacy OSes do not support
    // SetWindowLongPtr
    public static IntPtr SetWindowLongPtr( HandleRef hWnd, int nIndex, IntPtr dwNewLong )
    {
      if ( IntPtr.Size == 8 )
        return SetWindowLongPtr64( hWnd, nIndex, dwNewLong );
      else
        return new IntPtr( SetWindowLong32( hWnd, nIndex, dwNewLong.ToInt32() ) );
    }

    [DllImport( "user32.dll", EntryPoint = "SetWindowLong" )]
    private static extern int SetWindowLong32( HandleRef hWnd, int nIndex, int dwNewLong );

    [DllImport( "user32.dll", EntryPoint = "SetWindowLongPtr" )]
    private static extern IntPtr SetWindowLongPtr64( HandleRef hWnd, int nIndex, IntPtr dwNewLong );

    [DllImport( "user32.dll", EntryPoint = "GetWindowLong" )]
    static extern IntPtr GetWindowLongPtr( IntPtr hWnd, int nIndex );

    static void Main(string[] args)
    {

      //All trees (treeview) that are not hidden or part of a minimized window
      //are transformed into tree with lines and expand/collapse [+]/[-] buttons that won't fade out
      AutomationElement ae=AutomationElement.RootElement;// AutomationElement.FromHandle( parent );
      Condition isTree=new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Tree);
      AutomationElementCollection allTrees = ae.FindAll( TreeScope.Children | TreeScope.Descendants, isTree );
      Console.WriteLine( "Found " + allTrees.Count + " trees" );
      foreach ( AutomationElement eachTree in allTrees )
      {
        if ( null != eachTree )
        {
          IntPtr currentTree=(IntPtr)eachTree.Current.NativeWindowHandle;
          if ( IntPtr.Zero != currentTree )
          {
            //get current style for treelines below
            IntPtr style=GetWindowLongPtr( currentTree, GWL_STYLE );

            //transform triangles to [+] / [-] expand/collapse icons
            SetWindowTheme( currentTree, String.Empty, String.Empty );

            IntPtr result = IntPtr.Zero;
            //prevent fade out
            result = SendMessage( currentTree, TVM_SETEXTENDEDSTYLE, TVS_EX_FADEINOUTEXPANDOS, IntPtr.Zero );
            Console.WriteLine( "Tree named `"+eachTree.Current.Name+"` class:`"+eachTree.Current.ClassName+"` changed!" + " Result: " + result.ToString());// + " Tree: " + currentTree);
            //show treelines
            style = (IntPtr)((long)style | (long)TVS_HASLINES);
            SetWindowLongPtr( new HandleRef( currentTree, currentTree ), GWL_STYLE, (IntPtr)style );
          }
        }
      }
      Console.Write("Finished press Enter");
      Console.ReadLine();
    }
  }
}
Comment 8 John CLA 2011-05-20 10:32:39 EDT
oops, posted this in the wrong bug, no wonder I couldn't find this comment, anyway it was supposed to be an attachment anyway, feel free to remove it 
was meant for this bug: https://bugs.eclipse.org/bugs/show_bug.cgi?id=346664
Comment 9 Deepak Azad CLA 2011-08-09 11:32:08 EDT
I just moved to Windows 7, and this bug is annoying me now.

(In reply to comment #6)
> BTW: It would also be fine if SWT just disabled the fading globally out of the
> box. Compared to other platforms, there's currently information loss in trees
> on Vista and Windows 7, so disabling the fading on Windows would improve API
> consistency.
+1.
Comment 10 Markus Keller CLA 2011-09-21 07:20:43 EDT
Ping.

I still think SWT's default should be to avoid information loss (i.e. disable the fading). If you deem it worthwhile, you can still add a global switch (via system property, or as a static getter/setter on Tree).
Comment 11 Chris Funk CLA 2011-09-26 15:35:44 EDT
+1
Comment 12 Felipe Heidrich CLA 2011-09-27 16:26:49 EDT
Silenio, what is your vote ?

a) Remove the flag

b) Disable the flag by default, give option (setData hack) to enable it

c) Enable the flag by default,  give option (setData hack) to disable it

d) nothing, close bug as wontfix

I think a or b...
Comment 13 Silenio Quarti CLA 2011-09-28 10:07:25 EDT
The patch is fine for me (flag to disable animation with default equals false)
Comment 14 Benjamin Pasero CLA 2011-09-28 10:29:55 EDT
Ha, I see a chance that after so many years some code from me finally goes into SWT ;-P
Comment 15 Felipe Heidrich CLA 2011-09-28 11:28:09 EDT
(In reply to comment #13)
> The patch is fine for me (flag to disable animation with default equals false)

Note that the patch uses System.getProperty(), which means the users you need to either change the eclipse.ini file or add the option in the command line.

So, that the animation will be enabled for everybody excepted a few who know about the secret flag (I can to add a FAQ for it at least).

Is that the right thing Markus/Dani/Ben ?
Comment 16 Benjamin Pasero CLA 2011-09-28 11:35:07 EDT
Well, in my own products I am shipping a SWT version where I simply hardcode to turn the animation off so my patch is just something I had in mind to make it better configurable. If there is a common approach in SWT to configure this in a different way (e.g. static method), I am fine with it too.
Comment 17 Benjamin Pasero CLA 2011-09-28 11:35:59 EDT
(I think I used system property since I remember there was one for controlling the focus ring on mac swt apps some years ago)
Comment 18 Markus Keller CLA 2011-09-28 13:46:35 EDT
This bug lists a lot of reasons for disabling the animations (and there are more).

Can anybody give at least a single good reason for having them enabled them at all? I haven't heard any so far, and if there is none, then please just remove this "feature".


http://msdn.microsoft.com/en-us/library/aa511496.aspx doesn't contain a single word about this. http://msdn.microsoft.com/en-us/library/bb759981%28v=VS.85%29.aspx does not urge anybody to use it.

The dreaded TVS_EX_FADEINOUTEXPANDOS constant looks like it's only been added to allow the Explorer.exe to show off. It's not used anywhere else.
Comment 19 Dani Megert CLA 2011-09-29 03:57:49 EDT
I agree with Markus. The current Windows 7 tree LAF is just a mess.

If you decide to keep the animation then a system property is not good enough as products and users don't want to deal with system properties normally. Hence we need a proper API. With such an API Platform UI could e.g. disable the tree animation when the user disables General > Appearance > Enable animations. Whether we additionally offer the system property doesn't matter to me.
Comment 20 Felipe Heidrich CLA 2011-09-29 12:10:57 EDT
Fixed
http://git.eclipse.org/c/platform/eclipse.platform.swt.git/commit/?id=51efa62e5106d26340bb3dd91dd9b46463023214

twistie animation is off my default. Need to set -Dorg.eclipse.swt.internal.win32.enableFadeInOutExpandos to enable it.

Thank you Ben for the patch, I used it (just invert the logic to make it disable by default).
Comment 21 Markus Keller CLA 2011-09-29 12:13:50 EDT
Yipee! Thanks guys.
Comment 22 Remy Suen CLA 2011-09-29 12:15:16 EDT
Thanks Ben for the patch and the SWT team for releasing it!
Comment 23 Dani Megert CLA 2011-09-29 12:16:33 EDT
Awesome!
Comment 24 Benjamin Pasero CLA 2011-09-29 12:18:40 EDT
Wohoo thanks 8)
Comment 25 Chris Funk CLA 2011-09-29 13:36:07 EDT
Awesome!  Thanks everyone!

Now, being greedy, is there any way to get this functionality in 3.7?  Or when is the 3.8 release targeted?
Comment 26 Markus Keller CLA 2011-09-29 14:24:42 EDT
The default should not be changed in a maintenance release. If the patch also goes into 3.7.2, then the property should be migration compatible in both releases, i.e.:

3.7.2:
- no property => fading
- plain property => fading
- enableFadeInOutExpandos=false => no fading

3.8:
- no property => no fading
- plain property => fading
- enableFadeInOutExpandos=false => no fading (for compatibility with 3.7.2)


Implementation in R3_7_maintenance:

ENABLE_TVS_EX_FADEINOUTEXPANDOS =
  !"false".equals(System.getProperty("[..].enableFadeInOutExpandos"))


Implementation in master:

ENABLE_TVS_EX_FADEINOUTEXPANDOS =
  "".equals(System.getProperty("[..].enableFadeInOutExpandos"))
Comment 27 Felipe Heidrich CLA 2011-09-29 14:57:33 EDT
I don't think you guys will be using this flag ;-) but there it is:
http://www.eclipse.org/swt/faq.php#twistieanimation

Cris, you will have to wait for Eclipse 3.8 (summer 2012)
This problem is not a candidate for 3.7.2
Comment 28 Marcel Stör CLA 2012-02-07 15:17:49 EST
There's nothing one can do at OS-level to disable? All that Windows animation crap...
Comment 29 T. Orf CLA 2012-10-23 11:48:08 EDT
(In reply to comment #28)
> There's nothing one can do at OS-level to disable? All that Windows
> animation crap...

You can open the properties of eclipse.exe (or a shortcut to it), select the Compatibility Tab, and check "Disable visual themes". This changes the nodes to classic squares with "+" or "-" in them, and lots more.

It worked for me in Windows 7 Prof 64 bit.
Comment 30 T. Orf CLA 2012-10-23 14:01:48 EDT
(In reply to comment #29)
> It worked for me in Windows 7 Prof 64 bit.
That was with Eclipse 3.7.1 32 bit.

After switching to Eclipse 3.7.2 64 bit, "Disable visual themes" no longer helps.