Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

DeskMan: Window-Manager, Expose-Clone, miniMIZE, V-Desk


  • Please log in to reply
45 replies to this topic

Poll: Did you Try Deskman, and did it work (7 member(s) have cast votes)

Did you Try Deskman, and did it work

  1. Yes, nice app, i like it (works good) (2 votes [28.57%])

    Percentage of vote: 28.57%

  2. Tried it but deleted it fast (does not work for me) (3 votes [42.86%])

    Percentage of vote: 42.86%

  3. Dont like it (2 votes [28.57%])

    Percentage of vote: 28.57%

Vote Guests cannot vote
holomind
  • Members
  • 341 posts
  • Last active: Aug 23 2015 03:27 PM
  • Joined: 11 Mar 2006
*Updated 2006-08-10 *

This Thread is about Desktop-Manager, which combines several Ideas into one which is quite perfect for me.


After using "SphereXP" and "Scalable Fabric" from Mircrosoft and "TopDesk" Expose-Clone and "miniMIZE" (simply google for the quoted words) i found them quite good but annoying in some parts so i wrote my first AHK script and i am very happy with my new window manager.

Screenshots:
Posted Image
DeskMan - Dock, with Taskbar on right (100px wide) and Dock inside

Posted Image
DeskMan - Dock, with Taskbar on right (30px wide) and Dock outside

Posted Image
DeskMan - Dock, with Taskbar on bottom (outside) , inside also possible

I changed the Zip and compiled into an .exe, when you start it once it will install/extract the needed components (extracts files in directory of deskman.exe) wich are:
* the source DeskMan.*.ahk
* i_view32.exe ( for taking the screenshots, this is the freeware Irfanview ...link to be inserted here ...
* s.gif ( a transparent pixel as placeholder )


Versions, ahk-script:
DeskMan.ahk (latest = 0.5)
DeskMan_v0.5.ahk
DeskMan_v0.4.ahk
DeskMan_v0.3.ahk
DeskMan_v0.2.ahk
DeskMan_v0.1.ahk

Ini:
DeskMan.ini (my current ini-file)

Its a little bit similar to this (but i show the thumbs in a dock all the time)
Visual Task Tips

Visually its quite similar to :
Firefox: Tab Sidebar
Now i end up with TabSidebar on the left and Deskman on the right. Leaving framed content in the middle. Thumbnail-Overkill ? ;)

The Idea: Its a Mix of other Apps so i will explain what it does.

Like a Apple-Dock it sits on one side of the Screen/Desktop and shows Thumbnails of your active Windows like "miniMIZE".

The thumbnails are automatically refreshed, when you open or close or alt-tab some windows. this is cached as much as possible and should be fast. the repaint is every 1second, but only done if it really changes.
if the window-title changed (eg you surf another webpage in your browser the thumb gets refreshed, also with download dialogs) only the foregroundwindow gets refreshed for efficiency, and i also dont know a way to make screenshots of windows in background without activating them)

If something is going funny you can force a repaint with f10, you can also auto-maximize all your windows so the fit neat to the rest of your desktop (screen - dock - taskbar) with f9 .
You can click on the thumbnails to restore or bring to front this window.
the thumbnails are get by irfanview (capture active window) and stored and reused. to force a new getscreen you can press f10 which also removes closed windows from the dock.

If you restore a window with click on the thumbnail it also gets maximized without the dock and taskbar space.

when a window is smaller than half-screen-width then its not maximized as some dialog-boxes look bad when maximized.

the script is based on the multimonitor-tool as it showed me how to use irfanview with AHK.

The script is now optimized to autodetect the position of your taskbar and docks beside it or even into it. (actually its only an overlay but on the right position so it feels like its in the taskbar)

There are some nice Window-Managing functions on the Hotkeys also.

Current used Hotkeys:
see the beginning of the sourcecode for the latest hotkeys, i changed them several times

f12: repaint all windows (gets fresh thumbnails and clears cache)
f9 : like f12 but it also maximizes all your window to fit the position of taskbar + dock. (usefull if you change the position of your taskbar)

Some Resizing Functions:
win-up or altgr-up : make window half-size attached on top
win-down or altgr-down : make window half-size attached on bottom
win-left or altgr-left : make window half-size attached on left
win-right or altgr-right : make window half-size attached on right
win-enter or altgr-enter : maximize window to work-space size
altgr-PgUp / altgr-PgDn : similar to alt-tab switch to pref/next window continuously (on my keyboard PgUp and PgDn are next to arrows)

Special Combo-Move:
win-1: arrange last two windows horizontally
win-2: arrange last two windows vertically
win-3: restore / maximize last two windows (undo win1 and win2)

* New: Fullscreen (PaperSize) View
alt-gr -(minus): toggle between, [ normal | paper | fullscreen ], with this function you can have near fullscreen for all your apps, or restrict them to A4 like view for reading documents, instead of wide-view.

* New: Added Icon and Window-Title to screenshots
Now its easier to find the right windows if the screenshots are too similar.
(works best with taskbar on right side of screen, as there is little feedback in this forum about this script i make it only compatible or bugfixes on request ;)

*alt-gr #: can launch 320mph with an hotkey, very convenient as deskman runs all the time you can launch 320mph with one keypress.
The file has now a config-file for the most important values in an ini-reader based on WinSize.ahk from Skrommel.

* New: several little Bugfixes and optimizations.


(thanks for the many hints in this forum/thread to make things better )

Have Fun and experiment with it ;)

Daniel

#NoEnv

#SingleInstance	,Force								; configuration 
SetBatchLines	,-1
SetWinDelay 	,0
CoordMode	    ,Mouse,Screen
CoordMode	    ,ToolTip,Screen

countps = 0 

Main: ; this is only for reading, there is no "Main:" beeing called ;)
  Gosub, Configuration      ; Read from configfile
  Gosub, CreateFiles        ; Create some files and dirs
  Gosub, GetTaskbarPos      ; the taskbar
  Gosub, GetThumbSizes      ; calc the thumbnail dims
  Gosub, GetWorkPos         ; the area of "normal" windows
  Gosub, GetDockPos         ; the deskman-dock
  Gosub, InitDockGui        ; paint dock with picture placeholders
  Gosub, TRAYMENU			; init trayicon
  Gosub, WinBottom          ; move deskman away (needed when inside taskbar ?
  Gosub, RefreshDock         ; Get Fresh Thumbnails 
 ;Gosub, DEBUG
Return


Configuration: 
  BinDir                = %A_ScriptDir%\DeskManBin
  TempDir               = %A_ScriptDir%\DeskManTemp
  FastDir               = "E:\My Files"
  file_320mph           = %A_ScriptDir%\..\320mph\320mph.ahk
  file_iview		    = %BinDir%\i_view32.exe
  file_spacer		    = %BinDir%\s.gif 
  appTitle              = DeskMan - Dock
  appName               = DeskMan           ; perhaps this can be read automatically ?
  PaperSizeMode         = "Off"


; --------------- gestures
SetMouseDelay 			-1
SetDefaultMouseSpeed 	0
mg_active 				= 0
timeout 				= 100		; approx. half a second
sensitivity 			= 50		; this many pixels required before being accepted
gestures 				= -L-R-U-D-UU-DD-UL-UR-DR-RL-UUU-LLL-
excluded 				= Pixia
disabled 				= Minesweeper,Cheat Mine

;------------------------------------------------------------------------------

  wincorrect_y  = 1
  repaintcounter =0
      
  Gosub ,READINI

  ; Screenlayout: 
  ;  1  2 
  ;  3  4 

  ; define some Hot-Keys (win + arrow , or alt-gr + arrow (1 hand only!)
  Hotkey, <^>!#     , Run320Mph           ; Launch 320Mph
  Hotkey, #s        , OpenFastDir         ; Open special dir
  Hotkey , #Up , HalfUp
  Hotkey, <^>!Up    , HalfUp              ; Resize Window to take upper half  Sector( 1 + 2 ) 
  Hotkey , #Down , HalfDown
  Hotkey, <^>!Down  , HalfDown            ; Resize Window to take lower half  Sector( 3 + 4 ) 
  Hotkey, <^>!Left  , HalfLeft            ; Resize Window to take left half  Sector( 1 + 3 ) 
  Hotkey, <^>!Right , HalfRight           ; Resize Window to take right half  Sector( 2 + 4 ) 
  Hotkey, <^>!Enter , MaximizeWindow      ; Resize; Maximize the window Sector( 1 + 2 + 3 + 4 )
  Hotkey, <^>!-     , TogglePaperSize     ; Resize; Make Portrait-Layout (A4) for reading purpouse
  Hotkey, #4        , TogglePaperSizeOn   ; Resize; A4
  Hotkey, #5        , TogglePaperSizeFull ; Resize; Fullscreen (hide taskbar)
  Hotkey, #6        , TogglePaperSizeOff  ; Resize; Maximize restore taskbar (Bug Desktop icons are gone)
  Hotkey, #7        , FixTNMGraph  ; 
  Hotkey, !F11      , SpecialFullScreen
  Hotkey, <^>!PgDn  , NextWindow          ; Alt-Esc (similar Alt-Tab) to Next Window (Task)
  Hotkey, <^>!PgUp  , PrevWindow          ; shift Alt-Esc (similar Alt-Tab) to Previous Window (Task)
  Hotkey, ^f9        , RefreshDockMax      ; Maximize all Windows
  Hotkey, ^f12       , RefreshDock         ; Repaint Thumbnails and clear cache
  Hotkey, ^f8       , ReloadScript        ; For easier Programming
Return 

L_Action: 
	Gosub, PrevWindow
return

R_Action: 
	Gosub, NextWindow
return

U_Action: 
	Gosub, HalfUp
return

D_Action: 
	Gosub, HalfDown
return

UU_Action:
    Gosub, MaximizeWindow
return

LLL_Action:
	WinClose, A
return

UUU_Action:
	Gosub, ReloadScript
return 

DD_Action:
	Send, {F10}
return

UL_Action:
     ResizeWin( work_x , work_y, ceil( work_w / 2 ), ceil( work_h / 2 ) )
return

UR_Action:
     ResizeWin( work_x + ceil( work_w / 2 ), work_y, ceil( work_w / 2 ), ceil( work_h / 2 ) )
return

DL_Action:
     ResizeWin( work_x , work_y + ceil( work_h / 2 ), ceil( work_w / 2 ), ceil( work_h / 2 ) )
return

DR_Action:
     ResizeWin( work_x + ceil( work_w / 2 ), work_y + ceil( work_h / 2 ), ceil( work_w / 2 ), ceil( work_h / 2 ) )
return

CreateFiles:
  FileCreateDir	          , %TempDir%
  FileCreateDir           , %BinDir%
  FileInstall,i_view32.exe, %BinDir%\i_view32.exe,0
  FileInstall,s.gif       , %BinDir%\s.gif,0
  FileInstall,DeskMan.ahk , %BinDir%\DeskMan_v0.5.ahk,0
Return

HalfUp:
    ResizeWin( work_x, work_y, work_w, ceil( work_h / 2 ) )       
Return 

HalfDown:
    ResizeWin( work_x, ceil( work_h / 2 ), work_w, ceil( work_h / 2) )     
Return 

HalfLeft:
    ResizeWin( work_x, work_y, ceil( work_w / 2), work_h )     
Return 

HalfRight:
    ResizeWin( work_x + ceil(work_w / 2)  , work_y , ceil(work_w/2), work_h )    
Return 

FixTNMGraph:
    WinMove ,ahk_class TNMGraph, , 1296,  -2 , 100, 30    
Return 

MaximizeWindow:
    if PaperSizeMode <> "off" 
      ResizeWin( 0 , 0 , A_ScreenWidth  , A_ScreenHeight   )    ; fullscreen
    else
      ResizeWin( work_x ,work_y , work_w, work_h )              ; without taskbar
Return 

TogglePaperSize:
    if PaperSizeMode = "off" 
    {
        WinHide ahk_class Shell_TrayWnd
        WinHide ahk_id %deskman_id%
        WinHide,Program Manager
        SetTimer, RepaintDock , off
        Gosub, TogglePaperSizeOn
        SetTimer, RepaintDock , off
    }
    else if PaperSizeMode = "on"
    {
        WinHide ahk_class Shell_TrayWnd
        WinHide ahk_id %deskman_id%
        WinHide,Program Manager
        SetTimer, RepaintDock , off
        Gosub, TogglePaperSizeFull
        SetTimer, RepaintDock , off
    }   
    else ;if PaperSizeMode = "full"
    {
        WinShow ahk_class Shell_TrayWnd  ; Taskbar
        WinShow ahk_id %deskman_id%      ; Deskman-Dock
        WinShow,Program Manager          ; Desktop
        SetTimer, RepaintDock , off
        Gosub, TogglePaperSizeOff
        forcerepaint = 1
        Gosub, RepaintDock 
    }   

Return

PaperSize:
    ResizeWin( work_x + work_w / 8 ,work_y , work_w - work_w / 4, work_h )
Return

Run320Mph:
    RunWait,%file_320mph%
Return

TogglePaperSizeOn:
    PaperSizeMode="on"
    WinGet, paperactive_id, ID, A
    WinSet, Style, -0xC00000, A
    
    WinGetActiveStats, title, w, h, x, y 

    if ( w > minwidth ) 
        Gosub, PaperSize

    
    SetTimer, RepaintDock , off
    
    ; loop until current_id is in front (max is all processes)
    WinGet, ids, list,,, Program Manager
	loop, %ids%
    {
      win_id :=ids%a_index% 

      if ( win_id <> paperactive_id )
      {
        if ( winIsDocked%win_id% = 1 )
        {  
            WinMinimize, ahk_id %win_id%
            winisminimized%win_id% = %win_id% 
        }
      }
    }

    WinActivate, %paperactive_id%    
    WinShow, %paperactive_id%    
    
    ;SetTimer, RepaintDock , %repainttimer%
Return

TogglePaperSizeFull:
    PaperSizeMode="full"
    WinGet, paperactive_id, ID, A
    WinSet, Style, -0xC00000, A
    
    WinGetActiveStats, title, w, h, x, y 

    if ( w > minwidth ) 
        Gosub, MaximizeWindow

    
    SetTimer, RepaintDock , off
    
    ; loop until current_id is in front (max is all processes)
    WinGet, ids, list,,, Program Manager
	loop, %ids%
    {
      win_id :=ids%a_index% 

      if ( win_id <> paperactive_id )
      {
        if ( winIsDocked%win_id% = 1 )
        {  
            WinMinimize, ahk_id %win_id%
            winisminimized%win_id% = %win_id% 
        }
      }
    }

    WinActivate, %paperactive_id%    
    WinShow, %paperactive_id%    
    
    ;SetTimer, RepaintDock , %repainttimer%
Return

TogglePaperSizeOff:
    PaperSizeMode="off"
    WinGet, paperactive_id, ID, A
    WinSet, Style, +0xC00000, A
    
    Gosub, WinBottom          ; move window away
    
    SetTimer, RepaintDock , off

    ; loop until current_id is in front (max is all processes)
    WinGet, ids, list,,, Program Manager
	loop, %ids%
    {
      win_id :=ids%a_index% 
      if ( win_id <> paperactive_id )
      {
        if ( winisminimized%win_id% = win_id )
        {
          WinRestore, ahk_id %win_id%
          Gosub, WinBottom          ; move window away
          winisminimized%win_id% = 
        }
      }
    }


    WinActivate, %paperactive_id%    
    WinShow, %paperactive_id%    
    
    WinGetActiveStats, title, w, h, x, y 

    if ( w > minwidth ) 
        Gosub, MaximizeWindow

    ;SetTimer, RepaintDock , %repainttimer%
Return

OpenFastDir:
	RunWait, explorer %FastDir%
Return

SpecialFullScreen:
    Send, {F11}
    Gosub, MaximizeWindow
Return 

NextWindow:
    Send, !+{esc}
Return 

PrevWindow:
WinBottom:
    Send, !{esc}
Return 

InitDesktopDC:
    ; desktop_id = "Program Manager"
    ; hdc_desktop = getDC "Program Manager"
    ; hdc_deskman = getDC "DeskMan"
    WinGet desktop_id , ID, "Program Manager" 

    hdc_desktop := DllCall("GetDC", UInt, desktop_id)
    hdc_deskman := DllCall("GetDC", UInt, deskman_id)
Return

CaptureDCThumb:
   ; capture the current Desktop (or active Win) into the thumbnail
   ; y-position is either slot of pos_y_%win_id% or created on the fly and appended = height_max
   ; windows are redrawn or appended, position keeps until window is closed
   ; this also means no swaping of windows any more, but this also means the first is not the active
   ; perhaps easier to hit target as thumbs dont move away! (like old taskbar!)
   ; alt-tab is seldom used in deskman by mouse but only with keys
   ; rearange of thumbs would be nice but not really needed. (swap algo? one spare thumb to move image)
   ; does bitblt work if gui cropped ? and bitblt is painting on non existent window ?
   ; as we know the win-position by ahk_id, we can repaint the window with usage of PrintWindow at wish
Return


InitDockGui:

  ; add some picture-placeholder (dock-positions) 
  y=0										
  x=0

  Loop,  %maxthumbs%
  {
      y-=2
      ; Icon Titlebar
      Gui, Add, Pic , gRestoreWin x%x% y%y% w12 h12  vPicB%a_index%			; add dock-slots to gui
      y+= 14

      ; Thumbnail
      Gui, Add, Pic , gRestoreWin x%x% y%y%   vPic%a_index%			; add dock-slots to gui
      x2 := x+15
      y2 := y-10

      ; Title-Text
      Gui, Font, s6
      Gui, Add, Text , vText%a_index% x%x2% y%y2% h6 w2000 r1 #fcfcfc, 
     
      if ( taskbar_pos = "left" or taskbar_pos ="right" )
        y +=  %thumb_h% 								; move pointer for next pos
      else
      { 
         x +=  %thumb_w%							; move pointer for next pos
         y -= 12 ; restore y titlebar
      }
  }

  Gui, -Caption									; window-style / chrome
  Gui, +ToolWindow
  Gui, +AlwaysOnTop +LastFound +Owner  ; +Owner prevents a taskbar button from appearing.

  Gui, Show,	x%dock_x%	y%dock_y%	w%dock_w%	h%dock_h% ,	%appTitle%		; display window/Toolbar

  WinGet, deskman_id, ID, %appTitle%       ; fetch deskman_id for fast checks
  Gosub, DockToFront 
  ;SetTimer, DockToFront, %repainttimer%
 
Return

GetTaskbarPos:
    ; get dimensions and position of taskbar (specialcase autohide ?)
    WinGetPos, taskbar_x, taskbar_y, taskbar_w, taskbar_h, ahk_class Shell_TrayWnd 

    ; find out if its on top/left/bottom/right with its x,y
    ; x0,y0 ( w < h )  means its on top 
    if ( taskbar_x < 10 and taskbar_w < taskbar_h ) 
        taskbar_pos = left
    
    ; x0,y0 ( w >=  h )  means its on left
    if ( taskbar_x < 10 and taskbar_w >= taskbar_h )     
        taskbar_pos = top
    
    ; x+,y0 means its on right
    if ( taskbar_x > 10 )
        taskbar_pos = right
    
    ; x0,y+ means its on bottom
    if ( taskbar_y > 10 )
        taskbar_pos = bottom
      
Return


GetThumbSizes:
    ; calculate size of a thumbnail
    thumb_w       := ceil( A_ScreenWidth  / maxthumbs )                             ; width of dock (also thumbnail-width)
    thumb_h       := ceil( A_ScreenHeight / maxthumbs )                              ; height of thumbnails
Return

GetWorkPos:
    ; default without taskbar

    if ( insidetaskbar = "1" )
    {
      dock2_w = 0
      dock2_h = 0
    }
    else
    {
      dock2_w := thumb_w
      dock2_h := thumb_h
    }
    
    if taskbar_pos = left
    {
      work_x        := dock2_w + taskbar_w + work_border 
      work_y        := work_border - 1
      work_w        := A_ScreenWidth  - taskbar_w - dock2_w -work_border -work_border
      work_h        := A_ScreenHeight - work_border +1
    }
    if taskbar_pos = top
    {
      work_x        := work_border
      work_y        := dock2_h + taskbar_h + dock_border + work_border - 1
      work_w        := A_ScreenWidth  - work_border -work_border
      work_h        := A_ScreenHeight - taskbar_h - dock_h  -work_border -workborder +1
    }
    if taskbar_pos = bottom
    {
      work_x        := work_border
      work_y        := work_border -1
      work_w        := A_ScreenWidth  -work_border -work_border 
      work_h        := A_ScreenHeight - taskbar_h - dock2_h -work_border -work_border +1
    }
    if taskbar_pos = right
    {
      work_x        := work_border 
      work_y        := work_border -1
      work_w        := A_ScreenWidth - taskbar_w - dock2_w -work_border -work_border 
      work_h        := A_ScreenHeight - work_border -work_border +1
    }

    ; irfanview needs integer and not float so lets precalc it here and dont mess with casting later
    work_h_half   := ceil( work_h  / 2 )
    work_w_half   := ceil( work_w  / 2 )

    
    ; windows smaller than half get part-shot and not full window
    minwidth      := work_w_half      
Return

GetDockPos:

    if ( insidetaskbar = 1 )
    {
        if taskbar_pos = right
        {
          dock_x := work_x + work_w + work_border + dock_border  ; + 2
          dock_y := insidetaskbar_y0
          dock_w := thumb_w
          dock_h := A_ScreenHeight - insidetaskbar_y0 - insidetaskbar_yf
        }

        if taskbar_pos = left
        {
          dock_x := taskbar_w - dock_border 
          dock_y := insidetaskbar_y0
          dock_w := thumb_w
          dock_h := A_ScreenHeight - insidetaskbar_y0 - insidetaskbar_yf
        }

        if taskbar_pos = top
        {
          dock_x := insidetaskbar_x0
          dock_y := taskbar_h - dock_border
          dock_w := A_ScreenWidth - insidetaskbar_x0 - insidetaskbar_xf
          dock_h := thumb_h
        }

        if taskbar_pos = bottom
        {
          dock_x := insidetaskbar_x0
          dock_y := work_y + work_h +work_border + dock_border 
          dock_w := A_ScreenWidth - insidetaskbar_x0 - insidetaskbar_xf 
          dock_h := thumb_h 
        }
    }
    else
    {
        if taskbar_pos = right
        {
          dock_x := work_x + work_w + work_border + dock_border + 2
          dock_y := 0
          dock_w := thumb_w
          dock_h := A_ScreenHeight
        }

        if taskbar_pos = left
        {
          dock_x := taskbar_w - dock_border
          dock_y := 0
          dock_w := thumb_w
          dock_h := A_ScreenHeight
        }

        if taskbar_pos = top
        {
          dock_x := 0
          dock_y := taskbar_h - dock_border
          dock_w := A_ScreenWidth
          dock_h := thumb_h
        }

        if taskbar_pos = bottom
        {
          dock_x := 0
          dock_y := work_y + work_h + work_border + dock_border 
          dock_w := A_ScreenWidth 
          dock_h := thumb_h
        }
    }
Return


ResizeWin( XPos, YPos, XSize, YSize )
{
    
    WinGet, active_id, ID, A        ; fetch active foreground-window
    
    if ( active_id = deskman_id )
        return 

    ; correct some pixels in positioning to look "just right"
    ;YPos  := YPos  - wincorrect_y
    ;YSize := YSize + wincorrect_y 
    
    WinMove, ahk_id %active_id%, , %XPos% , %YPos%  , %XSize% , %YSize% 

    ; invalidate window so it gets refreshed next time
    WinIsDocked%active_id% = 
    
    ;Gosub, DockToFront    
}


DockToFront: 
      ; force DeskMan to Front
      Gui, +AlwaysOnTop +LastFound +Owner  ; +Owner prevents a taskbar button from appearing.
Return
   
RefreshDockMax:
    maximizeall = 1
    Gosub, RefreshDock
Return


RefreshDock:
    Gosub, DockToFront

    SetTimer, RepaintDock , Off ; clear old timers

	; remove thumbnails
	FileDelete, %TempDir%\*


    ; keep active window!
    WinGet, current_id, ID, A
      
    ; start with active
    Gosub, CaptureThumbActive
    winIsDocked%capture_id% = 1
    capture_id =x            ; clear
	    
    ; loop until current_id is in front (max is all processes)
    WinGet, ids, list,,, Program Manager
	loop, %ids%
    {
       
        if ( capture_id <> current_id )
        {
          Gosub, WinBottom

          if maximizeall = 1
          {
            WinGetActiveStats, title, w, h, x, y 

            if ( w > minwidth ) 
                ResizeWin( work_x ,work_y , work_w, work_h )
          }

          Gosub, CaptureThumbActive
          
          winIsDocked%capture_id% = 1
        }
    }


    forcerepaint = 1
    maximizeall = 0
    Gosub,  RepaintDock 

return

RepaintDock:        ; remove closed thumbs but dont do much (as this is done in a loop!)
    SetTimer, RepaintDock , off ; clear old timers

    if ( forcedocktofront = "1" )
    {
      Gosub, DockToFront
    }

    
    ; try to add foreground-window to dock if not in there ( changes are good we hit it shortly after start-new)

    WinGet, active_id, ID, A
    WinGetTitle, title, ahk_id %active_id%

    ;tooltip, %repaintcounter%
    if repaintcounter > 10
    {
        forcerepaint = 1
        winIsDocked%active_id% =
    }

    ; detect and add new windows
    if ( winIsDocked%active_id% = "" or winIsDockedTitle%active_id% <> title) 
    {
      winIsDockedTitle%active_id% := title ; store title and repaint if this changes

      ;sleep, 500 ; give the window a little bit time to render itself
      Gosub, CaptureThumbActive
      winIsDocked%capture_id% = 1
      ; thumb_w , thumb_h
      GuiControl,1:,Pic1,   *w%thumb_w% *h%thumb_h%	%TempDir%\thumb_%capture_id%.bmp 

      ; copy the dc for this picture
    }
    
    ; test if display has changed !

    dockedNewCount = 0								; start with empty dock
						
	Loop, %maxthumbs%
	{
		dockIdNew%a_index% = 						;clear
	}

    ; stack minimized windows into dock					;this way all "non-dead" minimized windows get stacked into dock
	WinGet, ids, list,,, Program Manager
	Loop, %ids%
	{
		StringTrimRight, id, ids%a_index%, 0				; find the id of this window
	
		if winIsDocked%id%						; is window with this id in dock already ?
        {
            dockedNewCount	+= 1					; how many slots are used already ?		
			dockIdNew%dockedNewCount% = %id%				; remeber id for this position
	    }

    }
    
	; fill with file_spacer if empty
	loop, %maxthumbs% 
	{
        val1 := DockId%a_index%
        val2 := DockIdNew%a_index% 

		if ( val1 <> val2 )
        {
			forcerepaint = 1
            Gosub, DockToFront

        }
	}

    
    if forcerepaint <>
    {
      
      dockedCount = 0								; start with empty dock
                          
      Loop, %maxthumbs%
      {
          dockId%a_index% = 						;clear
      }

      ; stack minimized windows into dock					;this way all "non-dead" minimized windows get stacked into dock
      WinGet, ids, list,,, Program Manager
      Loop, %ids%
      {
          StringTrimRight, id, ids%a_index%, 0				; find the id of this window
      
          if winIsDocked%id%						; is window with this id in dock already ?
          {
              dockedCount	+= 1					; how many slots are used already ?		
              dockId%dockedCount% = %id%				; remeber id for this position
              title := winIsDockedTitle%id%

              GuiControl,1:,Pic%dockedCount% ,   *w%thumb_w% *h%thumb_h%	%TempDir%\thumb_%id%.bmp 
              GuiControl,1:,PicB%dockedCount%,   *w12 *h12	%TempDir%\thumbB_%id%.bmp 
              
              if ( forcetitlerepaint = "1" )
              {
                  GuiControl,1:,Text%dockedCount%,   %title%
              }
          }

      }
      
      ; fill with file_spacer if empty
      loop, %maxthumbs% 
      {
          if DockId%a_index% =
          {
              GuiControl,1:,Pic%a_index%,   *w%thumb_w% *h%thumb_h%	%file_spacer%			
          }
      }
        
      repaintcounter =0
      Gosub, TryResizeDock      
      Gosub, DockToFront

    } ; end forcerepaint
    forcerepaint   =        ; try not to draw in next round (but its multithreaded!) somebody can click restore while repaint, 
    
    if ( forceautorefresh = "1")
    {
      repaintcounter := repaintcounter +1 
    }

    SetTimer, RepaintDock , %repainttimer%

Return

TryResizeDock: 
    if ( forcedocktransparent = "1")
    {
        newheight := dockedNewCount * ( thumb_h + 12 )
        if ( newheight > dock_h ) 
            newheight := dock_h

        newwidth  := dockedNewCount * thumb_w
        if ( newwidth > dock_w ) 
            newwidth := dock_w

        
        if ( taskbar_pos ="left" or taskbar_pos="right" )
            WinMove , ahk_id %deskman_id% ,, %dock_x%, %dock_y%, %dock_w% , %newheight% 
        else
            WinMove , ahk_id %deskman_id% ,, %dock_x%, %dock_y%, %newwidth% , %dock_h% 
    }
Return

CaptureThumbActive: 
    WinGet                     , captureactive_id, ID, A
    winGetTitle, title , ahk_id %captureactive_id%
    WinGetClass, class , ahk_id %captureactive_id%					;get Class-name

    capture_id = 

    if ( title = ""  or captureactive_id = deskman_id )				; skip DeskMan Window (recursion!)
      return

    ; skip some programs not good with deskman 
    if class in TPickSessionDlg,TForm,TFormMain,TBaseLoadErrorDlg,Shell_TrayWnd,DV2ControlHost,ZORRO,Progman, tooltips_class32,AutoHotkeyGUI,TForm4,AutoHotkeyGUI,TfrmDUGraph,TNMGraph	
        return
    
    Gosub, CaptureThumb 
return 

CaptureThumb: 
	capture_id := captureactive_id

    sleep, 100
    wingetpos, x, y, width, height, ahk_id %capture_id%	; read width from capture-window
    if ( y < A_ScreenHeight - 50 )   ; dont snap offscreen pics => PrintWindow ?
    {
	if ( width < minwidth )
	{	
        ; get picture cropped so we see more detail
		RunWait,%file_iview% /silent  /capture=1 /crop=(0`,0`,%work_w_half%`,%work_h_half%)  /resample=(%thumb_w%`,%thumb_h%)   /convert=%TempDir%\thumb_%capture_id%.bmp
	}
	else
	{
        ; get thumb of active window
		RunWait,%file_iview%  /silent /jpgq=100 /capture=1    /resample=(%thumb_w%`,%thumb_h%)  /convert=%TempDir%\thumb_%capture_id%.bmp
	}	
    }
	
	; always capture icon and title
	RunWait,%file_iview% /silent  /capture=1 /crop=(0`,0`,24`,24)  /resample=(12`,12)   /convert=%TempDir%\thumbB_%capture_id%.bmp
return

RestoreWin: 

    StringReplace, pos , A_GuiControl, Pic

    SetTimer, RepaintDock , off
    
    Gosub, WinBottom ; undo the click on deskman
    ; find active window, which is on top of stack, DeskMan is active because of click 
    
 
    ; get some lookups
	forcerepaint    = 1
	dockIdpos       := dockId%pos%
	id              := dockId%pos%

    if ( winIsDocked%id% <> "" )
    {
      ; activate restored id
      WinActivate, ahk_id %id%	
      WinGetTitle, title, ahk_id %id%
      wingetpos, x, y, width, height, ahk_id %id%
      
      ; only maximize and move big windows, as small ones eg. dialogboxes dont like maximize
      if ( width > minwidth )
      {
          ResizeWin( %work_x%, %work_y%, %work_w%, %work_h% )
      }

      winIsDocked%id% = ; force repaint in next interval
    }

    Gosub, RepaintDock

Return

RButton::
 
  MouseGetPos,,, id
  WinGetTitle mg_title, ahk_id %id%
  if mg_title contains %disabled%
    Suspend
  else if mg_title not contains %excluded%
  {
    mg_active = 1
    mg_executed = 0
    mg_rheld = 0
    mg_str =
    mg_idletime = 0
    ifEqual mg_show,, ToolTip %A_Space%
    MouseGetPos px, py
    px2 = %px%
    py2 = %py%
    loop
    {
      GetKeyState st, RButton, P
      if st = U
      {
	ifEqual mg_show,, ToolTip
	if mg_rheld = 0
	{
	  mg_active = 0
	  if mg_executed = 0
	  if mg_str =
	    MouseClick R
	  else ifInString gestures, -%mg_str%-
	    gosub %mg_str%_Action
          else ifEqual mg_rclick,,
	    MouseClick R
	}
	else
	  MouseClick R,,,,,U
	return
      }
      else if mg_idletime < %timeout%
      {
	MouseGetPos dx, dy
	dx -= %px2%
	dy -= %py2%
	if dx > %sensitivity%
	  mg_dir = R
	else if dx < -%sensitivity%
	  mg_dir = L
	else if dy > %sensitivity%
	  mg_dir = D
	else if dy < -%sensitivity%
	  mg_dir = U
	if mg_dir <>
	{
	  mg_str = %mg_str%%mg_dir%
	  ifEqual mg_show,, ToolTip %mg_str%
	  MouseGetPos px2, py2
	  mg_idletime = 0
	  mg_dir =
	}
	else
	  mg_idletime++
      }
      else
      if mg_rheld = 0
      if mg_executed = 0
      {
	MouseGetPos px2, py2
	if px2 <> %px%
	if py2 <> %py%
	{
	  ifEqual mg_show,, ToolTip
	  MouseClick R, %px%, %py%,,,D
	  MouseMove %px2%, %py2%
	  mg_rheld = 1
	  mg_active = 0
	}
      }
      Sleep 10
    }
  }
  mb = R
goto ButtonWait

ButtonWait:
  MouseClick %mb%,,,,,D
  loop
  {
    GetKeyState st, %mb%Button, P
    ifEqual st, U, break
    Sleep 10
  }
  MouseClick %mb%,,,,,U
return

ReloadScript:
	Reload ; 
	Sleep 200 ; If successful, the reload will close this instance during the Sleep, so the line below will never be reached.
	MsgBox, 4,, The script could not be reloaded. Would you like to open it for editing?
	IfMsgBox, Yes, Edit
Return

DEBUG:
  tooltip, %work_x% %work_y% %work_w% %work_h% 
Return

TRAYMENU:
    Menu,Tray,Add,&Settings,SETTINGS
	Menu,Tray,Add,DeskMan,ABOUT
	Menu,Tray,Add
	Menu,Tray,Add,&About,ABOUT
	Menu,Tray,Add,E&xit,EXIT
	Menu,Tray,Default,DeskMan
Return

ABOUT:
   about=
     (LTrim
        DeskMan
        `nControl all your Windows, similar to Apple-Dock but different ;)
        `n`nThis program uses IrFanView by Irfan Skiljan.
        `nHolomind @2006   
        (based on) MultiMonMan Skrommel @2006    www.donationcoders.com/skrommel
     )
   MsgBox,0,DeskMan,%about%
Return

SETTINGS:
  Gosub,READINI
  RunWait,%appName%.ini
  Gosub,READINI
Return

READINI:
  IfNotExist,%appName%.ini
  {

    ini=
    (LTrim
        `;[Settings]
        `;maxthumbs       = 14    ; how many thumbs to show ( screenheight / maxthumbs = thumbheight )? 
        `;work_border     = 4     ; looks nicer
        `;dock_border     = 0     ; make a gap between dock and your window. 
        `;repainttimer    = 1000  ; msecs
        `;forcedocktofront=0   ; force at every repaint desman to always on top
        `;forcedocktransparent=0   ; force at every repaint desman to always on top
        `;insidetaskbar    = 0    ; 
        `;insidetaskbar_x0 = 70  ; when needed move this much (eg. startbutton)
        `;insidetaskbar_y0 = 30   ; when needed move that much (eg. startbutton)
        `;insidetaskbar_xf = 200  ; when needed keep free on right (eg. trayicons+clock)
        `;insidetaskbar_yf = 200   ; when needed keep free on bottom (eg. trayicons+clock)
        
        [Settings]
        maxthumbs=14    
        work_border=4     
        dock_border=0     
        repainttimer=1000 
        forcetitlerepaint=1
        forcedocktofront=0
        forcedocktransparent=0
        insidetaskbar=0   
        insidetaskbar_x0=70 
        insidetaskbar_y0=30  
        insidetaskbar_xf=200 
        insidetaskbar_yf=200  
    )
    FileAppend,%ini%,%appName%.ini
    ini=
  }


  IniRead,forcedocktofront ,%appName%.ini,Settings,forcedocktofront
  IniRead,forcedocktransparent ,%appName%.ini,Settings,forcedocktransparent
  IniRead,forcetitlerepaint ,%appName%.ini,Settings,forcetitlerepaint
  IniRead,maxthumbs           ,%appName%.ini,Settings,maxthumbs
  IniRead,work_border         ,%appName%.ini,Settings,work_border
  IniRead,dock_border         ,%appName%.ini,Settings,dock_border
  IniRead,repainttimer        ,%appName%.ini,Settings,repainttimer
  IniRead,insidetaskbar       ,%appName%.ini,Settings,insidetaskbar
  IniRead,insidetaskbar_x0    ,%appName%.ini,Settings,insidetaskbar_x0
  IniRead,insidetaskbar_y0    ,%appName%.ini,Settings,insidetaskbar_y0
  IniRead,insidetaskbar_xf    ,%appName%.ini,Settings,insidetaskbar_xf
  IniRead,insidetaskbar_yf    ,%appName%.ini,Settings,insidetaskbar_yf

Return

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
GuiClose:
EXIT:
    ExitApp



BoBo
  • Guests
  • Last active:
  • Joined: --
Beeindruckend ! Thanks for sharing it :D

Posted Image
"Warum in die Ferne schweifen
- wenn das Gute liegt so nah


Laughing Man
  • Members
  • 84 posts
  • Last active: Oct 25 2007 04:43 AM
  • Joined: 28 Apr 2005
Hmm downloaded it, unrared it. Doubleclicked to run it. Didn't see any screenshots of windows. Pressing F9 and F10 moved windows around but that was about it.

My resolution is one tick above the 1024x768 one. Had Opera and an Explorer window open. Could be that it was because of ObjeckDock running? But I closed it, my taskbar is on top though.
"I thought what I'd do was I'd pretend I was one of those deaf-mutes" ~ Laughing Man - GITS:SAC

holomind
  • Members
  • 341 posts
  • Last active: Aug 23 2015 03:27 PM
  • Joined: 11 Mar 2006

Hmm downloaded it, unrared it. Doubleclicked to run it. Didn't see any screenshots of windows. Pressing F9 and F10 moved windows around but that was about it.

My resolution is one tick above the 1024x768 one. Had Opera and an Explorer window open. Could be that it was because of ObjeckDock running? But I closed it, my taskbar is on top though.


when you have 1024x768 you dont see nothing ;) as the toolbar is on the right side of the screen with a fixed offset of about 1200px so its in your "invisible" area.

i didnt see the need yet to use it with "lower" resolution. for a quick try you can try to change the coordinates which are between 1000 and 1200 and make them 800-1000 so you can see the toolbar.
i will make a next version with screenautodetect and better to customize sizes. but in the moment it works "very" good for me so my motivation to change it is not so high. (when i dont like to change it, this tells me it works ;)

do you have a chance to increase your resolution to 1400 or 1600 ? just to see the effect. also it only makes sense on a large screen with high resolution as this takes away to much space on a 1024 which would leave you with a "workspace" of only 800 width, and you have trouble with some websites. (on the other hand, perhaps one can live with 800=window + 200=deskman)

its nice to hear actually somebody tried it ;)

holomind
  • Members
  • 341 posts
  • Last active: Aug 23 2015 03:27 PM
  • Joined: 11 Mar 2006

Hmm downloaded it, unrared it. Doubleclicked to run it. Didn't see any screenshots of windows. Pressing F9 and F10 moved windows around but that was about it.


i made some bugfixes and uploaded a new version, this now automatically detects the screenresolution, but asumes you have the taskbar on the right, you can tweak the positioning with the variables on the beginning of the script.
i changed the source in the first post and also the linked zip/install (with the 3 needed files).

i also added a new hotkey win-1 and win-2 and win-3 which lets you resize the windows to upper-half , lower-half and full but always leaving space for deskman.

have fun
daniel

holomind
  • Members
  • 341 posts
  • Last active: Aug 23 2015 03:27 PM
  • Joined: 11 Mar 2006
I just updated the version again, see the zip in the first post.

it now contains an alternate version deskman_1024.ahk, which is optimized for 1024 (or smaller) with taskbar on bottom, also the window-thumbnails will be on bottom.

on a small screen (1024 or 800) i prefer taskbar on bottom as i then can use the full 800 or 1024 in width which most pages are optimized for.

on bigger screens i prefer taskbar on right as then the ratio for webpages is better. 1000x1000 makes more sense with documents and webpages compared to 1400x700 ;)

the thumbnailsize automatically resizes due to the given "maxthumbs" so if you have 5 maxthumbs they are much bigger than 14 max-thumbs (which will result in 100px on a 1400 screen)

i also introduced a repaint function which checks if the Progman (tasks) have changed (eg. if you closed a window) and when a change is detected the dock is repainted.

next todos or features planned:
* make some use of the tray-icon and put the configurations in there and make then changeable
* extend the help and show the used hotkeys.
* perhaps even allow a remap of hotkeys inside of trayicon or use another GUI for customizing (like topdesk for exampe).
* try and experiment with making dock resizable like in the original multimonitor from scrommel (which i deactivated) so it would behave more like a objectdock or rocketdock bar. but in the moment its ok for me to use the full widht or height and define the size by max numbers of thumbs.
* would it make sense to include app-starter or tray-icons into dock ? but i dont use this feature (i have purchased the full version of object-dock, so o have no need not to use it , but even object-dock has its limitations ;)
* perhaps have hover-tooltips for the pictures so i can display the window title similar to the original taskbar.
* would it make sense to have the window-icon on the thumbs ? i guess miniMIZE gives the option to show them.

i already tried with compile script which gives a nice "one-file" exe, which even includes the pixel and i_view32.exe file (results in a 600kb file) this way i could make a free or share or donation-ware out of it and people dont need autohotkey to run it. but i guess i prefer opensource and donationware for people who want to support it.

by changing and bugfixing i am learning more about the details of autohotkey and i am still amazed, what i was able to do with this in some days, i could *never* have done this with visual-studio in this time and so easy. also the big thing in the 600kb file is the 400k of i_view ;)

AHK is fun ;)

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
Looks nice. I made a tiny change to the script to prevent horizontal scrolling in the forum (which might make it easier for people to read this topic). I divided the "if class in..." line into two lines by starting the second line with a comma.

toralf
  • Moderators
  • 4035 posts
  • Last active: Aug 20 2014 04:23 PM
  • Joined: 31 Jan 2005
Pic1:   ; event-handler for image-click (is there a better way ?) 

Yes, there is. You can combine all of these subroutines to a single one. To get the pos, you can use
StringReplace, pos , A_GuiControl, Pic

Ciao
toralf
 
I use the latest AHK version (1.1.15+)
Please ask questions in forum on ahkscript.org. Why?
For online reference please use these Docs.

PhiLho
  • Moderators
  • 6850 posts
  • Last active: Jan 02 2012 10:09 PM
  • Joined: 27 Dec 2005

also the big thing in the 600kb file is the 400k of i_view ;)

AHK is fun ;)

I agree with the last sentence...

I don't see why you are packaging a freeware which can be downloaded easily on the Net. Just point to the site of IrfanView and let the users get the whole package, which is interesting to have anyway.
Posted Image vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")

evl
  • Members
  • 1237 posts
  • Last active: Oct 20 2010 11:41 AM
  • Joined: 24 Aug 2005
... or better yet, have one version with and one version without the i_view component - it can be inconvenient for users to install a whole other package just for one little file. Also it's sensible to package together required components in case they are hard to acquire in the future (or compatability is broken).

holomind
  • Members
  • 341 posts
  • Last active: Aug 23 2015 03:27 PM
  • Joined: 11 Mar 2006

AHK is fun ;)

I agree with the last sentence...


you bet ;) also the forum gives so much examples and i now learn windows / gui programming the easy way. never liked the c++ syntax for handling windows ...

I don't see why you are packaging a freeware ...


oh, i have no problem giving away the ahk-file. the only reason is to give users a "very" easy way to "try" the tool.
1) download exe
2) double-click.

you are running ;) pointing to irfanview-website is not bad, but i bet some wont give it a try if they have to do some extras. if i use topdesk or other apps i also dont download funny dlls, but have one package.

actually i only use a very small or specific function of iview, so perhaps this could be done with an dll-call which is in windows already ? i dont care as it works for now

holomind
  • Members
  • 341 posts
  • Last active: Aug 23 2015 03:27 PM
  • Joined: 11 Mar 2006
I just updated the source-code and the attached zip, with some little bugfixes.

autorefresh to detect closing windows now works good.
the finding of new windows is not optimal yet. but you can refresh all windows with F10 ( i put it on a special button of my mouse) .

i added some new hotkeys: for resizing:
win-1 upper-half
win-2 lower-half
win-3 full (without dock)
win-4 left-half
win-5 right-half

this is very efficient if you need to copy files with two windows (eg. explorer) and dont have to fiddle arround with positioning.

perhaps i change them to be win-left, win-up, win-down, win-right, win-enter ? so they react more intuitive compared to 12345.
(have to loop in the manual what win-left is as a key #left:: ? )

i will include the optimisation of toralf and make it look better ?

has somebody tried it ? does it work, or did you delete it quickly ?

Any suggestions for new version ?

crosslinks => could be used by alt-tab replace in this forum to have thumbnails at tasks instead of only icons ? (but taskswitchXP does this already, but not in AHK ;) )

holomind
  • Members
  • 341 posts
  • Last active: Aug 23 2015 03:27 PM
  • Joined: 11 Mar 2006

... or better yet, have one version with and one version without the i_view component - it can be inconvenient for users to install a whole other package just for one little file. Also it's sensible to package together required components in case they are hard to acquire in the future (or compatability is broken).


i would handle this with having the compiled version including the iview.exe, and giving the ahk source with it. and point to the irfanview website in the source code , you even could make the source file itself an install file for ahk-compile so after running the file.exe once you have the current source-code in the directory. ...

holomind
  • Members
  • 341 posts
  • Last active: Aug 23 2015 03:27 PM
  • Joined: 11 Mar 2006

Pic1:   ; event-handler for image-click (is there a better way ?) 
Yes, there is. You can combine all of these subroutines to a single one. To get the pos, you can use
StringReplace, pos , A_GuiControl, Pic


I only understand half of your tipp, ok, in my restore function i can get the position with A_GuiControl. but Pic1: also triggers the function. as i learned calling a pic gPic%something% it automatically calls the function.

where do i have to look in the manual to apply your tipp .
or do you only think a should move the
"pos=3" into the subroutine, which would still leave me 20 Pic1: Pic2: etc. markers for Gosub.

perhaps i have to try WM_MOUSECLICK (message etc. ) and then test if A_GuiControl is similar to my Pic-Name ;)

this way i also could add some tooltips when you hover over it.

toralf
  • Moderators
  • 4035 posts
  • Last active: Aug 20 2014 04:23 PM
  • Joined: 31 Jan 2005
All your Picture controls have a g-label and a v-label.
Gui, Add, Pic, gPic%a_index% x0 y%y%   vPic%a_index%         ; add dock-slots to gui 
If you would now remove the A_index from the g-label. All clicks on any picture would go to a single subroutine "Pic".

This pic subroutine would look like this:
Pic: 
   StringReplace, pos , A_GuiControl, Pic
   Gosub, restore 
return 
Maybe you can even put the restore as a g-label into the Gui Control. And place the StringReplace inside the replace.
Ciao
toralf
 
I use the latest AHK version (1.1.15+)
Please ask questions in forum on ahkscript.org. Why?
For online reference please use these Docs.