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
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
| local Info = package.loaded.regscript or function(...) return ... end
local nfo = Info {_filename or ...,
name = "RecentScreens";
--переключение между окнами как в MS Windows™
description = "switch screens in MRU-order";
version = "3.11.1"; --http://semver.org/lang/ru/
author = "jd";
url = "http://forum.farmanager.com/viewtopic.php?f=60&t=7876";
id = "789DF383-23EE-4CF2-B274-7F3D387AEB98";
minfarversion = {3,0,0,5547,0}; --DN_LISTCHANGE
options = {
macroKey = "Tab", -- Ctrl-Tab / CtrlShift-Tab
--macroKey = "`", -- Ctrl-~ / CtrlShift~
--macroKey = "CapsLock", -- Ctrl-CapsLock / CtrlShift-CapsLock
-- default settings:
listDelay = 200, -- * delay before RecentScreens list show
-- 0 means no delay
-- <no list> means no list
listInstant = true, -- * in list:
-- true - switch screen on every Ctrl+Tab
-- false - switch only after Ctrl release
-- other options
fixAltDigitMacro = true,
hideDesktop = true,
debug = true,
};
help = function(self) far.Message(self.helpstr,self.name.." v"..self.version,nil,"kl") end;
helpstr = [[
Параметры, управляющие переключением,
можно изменить с помощью горячих клавиш
на цифровой клавиатуре:
[/] Instant - определяет момент переключения
- true - сразу, при каждом нажатии Ctrl+Tab
- false - после отпускания Ctrl
[*] Delay - задержка появления списка экранов
Плавно изменить: [+/-]
/* при <no list> список будет доступен по Ctrl+F12 */]];
--todo full help
--CtrlBS
--CtrlBackSlash
--Ctrl=
--CtrlEnter
--Enter/Esc/Break
--CtrlF8
--disabled = false;
}
if not nfo or nfo.disabled then return end
local O = nfo.options
local F = far.Flags
------------------------------------------------
--Settings
local _KEY,_NAME = "JD",nfo.name
local S -- current settings
local function defaultSettings()
return {
listDelay = O.listDelay,
listInstant = O.listInstant,
}
end
local function resetSettings()
if far.Message("\nDelete saved settings?\n",nfo.name,";OkCancel") then
mf.mdelete(_KEY,_NAME)
S = defaultSettings()
end
end
Event { description="[RecentScreens] Save settings (on exit)";
id="3B6F9E40-C470-4194-9DD3-4A76206ED8C8";
group="ExitFAR";
action=function() mf.msave(_KEY,_NAME,S) end;
}
S = mf.mload(_KEY,_NAME) --initial settings load
if not S or type(S)~="table" or type(S.listDelay)~="number" then
S = defaultSettings()
end
-------------------------------------------------------------
--- some general definitions
local function aKey() return mf.akey(1,1) end
local function Warning(msg)
far.Message(msg,"Warning","","w"); far.Text(); win.Sleep(500)
end
local Lock = {Num=0, Caps=1, Scroll=2}
local modeIsOn,keyIsPressed = 1,0xff80
local function LockState(xLock,Action) --set State: 0|1|2=toggle
--get State: nil|-1
local Lkey = assert(Lock[xLock])
local State = mf.flock(Lkey,-1)
local mode, hold = band(State,modeIsOn)==modeIsOn,
band(State,keyIsPressed)==keyIsPressed
if Action==2 or Action~=-1 and (mode==(Action==0)) then
if hold then mf.flock(Lkey,Action) end --http://forum.farmanager.com/viewtopic.php?p=139236#p139236
mf.flock(Lkey,Action)
end
return mode,hold
end
local _mod
-- can be rewrited using win.ExtractKeyEx and DN_INPUT (+DM_SETINPUTNOTIFY)
-- EventType==KEY_EVENT / Param2.ControlKeyState
local mod_mask = bor(F.RIGHT_CTRL_PRESSED,F.LEFT_CTRL_PRESSED)
local function ModReleased(set)
if set then
_mod = band(mod_mask,Mouse.LastCtrlState) -- state updates only after mf.waitkey / or in dialog event loop
elseif set==false then
_mod = false
else
return _mod and band(mod_mask,Mouse.LastCtrlState,_mod)~=_mod
end
end
local actl, GetWindowCount, GetWindowInfo, SetCurrentWindow
= far.AdvControl,F.ACTL_GETWINDOWCOUNT,F.ACTL_GETWINDOWINFO,F.ACTL_SETCURRENTWINDOW
local En = {
[F.WTYPE_PANELS]="Panels",[F.WTYPE_VIEWER]="View",[F.WTYPE_EDITOR]="Edit",
[F.WTYPE_DIALOG]="Dialog",[F.WTYPE_DESKTOP]=not O.hideDesktop and "Desktop",
}
local function Uid(w) --skip unsupported screen types
return En[w.Type]
and (w.Type~=F.WTYPE_DIALOG or band(w.Flags,F.WIF_MODAL)==0) --no modal dialogs
and En[w.Type]..tostring(w.Id)
end
--------------------------------------------------------
local Screens = { --array of windows' uid's in MRU order
--[1]="Desktop0",
--[2]="Panels0",
--[3]="Edit5",
uids = {
--["Desktop0"]=true,
--["Panels0"]=true,
--["Edit5"]=true,
},
--stateFreezeOrder=false,
}
function Screens:exist(uid)
return self.uids[uid]
end
function Screens:add(uid)
table.insert(self,uid)
self.uids[uid] = true
end
function Screens:Remove(uid,nonstrict)
if self:exist(uid) then
for i=1,#self do
if self[i]==uid then
table.remove(self,i)
self.uids[uid] = nil
return i
end
end
elseif nonstrict then --or self.stateFreezeOrder
return
end
if O.debug then Warning("uid do not exist: "..tostring(uid)) end
end
function Screens:Delta(d) return self[#self-d] end
function Screens:Focus(uid) -- move to top
if O.debug then
--win.OutputDebugString(table.concat(Screens,"|").."=>"..uid)
end
if self[#self]~=uid then
self:Remove(uid,"if any")
self:add(uid)
return true
end
end
function Screens.it_windows() --iterate over all screens / ret: i,uid,w
return function(n,i)
while(i<n) do
i = i+1
local w = actl(GetWindowInfo,i)
local uid = Uid(w)
if uid then return i,uid,w end
end
end,actl(GetWindowCount),0
end
function Screens:Goto(_uid) -- switch screen
for _,uid,w in self:it_windows() do
if uid==_uid then
if band(w.Flags,F.WIF_CURRENT)==0 then
actl(SetCurrentWindow,w.Pos)
end
return true
end
end
--
if O.debug then Warning("cannot find window "..tostring(_uid)) end
self:Remove(_uid)
end
--[[
function:Screens:Commit()
--for i=1,#self do self:Goto(self[i]) end
local windows = {}; for _,uid,w in self:it_windows() do windows[uid] = w end -- helper table (windows by uid)
local pos,n = {},#self; for i=1,n do pos[i] = windows[Screens[i] ].Pos end
for i=1,n do
local Pos = pos[i]
actl(SetCurrentWindow,Pos)
for j=i+1,n do
if pos[j]>Pos then pos[j] = pos[j]-1
end
end
end
--]]
-- limitations: https://forum.farmanager.com/viewtopic.php?p=123663#p123663
-- CtrlTab usually is served by Conemu itself
-- so we are unable to properly handle Panels/Desktop screens
-- thus MRU order will be incorrect
-- nevertheless, someone still wants it in conemu:
-- https://forum.farmanager.com/viewtopic.php?p=124349#p124349
-- so let them
-- but it's still better to disable some functions (MRUswithOnClose).. --todo
--[[
local function Conemu(param)
return Plugin.SyncCall("4B675D80-1D4A-4EA9-8436-FDC23F2FC14B",param)
end
--if win.GetEnv"ConEmuDir"
--if Conemu("IsConEmu")
--and O.macroKey=="Tab"
--!!check attach/detach
if akey():sub(-3)=="Tab" and Conemu("GetOption TabSelf")~="0" then
--
end
--]]
for _,uid in Screens:it_windows() do Screens:add(uid) end -- init Screens
---------------------------------------------------------------
-- Helper event-handlers
Event{ description="[RecentScreens] editor handler"; group="EditorEvent";
id="39C42CCD-E4E1-4165-AAAF-FD81D9C54E37";
action=function(id,Event)
if Event==F.EE_CLOSE then
local uid = "Edit"..id
Screens:Remove(uid)
elseif Event==F.EE_GOTFOCUS and not Screens.stateFreezeOrder then
local uid = "Edit"..id
Screens:Focus(uid)
end
end;
}
Event{ description="[RecentScreens] viewer handler"; group="ViewerEvent";
id="267160C4-7C26-4883-A126-D4EB081C254D";
action=function(id,Event)
if Event==F.VE_CLOSE then
local uid = "View"..id
Screens:Remove(uid,"skip QView,Info")
elseif Event==F.VE_GOTFOCUS and not Screens.stateFreezeOrder then
local uid = "View"..id
Screens:Focus(uid)
end
end;
}
Event{ description="[RecentScreens] dialog handler"; group="DialogEvent";
id="2FE435A8-52B6-47F6-8823-9F4D064B1DBA";
action=function(Event,param)
if Event~=F.DE_DLGPROCEND then return end
local Msg,hDlg,Param1 = param.Msg,param.hDlg,param.Param1
if Msg==F.DN_CLOSE then
local uid = "Dialog"..tostring(hDlg)
Screens:Remove(uid,"skip modals")
elseif Msg==F.DN_GOTFOCUS and Param1==-1 --nonmodals only
and not Screens.stateFreezeOrder then
local uid = "Dialog"..tostring(hDlg)
Screens:Focus(uid)
end
end;
}
-----------------------------------------------------------
-- RecentScreens menu logic helpers (see showRecentScreens)
local RSid = "92B73618-3C29-401C-BE62-B0406513CB82" -- RecentScreens menu id
local function isRecentScreensMenu() return Menu.Id==RSid end; --DM_GETDIALOGINFO
local STEP = 50 --ms
local NOLIST = -STEP
local function needSwitch() return S.listInstant or S.listDelay==NOLIST end
--!!2do reimplement menu via dialog
Event{ description="[RecentScreens] internal handler"; group="DialogEvent";
id="15FF5001-632B-4FB8-8A62-A0F629791369";
condition=function(Event) return Event==F.DE_DLGPROCINIT end;
action=function(_,Param)
local Msg,hDlg,Param2 = Param.Msg,Param.hDlg,Param.Param2
if Msg==F.DN_INPUT then -- close on mod release
if Param2.KeyDown==false and isRecentScreensMenu() and ModReleased() then
--hDlg:send(F.DM_KEY,nil,"Enter")
hDlg:send(F.DM_CLOSE)
end
elseif Msg==F.DN_LISTCHANGE then -- auto-switching
if needSwitch() and isRecentScreensMenu() then
mf.postmacro(Keys,"CtrlEnter") -- send BreakKey /close, switch window, and reopen/
end
end
end;
}
------------------------------------------------
-- RecentScreens-menu macros
Macro { description="[RecentScreens] Prev/Next";
area="Menu"; key="/^[LR]Ctrl(Shift)?(CapsLock|Tab|`)$/";
id="650C5D50-2750-4814-A12A-E7E749F4E322";
condition=isRecentScreensMenu;
action=function()
Keys(aKey():find"Shift" and "Up" or "Down")
end;
}
local NavKeys = "Up|Down|PgUp|PgDn|Num9|Num3|Home|End|Num7|Num1"
Macro { description="[RecentScreens] Prev/Next (additional)";
area="Menu"; key="/^[LR]Ctrl("..NavKeys..")|"..NavKeys.."$/";
id="F7ABABFA-A70D-4A26-A725-632040747F0A";
condition=isRecentScreensMenu;
action=function()
Keys(aKey():match"^R?Ctrl(.+)$" or "AKey")
end;
}
Macro { description="[RecentScreens] Scroll long titles";
area="Menu"; key="CtrlRight CtrlLeft";
id="BCD83367-88D6-4CAF-BF33-C2FF176D09AB";
condition=isRecentScreensMenu;
action=function() Keys("Alt"..aKey():match"Ctrl(.+)") end;
}
Macro { description="[RecentScreens] Goto [0-9A-Z]";
area="Menu"; key="/^[RL]Ctrl\\w$/";
id="A1428D9E-C5A0-46A8-8A1B-F5B0A2407FE1";
condition=isRecentScreensMenu;
action=function() Keys(aKey():sub(-1)) end;
}
-------------------------------------------
-- RecentScreens menu itself
local function getPanelInfo(name,typename)
local p = panel.GetPanelInfo(nil,1)
local ptype = p.PanelType
if ptype==F.PTYPE_FILEPANEL then
--https://forum.farmanager.com/viewtopic.php?f=8&t=11290
--unfortunately there is no strict order in plugins different plugins' info
--so to construct panel title we have to use heavy smart-ass euristics here(
name = name:match".*\\"
if band(p.Flags,F.PFLAGS_PLUGIN)~=0 then
--??2do: name from plugin panel
--??todo APanel.UNCPath
--??Object.Title
typename = "[plugin]"
local prefix = panel.GetPanelPrefix(nil,1) or ""
if prefix:len()>0 then
prefix = prefix:match"[^:]*"..":"
typename = prefix
end
local host = panel.GetPanelHostFile(nil,1) or ""
if host:len()>0 then
--??2do: truncate long host path, add plugin path
name = host
else
local format = panel.GetPanelFormat(nil,1) or ""
if format:len()>0 then
name = format.." - "..name
end
end
end
else
typename = ptype==F.PTYPE_INFOPANEL and "Info"
or ptype==F.PTYPE_QVIEWPANEL and "QView"
or ptype==F.PTYPE_TREEPANEL and "Tree"
--todo QView
name = APanel.Path --https://bugs.farmanager.com/view.php?id=3639
end
return name,typename,band(p.Flags,F.PFLAGS_VISIBLE)==0 and "-"
or band(p.Flags,F.PFLAGS_PANELLEFT)~=0 and "<" or ">"
end
local function prepItem(w,i,modal)
local name,typename = w.Name,w.TypeName
local current = band(w.Flags,F.WIF_CURRENT)~=0
local mark,checked,key
-- =≡■
if w.Type==F.WTYPE_PANELS then
checked,key = "≡","BackSlash"
name,typename,mark = getPanelInfo(name,typename)
elseif w.Type==F.WTYPE_DESKTOP then
checked = ""
elseif w.Type==F.WTYPE_EDITOR then
mark = band(w.Flags,F.WIF_MODIFIED)~=0 and "*"
local title = editor.GetTitle(w.Id) --Показывать заголовки редакторов в меню Screens вместо путей
if title~=name then name = title.." - "..name end --https://bugs.farmanager.com/view.php?id=3316
end
--local hk = w.Pos-1 --"Pos" used to be same as Screens #hotkey
-- not anymore http://forum.farmanager.com/viewtopic.php?f=54&t=8883&p=125016#p125016
local hk = i
hk = hk<=9 and hk or hk<=35 and string.char(("A"):byte()+hk-10)
hk = hk and "&"..hk.."." or ""
return {
text = ("%2s %-8s %1s %s"):format(hk,typename,mark or "",name),
checked=band(w.Flags,F.WIF_MODAL)~=0 and "!" or checked,
disable=modal and not current,
selected=current,
AccelKey=key, --https://bugs.farmanager.com/view.php?id=3471
}
end
local BreakKeys = {
{BreakKey="CtrlEnter"}, --no action, need for menu close/reopen and window auto-switching
{BreakKey="CtrlDivide", action=function() S.listInstant = not S.listInstant; end},
{BreakKey="CtrlAdd", action=function() S.listDelay = S.listDelay<0 and 0 or S.listDelay+STEP; end},
{BreakKey="CtrlSubtract",action=function() S.listDelay = S.listDelay<0 and NOLIST or S.listDelay-STEP; end},
{BreakKey="CtrlMultiply",action=function() --cycle through listDelay values
S.listDelay = S.listDelay==NOLIST and 0
or S.listDelay==0 and O.listDelay --default
or S.listDelay>0 and NOLIST
end},
{BreakKey="F1", action=function() nfo:help() end},
}
local CommonKeys = { --!!to doc
CtrlF8 = resetSettings;
CtrlF1 = function(self) nfo:help(); self.br = ModReleased() end;
CtrlBS = function() return Screens:Delta(0) end;
CtrlO = not O.hideDesktop
and function() return "Desktop0" end or nil;
CtrlBackSlash = panel.CheckPanelsExist()
and function() return "Panels0" end or nil;
}
for k,v in pairs(CommonKeys) do table.insert(BreakKeys,{BreakKey=k,action=v}) end
local Props = {Title="RecentScreens",Id=win.Uuid(RSid),Flags=F.FMENU_WRAPMODE}
local Bottom = ("[F1] Help [/] Instant: %-5s [*/+/-] Delay: %9s")
local function _shift(key)
return key:find("Down$") and -1
or key:find("^R?CtrlShift") and -1
or key:find("Up$") and 1
or key:find("^R?Ctrl") and 1
or 0
end
local function _align(pos)
return pos>#Screens and 1 or pos<1 and #Screens or pos
end
local function RS_menu(key,is_modal) --switch far screens (shows list)
--??idea: show all windows even if nouid
local windows = {} -- helper table (windows by uid)
for _,uid,w in Screens:it_windows() do windows[uid] = w end
local Items = {}
for i=#Screens,1,-1 do
table.insert(Items,prepItem(windows[Screens[i]],i,is_modal))
end
local pos = not is_modal and key and _align(1+_shift(key))
local uid
repeat
if needSwitch() and not is_modal and pos then
Screens:Goto(Screens:Delta(pos-1))
end
Props.Bottom = Bottom:format(
tostring(S.listInstant),
S.listDelay==NOLIST and "<no list>" or S.listDelay.." ms"
)
Props.SelectIndex = pos
local item
item,pos = far.Menu(Props,Items,BreakKeys)
if item and item.action then --if BreakKey
uid = item:action()
end
until not item -- menu cancelled (Esc, CtrlBreak ets) / pos==nil
or item.text -- item selected (Enter pressed etc) / item==Items[pos]
or item.br -- BrK: currently active item will be selected
or uid and not is_modal -- BrK
if not is_modal then
return uid
or Screens:Delta((pos or 1)-1) -- no pos if dialog canceled (Ctrl-Break, Esc, ...)
-- !!pos==0 if all items disabled
end
end
---------------------------
-- switch without menu
local time
local function timeout(new)
if S.listDelay==NOLIST then return end --no-menu mode does not need timeout
local uptime = Far.UpTime
if not new then return uptime-time>S.listDelay end
time = uptime + S.listDelay
end
local function RS_nomenu(key) --switch far screens (no list)
timeout"new"
local Pos,uid = #Screens
mmode(1,0) --enable output
repeat -- NB: new loop every 50 ms
if key=="" and timeout() or key=="CtrlF12" then
return
elseif key~="" then
if CommonKeys[key] then
uid = CommonKeys[key]{}
else
Pos = _align(Pos-_shift(key))
Screens:Goto(Screens[Pos])
end
timeout"new"
end
key = uid or mf.waitkey(50)
until uid or ModReleased()
return uid or Screens[Pos]
end
----------------------------------------
-- main
local function need_manual_tracking(w)
return w.Type~=F.WTYPE_DIALOG and w.Type~=F.WTYPE_EDITOR and w.Type~=F.WTYPE_VIEWER
end
local function RecentScreens(mode)
local nomenu,key
if mode then
key = aKey()
nomenu = mode=="switch w/o menu"
end
local w = assert(actl(GetWindowInfo))
local uid = Uid(w)
if uid and need_manual_tracking(w) then
Screens:Focus(uid)
end
local is_modal = band(w.Flags,F.WIF_MODAL)~=0 or not uid
ModReleased(key and "set current" or false)
Screens.stateFreezeOrder = true
local target_uid
if not is_modal and nomenu and S.listInstant and S.listDelay~=0 and #Screens~=1 then
target_uid = RS_nomenu(key,is_modal)
key = false
end
if not target_uid then
target_uid = RS_menu(key,is_modal)
end
if target_uid then
Screens:Focus(target_uid)
Screens:Goto(target_uid)
end
Screens.stateFreezeOrder = false
end
nfo.config = function() RecentScreens() end;
---------------------------------------------
-- Main macro
local allScreens = "Shell Info QView Tree Editor Viewer Dialog "
if not O.hideDesktop then allScreens = allScreens.."Desktop " end
local function has_uid()
return Uid(assert(actl(GetWindowInfo)))
end
if O.macroKey then
Macro { description="[RecentScreens] switch";
area=allScreens; key="/^LCtrl(Shift)?("..O.macroKey..")$/";
id="792800D3-DD8A-4F5D-A4A8-1004E6AFBE7E";
condition=has_uid;
action=function()
RecentScreens"switch w/o menu"
if O.macroKey=="CapsLock" then LockState("Caps",0) end
end;
}
end
NoMacro { description="[RecentScreens] switch & show list";--https://forum.farmanager.com/viewtopic.php?p=121183#p121183
area=allScreens; key="/^LCtrl(Shift)?CapsLock$/";
id="3DC8C55E-376D-4ED5-8C42-FF3E30F0AD68";
condition=has_uid;
action=function()
RecentScreens"switch"
LockState("Caps",0)
end;
}
Macro { description="[RecentScreens] show list";
area="Common"; key="CtrlShiftF12";
id="40CA4C44-03C3-426A-8D25-0F882E7A50E5";
condition=function() return not isRecentScreensMenu() end;
action=function()
RecentScreens()
end;
}
MenuItem{ --!!test
menu= "Plugins Disks Config"; area="Common";
description=nfo.description;
text=function() return not isRecentScreensMenu() and nfo.name end;
guid="5019E6EC-1CD0-4C1F-91D7-DB505DC60ED6";
action=function() RecentScreens() end;
}
if O.fixAltDigitMacro then
Macro { description="[RecentScreens] fix MRU for Addons/Macros/AltScreens.lua";
area=allScreens.."Desktop "; key="/[LR]Alt[0-9]/";
id="67124A52-B6F8-448D-BF9D-846423785181";
condition=function()
local uid = Uid(assert(actl(GetWindowInfo)))
if uid then Screens:Focus(uid) end
end;
action=function()end;
}
end
--todo check Screens:Commit
--todo: сделать лайт-версию (после 4138 известен z-order, что позволяет не хранить порядок)
|