-
Notifications
You must be signed in to change notification settings - Fork 0
/
AlexTaskbar.ahk
460 lines (359 loc) · 9.91 KB
/
AlexTaskbar.ahk
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
#NoEnv
#SingleInstance force
#Persistent
; AlexTaskbar v1.0.2
; https://github.com/LatinSuD/AlexTaskbar/
; Set the width of the taskbar
TaskbarWidth := 200
; Whether to use clock
useClock=1
; calendar application (when double click on clock)
calendarApp = outlookcal:
; show delay (in 100ms ticks)
showDelay := 1
; TODO: Seccion known bugs (iconos de "Fotos" no sale, icono de apps de otros no salen, salen apps que no deberian salir)
; TODO: restaurar ventanas con sendmessage (winrestore no siempre funcioan)
; TODO: Arreglar URL Github
; TODO: coger icono del EXE si no se puede de la app
; TODO: Drag Drop en tiempo real as opposed to ahora que no es intuitivo
; TODO: Prevent listing of hidden apps like "program manager"
; TODO: Delay when opening
; TODO: right click: open real menu (shift modifies?), close, max/minimize, insert separator, delete separator, change title, change icon
; TODO: function to search open apps using keyboard
; TODO: click active window to minimize
; TODO: settings (right click en una zona vacia?)
; TODO: store preferences in file or reg
; TODO: save window order by id or title accross relaunch/reboot!
; TODO: Hint/tooltip. When mouse over slot show full title
DictImg := [] ; icons of windows
DictTitles := [] ; titles of windows
DictLastSeen := [] ; to keep track of terminated windows
showDelayCounter := 0
if ( useClock )
clockPosition := A_ScreenHeight - 20
else
clockPosition := A_ScreenHeight
; Create the GUI for the taskbar
Gui +LastFound +OwnDialogs -Border +AlwaysOnTop +ToolWindow
; handle to our own window
myHWND := WinExist()
; remove ourselves from task list
WinSet, ExStyle, +0x80
Gui Color, 000000
Gui Font, s14 cWhite
; create Listview
Gui Add, ListView, x-5 y-5 h%clockPosition% vMyListView gMyClick -Hdr AltSubmit, Icon|Window Title|ImageIndex|windowId
LV_ModifyCol(1,20)
LV_ModifyCol(2,TaskbarWidth)
LV_ModifyCol(3,0)
LV_ModifyCol(4,0)
Gui +LastFound
;WinSet, TransColor, FFFFFF
GuiControl, +Backgroundblack, MyListView
; where we are shown or hidden
showState=0
; Set the size and position of the taskbar
;WinSet, Region, 0-0 %TaskbarWidth%-%TaskbarHeight%, A
;WinMove, A, , 0, %A_ScreenHeight% - %TaskbarHeight%, %TaskbarWidth%, %TaskbarHeight%
; Timer to control mouse, auto-hide, clock
SetTimer, PeriodicTimer, 100
; Create an ImageList to hold 10 small icons initially
ImageListID := IL_Create(10)
LV_SetImageList(ImageListID)
; Hide the original taskbar (not recommended)
;WinHide, ahk_class Shell_TrayWnd
CoordMode,Mouse,Screen
;; CLOCK
if ( useClock ) {
; Size 9, no antialising
Gui, Font, cFFffff s9 q3, Arial
;
Gui, Add, Text, vclockTime x1 y%clockPosition% BackgroundTrans gClockClick, %A_YYYY%-%A_MM%-%A_DD% %a_hour%:%a_min%:%a_sec%.
; Size 9, no antialising, bold
Gui, Font, cFFffff s9 q3 w800, Arial
Gui, Add, Text, vclockMinutes x68 y%clockPosition% BackgroundTrans gClockClick,%a_hour%:%a_min%
}
return
;;;;;; END OF MAIN
;;;;;;;;;;;;;;;;;;;;;;;
; Function to update the taskbar list
UpdateTaskbar:
{
stamp := A_TickCount
WinGet, idList, List
Loop % idList
{
id := idList%A_Index%
;OutputDebug, id %id%
; skip ourselves
if ( id == myHWND ) {
Continue
}
WinGet, wStyle, ExStyle, ahk_id %id%
If (wStyle & 0x80) {
; Ignore "tool" windows
Continue
}
if (ObjRawGet(DictLastSeen, id) == "")
isNewWindow=1
else
isNewWindow=0
WinGetTitle, title, ahk_id %id%
;WinGet, processName, ProcessName, ahk_id %id%
if ( title == "" ) {
Continue
} else {
oldTitle := ObjRawGet(DictTitles, id)
if (oldTitle != "" && oldTitle != title) {
; Update window title if changed
Loop % LV_GetCount() {
LV_GetText(aId, A_Index, 4)
;OutputDebug, %id% %aId%
if (id == aId) {
;OutputDebug, AJA
LV_Modify(A_Index, "Col2", title)
}
}
}
ObjRawSet(DictTitles, id, title)
ObjRawSet(DictLastSeen, id, stamp)
}
;LV_Modify(0, "-Select")
if ( id == activa ) {
Loop % LV_GetCount() {
LV_GetText(aId, A_Index, 4)
if ( id == aId ) {
;OutputDebug, Seleccionando %id%
LV_Modify(A_Index, "Select")
} else {
LV_Modify(A_Index, "-Select")
}
}
}
; process icon
IconHwnd := getIconFromWindow(id)
;OutputDebug, %IconHwnd%
if (ObjRawGet(DictImg, IconHwnd) == "") {
; Unseen icon
res := IL_Add(ImageListID, "HICON:" . IconHwnd)
if (res == 0) {
res := IL_Add(ImageListID, "shell32.dll", 1)
}
ObjRawSet(DictImg, IconHwnd, res)
IndiceImg := res
; Update icon in ListView
Loop % LV_GetCount() {
LV_GetText(aId, A_Index, 4)
if ( id == aId ) {
;OutputDebug, Seleccionando %id%
LV_Modify(A_Index, "Icon" . IndiceImg, , , IndiceImg)
}
}
} else {
; Icon already in list
IndiceImg := ObjRawGet(DictImg, IconHwnd)
}
; add new window
if (isNewWindow) {
if ( id == activa ) {
; highlight active window
LV_Add("Icon" . IndiceImg . " Select", , title, IndiceImg, id)
} else {
LV_Add("Icon" . IndiceImg, , title, IndiceImg, id)
}
}
}
; Remove windows that were deleted
For id, oldStamp in DictLastSeen {
if ( 0+oldStamp != 0+stamp ) {
DictLastSeen.Delete(id)
Loop % LV_GetCount() {
;OutputDebug,aid %aId%
LV_GetText(aId, A_Index, 4)
if (id == aId) {
;OutputDebug, Elminio fila LV %id%
LV_Delete(A_Index)
}
}
}
}
Gui,Show, x-4 w200 y-3 h%A_ScreenHeight% NoActivate, AlexTaskbar
showState=1
return
}
; update clock text
updateClock:
{
; only update once per second
if ( lastClockUpdate == A_NowUTC )
return
lastClockUpdate := A_NowUTC
timeText = %A_YYYY%-%A_MM%-%A_DD% :%a_sec%
minuteText = %a_hour%:%a_min%
GuiControl, , clockMinutes,%minuteText%
GuiControl, , clockTime, %timeText%
return
}
; Mouse left click handler
MyClick:
{
rowClick := A_EventInfo
OutputDebug, rowClick %rowClick% EVENTINFO %A_EventInfo% GUIEVENT: %A_GuiEvent%
if ( A_GuiEvent == "RightClick" ) {
;MsgBox,SI
;lastClickItem:=A_EventInfo
Menu, rightMenu, Add, Close, MyRightClick
Menu, rightMenu, Show
GoSub,UpdateTaskbar
return
}
; If starting Drag&Drop
If (A_GuiEvent == "D")
{
dragging := True
OutputDebug, START DRAG
MouseGetPos,,yDrag
CutItem := A_EventInfo
Loop, % LV_GetCount("Col") {
LV_GetText(HoldText%A_Index%, CutItem, A_Index)
}
HotKey, LButton UP, DragDropEnd, On
return
}
; If normal click
if ( A_GuiEvent == "Normal" ) {
; If ending Drag&Drop
If (WaitClick)
{
OutputDebug, END DROP. Columnas %HoldText1% , 3 %HoldText3%, %HoldText2%
WaitClick := False
LV_Delete(CutItem)
LV_Insert(A_EventInfo, "Icon" . HoldText3, , HoldText2, HoldText3, HoldText4 )
GoSub, UpdateTaskbar
} Else {
; Really normal click
if ( rowClick != 0 ) {
LV_GetText(clickWID, rowClick, 4)
; activate or minimize clicked window
if ( clickWID == activa ) {
WinMinimize,ahk_id %clickWID%
} else {
WinActivate,ahk_id %clickWID%
}
}
}
return
}
return
}
; right click handler
MyRightClick:
{
OutputDebug, %A_ThisMenuItem% on %rowClick%
if ( A_ThisMenuItem == "Close" && rowClick != 0 ) {
LV_GetText(clickWID, rowClick, 4)
WinClose,ahk_id %clickWID%
}
return
}
; double click on clock
ClockClick:
{
If (A_GuiEvent == "DoubleClick") {
; open calendar
Run,%calendarApp%
}
return
}
; end of drag and drop sequence
DragDropEnd:
dragging := False
ReplaceSystemCursor()
HotKey, LButton UP, DragDropEnd, Off
MouseGetPos,,, WinID, ConID
OutputDebug, DRAGDROP_END, %myHWND% vs %WinID%
If (WinID = myHWND )
{
;OutputDebug, CUMPLE
WaitClick := True
Send, {Click}
}
Return
; periodic timer
PeriodicTimer:
MouseGetPos x, y
candidateActiva := WinExist("A")
if (candidateActiva != myHWND)
activa := candidateActiva
; if have to show
if ( x < 2 && showState==0 ) {
if ( showDelayCounter > showDelay ) {
GoSub,UpdateTaskbar
} else {
showDelayCounter := showDelayCounter + 1
}
} else {
; if have to hide
if ( x >= TaskbarWidth && showState == 1 ) {
showState=0
showDelayCounter=0
OutputDebug,HIDE
Gui, Hide
}
}
if ( showState == 1 ) {
; if we are drag&dropping
if ( dragging ) {
OutputDebug, showState = %showState%
if ( y < yDrag )
ReplaceSystemCursor("IDC_ARROW", "IDC_UPARROW")
else
ReplaceSystemCursor("IDC_ARROW", "IDC_SIZEALL")
}
; update clock
GoSub,updateClock
}
return
; To replace cursor while drag&dropping
; original source: https://www.autohotkey.com/boards/viewtopic.php?p=496913#p496913
ReplaceSystemCursor(old := "", new := "")
{
static IMAGE_CURSOR := 2, SPI_SETCURSORS := 0x57
, exitFunc := Func("ReplaceSystemCursor").Bind("", "")
, setOnExit := false
, SysCursors := { IDC_ARROW : 32512
, IDC_UPARROW : 32516
, IDC_SIZEALL : 32646 }
if !old {
DllCall("SystemParametersInfo", "UInt", SPI_SETCURSORS, "UInt", 0, "UInt", 0, "UInt", 0)
OnExit(exitFunc, 0), setOnExit := false
}
else {
hCursor := DllCall("LoadCursor", "Ptr", 0, "UInt", SysCursors[new], "Ptr")
hCopy := DllCall("CopyImage", "Ptr", hCursor, "UInt", IMAGE_CURSOR, "Int", 0, "Int", 0, "UInt", 0, "Ptr")
DllCall("SetSystemCursor", "Ptr", hCopy, "UInt", SysCursors[old])
if !setOnExit
OnExit(exitFunc), setOnExit := true
}
}
; extract the icon from an active window
; original source: https://www.reddit.com/r/AutoHotkey/comments/ejm86o/comment/fcz4xsq/?utm_source=reddit&utm_medium=web2x&context=3
getIconFromWindow(windowDef) {
WM_GETICON := 0x007F
ICON_SMALL := 0
ICON_BIG := 1
GCLP_HICON := -14
GCLP_HICONSM := -34
MyHwnd := windowDef
SendMessage, WM_GETICON, ICON_SMALL, 96, , ahk_id %MyHwnd%
if (ErrorLevel != "FAIL")
{
IconHwnd := ErrorLevel
}
if (IconHwnd = 0)
{
IconHwnd := DllCall("GetClassLongPtr", "Ptr", MyHwnd, "Int", GCLP_HICON)
}
;MsgBox, %IconHwnd%
return IconHwnd
}