OsX Spaces

From Lundman Wiki
Revision as of 08:54, 7 December 2009 by Lundman (talk | contribs)

OsX Spaces

For those of you with older OsX, you might have run VirtuaDesktop or similar, where you can change the 'switch from one desktop space to another'-animation in the setup. With SnowLeopard, it has 'Spaces' built in. Unfortunately, you can not change the animation, or speed of the animation for the Workspace-switch.

For me, the animation is rather annoying, and irritates my eyes. So I have attempted to see if I can remove it, or change the speed to be so fast it is virtually instant.

The Spaces/Dock appear to send the com.apple.switchSpaces notification when you attempt to change spaces.

This appears to be handled in CoreGraphics, or more precisely /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/CoreGraphics.framework/Versions/A/CoreGraphics.

There appears to be two top-level functions for it:

│__text:0000000000212F43                 public _CGSSetWorkspaceWithTransition 
│__text:0000000000212F43                                                      
│__text:0000000000212F43                 push    rbp             ; extern OSStatus CGSSetWorkspaceWithTransition(const CGSConnection cid,
│__text:0000000000212F43                                         ;         int workspaceNumber, CGSTransitionType transition, CGSTransitionOption subtype,
│__text:0000000000212F43                                         ;         float time);


│__text:0000000000213014                 public _CGSSetWorkspace
│__text:0000000000213014                 push    rbp             ; extern OSStatus CGSSetWorkspace(const CGSConnection cid, int workspace);


The comments are my additions to random API/Header files I have come across. What is peculiar is that CGSSetWorkspace actually appears to take 3 arguments. The logic for the 3rd argument goes as follows:

switch($arg3) {
  case 2:
     ecx  = 0x10000001;
     xmm0 = 0x40800000;  (float for Decimal=4)
     break;
  case 3:
     ecx  = 0;
     xmm0 = 0;
     break;
  case 1:
     ecx  = 0;
     xmm0 = 0x3e4ccccd;  ( float for Decimal=0.2)
     break;
  default:
     ecx  = 0x10000001;
     xmm0 = 0x3e4ccccd;  ( float for Decimal=0.2)
  }

__CGSSetWorkspace();

As you can guess, xmm0 is the float value of time as also specified in CGSSetWorkspaceWithTransition. The Dock appears to be the program to call CGSSetWorkspace(), interestingly not the CGSSetWorkspaceWithTransition(). So I was assuming that with ecx set to 'use the default', CoreGraphics kicks in and sets the time to 0.2 for normal, and 4 for the 'slow version' (hold shift).

However, binary edit of CoreGraphics and reboot did not have any direct/noticeable difference that I can see. Presumably ecx=3 should be 'Set Directly'.

For some peculiar reason, I can not load Dock into IDAPro, it just does not like it. So I am unsure what values the Dock sends.

However, gdb confirms the values sent to CGSSetWorkspace are as follows:

rax            0x0      0
rbx            0x0      0
rcx            0x7fff84405e3a   140735412198970
rdx            0x3      3
rsi            0x2      2
rdi            0x6d0b   27915
rbp            0x10bed7ce0      0x10bed7ce0
rsp            0x10bed7ca0      0x10bed7ca0
r8             0x87b3   34739
r9             0x0      0
r10            0x2c     44
r11            0x1200   4608
r12            0x0      0
r13            0x4      4
r14            0x10     16
r15            0x6      6
xmm0           0

Which means Dock is using type = 3, and ecx = 0 and xmm0 = 0. Disappointing.