node-mac-recorder 1.2.11 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -10,7 +10,10 @@
10
10
  "Bash(brew install:*)",
11
11
  "Bash(open:*)",
12
12
  "Bash(curl:*)",
13
- "Bash(system_profiler:*)"
13
+ "Bash(system_profiler:*)",
14
+ "Bash(mkdir:*)",
15
+ "Bash(/dev/null)",
16
+ "Bash(ls:*)"
14
17
  ],
15
18
  "deny": []
16
19
  }
@@ -0,0 +1,461 @@
1
+ # Window Selector
2
+
3
+ **macOS Window Selection Tool with Real-time Visual Overlay**
4
+
5
+ Bu modül, macOS'ta sistem imleci ile pencere seçimi yapabilmenizi sağlayan güçlü bir araçtır. İmleç hangi pencerenin üstüne gelirse, o pencereyi mavi kapsayıcı ile highlight eder ve merkeze yerleştirilen "Select Window" butonu ile seçim yapabilirsiniz.
6
+
7
+ ## ✨ Özellikler
8
+
9
+ - **Real-time Window Detection**: İmleç hangi pencereye gelirse otomatik olarak tespit eder
10
+ - **Visual Overlay**: Seçilebilir pencereleri mavi transparant kapsayıcı ile highlight eder
11
+ - **Interactive Selection**: Merkeze yerleştirilen "Select Window" butonu ile kolay seçim
12
+ - **Multi-display Support**: Çoklu ekran kurulumlarında çalışır
13
+ - **Detailed Window Info**: Pencere pozisyonu, boyutu ve hangi ekranda olduğunu döndürür
14
+ - **Event-driven API**: Pencere hover, seçim ve hata durumları için event'ler
15
+ - **Window Focus Control**: Detect edilen pencereyi otomatik olarak en öne getirir
16
+ - **Auto Bring-to-Front**: Cursor hangi pencereye gelirse otomatik focus yapar
17
+ - **Permission Management**: macOS izin kontrolü ve yönetimi
18
+
19
+ ## 🚀 Kurulum
20
+
21
+ ```bash
22
+ # Ana proje dizininde
23
+ npm install
24
+
25
+ # Native modülü build edin
26
+ npm run build
27
+ ```
28
+
29
+ ## 📋 Sistem Gereksinimleri
30
+
31
+ - **macOS 10.15+** (Catalina veya üzeri)
32
+ - **Node.js 14+**
33
+ - **Xcode Command Line Tools**
34
+ - **System Permissions**:
35
+ - Screen Recording permission
36
+ - Accessibility permission
37
+
38
+ ## 🔐 İzinler
39
+
40
+ İlk kullanımda macOS aşağıdaki izinleri isteyecektir:
41
+
42
+ 1. **System Preferences > Security & Privacy > Privacy > Screen Recording**
43
+ - Terminal veya kullandığınız IDE'yi (VSCode, WebStorm, vb.) etkinleştirin
44
+
45
+ 2. **System Preferences > Security & Privacy > Privacy > Accessibility**
46
+ - Terminal veya kullandığınız IDE'yi etkinleştirin
47
+
48
+ ## 🎯 Temel Kullanım
49
+
50
+ ### Basit Pencere Seçimi
51
+
52
+ ```javascript
53
+ const WindowSelector = require('./window-selector');
54
+
55
+ async function selectWindow() {
56
+ const selector = new WindowSelector();
57
+
58
+ try {
59
+ console.log('Bir pencere seçin...');
60
+ const selectedWindow = await selector.selectWindow();
61
+
62
+ console.log('Seçilen pencere:', {
63
+ title: selectedWindow.title,
64
+ app: selectedWindow.appName,
65
+ position: `(${selectedWindow.x}, ${selectedWindow.y})`,
66
+ size: `${selectedWindow.width}x${selectedWindow.height}`,
67
+ screen: selectedWindow.screenId
68
+ });
69
+
70
+ return selectedWindow;
71
+
72
+ } catch (error) {
73
+ console.error('Hata:', error.message);
74
+ } finally {
75
+ await selector.cleanup();
76
+ }
77
+ }
78
+
79
+ selectWindow();
80
+ ```
81
+
82
+ ### Manuel Kontrol
83
+
84
+ ```javascript
85
+ const WindowSelector = require('./window-selector');
86
+
87
+ async function manualSelection() {
88
+ const selector = new WindowSelector();
89
+
90
+ // Event listener'lar
91
+ selector.on('windowEntered', (window) => {
92
+ console.log(`Pencere üstünde: ${window.title} (${window.appName})`);
93
+ });
94
+
95
+ selector.on('windowSelected', (window) => {
96
+ console.log(`Seçildi: ${window.title}`);
97
+ });
98
+
99
+ // Seçimi başlat
100
+ await selector.startSelection();
101
+
102
+ // Kullanıcı seçim yapana kadar bekle
103
+ // Seçim tamamlandığında 'windowSelected' event'i tetiklenir
104
+
105
+ // Seçimi durdurmak için:
106
+ // await selector.stopSelection();
107
+ }
108
+ ```
109
+
110
+ ## 📚 API Reference
111
+
112
+ ### WindowSelector Class
113
+
114
+ #### Constructor
115
+ ```javascript
116
+ const selector = new WindowSelector();
117
+ ```
118
+
119
+ #### Methods
120
+
121
+ ##### `async selectWindow()`
122
+ Promise tabanlı pencere seçimi. Kullanıcı bir pencere seçene kadar bekler.
123
+
124
+ **Returns:** `Promise<WindowInfo>`
125
+
126
+ ```javascript
127
+ const window = await selector.selectWindow();
128
+ ```
129
+
130
+ ##### `async startSelection()`
131
+ Pencere seçim modunu başlatır.
132
+
133
+ **Returns:** `Promise<boolean>`
134
+
135
+ ##### `async stopSelection()`
136
+ Pencere seçim modunu durdurur.
137
+
138
+ **Returns:** `Promise<boolean>`
139
+
140
+ ##### `getSelectedWindow()`
141
+ Son seçilen pencere bilgisini döndürür.
142
+
143
+ **Returns:** `WindowInfo | null`
144
+
145
+ ##### `getStatus()`
146
+ Seçici durumunu döndürür.
147
+
148
+ **Returns:** `SelectionStatus`
149
+
150
+ ##### `async checkPermissions()`
151
+ macOS izinlerini kontrol eder.
152
+
153
+ **Returns:** `Promise<PermissionStatus>`
154
+
155
+ ##### `async bringWindowToFront(windowId)`
156
+ Belirtilen pencereyi en öne getirir (focus yapar).
157
+
158
+ **Parameters:**
159
+ - `windowId` (number) - Window ID
160
+
161
+ **Returns:** `Promise<boolean>` - Başarı/başarısızlık
162
+
163
+ ```javascript
164
+ const success = await selector.bringWindowToFront(windowInfo.id);
165
+ ```
166
+
167
+ ##### `setBringToFrontEnabled(enabled)`
168
+ Otomatik pencere en öne getirme özelliğini aktif/pasif yapar.
169
+
170
+ **Parameters:**
171
+ - `enabled` (boolean) - Enable/disable
172
+
173
+ ```javascript
174
+ selector.setBringToFrontEnabled(true); // Auto mode ON
175
+ selector.setBringToFrontEnabled(false); // Auto mode OFF
176
+ ```
177
+
178
+ ##### `async cleanup()`
179
+ Tüm kaynakları temizler ve seçimi durdurur.
180
+
181
+ #### Events
182
+
183
+ ##### `selectionStarted`
184
+ Seçim modu başladığında tetiklenir.
185
+
186
+ ```javascript
187
+ selector.on('selectionStarted', () => {
188
+ console.log('Seçim başladı');
189
+ });
190
+ ```
191
+
192
+ ##### `windowEntered`
193
+ İmleç bir pencereye geldiğinde tetiklenir.
194
+
195
+ ```javascript
196
+ selector.on('windowEntered', (windowInfo) => {
197
+ console.log(`Pencere: ${windowInfo.title}`);
198
+ });
199
+ ```
200
+
201
+ ##### `windowLeft`
202
+ İmleç bir pencereden ayrıldığında tetiklenir.
203
+
204
+ ```javascript
205
+ selector.on('windowLeft', (windowInfo) => {
206
+ console.log(`Ayrıldı: ${windowInfo.title}`);
207
+ });
208
+ ```
209
+
210
+ ##### `windowSelected`
211
+ Bir pencere seçildiğinde tetiklenir.
212
+
213
+ ```javascript
214
+ selector.on('windowSelected', (windowInfo) => {
215
+ console.log('Seçilen pencere:', windowInfo);
216
+ });
217
+ ```
218
+
219
+ ##### `selectionStopped`
220
+ Seçim modu durduğunda tetiklenir.
221
+
222
+ ##### `error`
223
+ Bir hata oluştuğunda tetiklenir.
224
+
225
+ ```javascript
226
+ selector.on('error', (error) => {
227
+ console.error('Hata:', error.message);
228
+ });
229
+ ```
230
+
231
+ ## 📊 Data Types
232
+
233
+ ### WindowInfo
234
+ ```javascript
235
+ {
236
+ id: number, // Pencere ID'si
237
+ title: string, // Pencere başlığı
238
+ appName: string, // Uygulama adı
239
+ x: number, // Global X pozisyonu
240
+ y: number, // Global Y pozisyonu
241
+ width: number, // Pencere genişliği
242
+ height: number, // Pencere yüksekliği
243
+ screenId: number, // Hangi ekranda olduğu
244
+ screenX: number, // Ekranın X pozisyonu
245
+ screenY: number, // Ekranın Y pozisyonu
246
+ screenWidth: number, // Ekran genişliği
247
+ screenHeight: number // Ekran yüksekliği
248
+ }
249
+ ```
250
+
251
+ ### SelectionStatus
252
+ ```javascript
253
+ {
254
+ isSelecting: boolean, // Seçim modunda mı?
255
+ hasSelectedWindow: boolean, // Seçilmiş pencere var mı?
256
+ selectedWindow: WindowInfo | null,
257
+ nativeStatus: object // Native durum bilgisi
258
+ }
259
+ ```
260
+
261
+ ### PermissionStatus
262
+ ```javascript
263
+ {
264
+ screenRecording: boolean, // Ekran kaydı izni
265
+ accessibility: boolean, // Erişilebilirlik izni
266
+ microphone: boolean // Mikrofon izni
267
+ }
268
+ ```
269
+
270
+ ## 🎮 Test Etme
271
+
272
+ ### Test Dosyasını Çalıştır
273
+ ```bash
274
+ # Interaktif test
275
+ node window-selector-test.js
276
+
277
+ # API test modu
278
+ node window-selector-test.js --api-test
279
+ ```
280
+
281
+ ### Örnekleri Çalıştır
282
+ ```bash
283
+ # Basit örnek
284
+ node examples/window-selector-example.js
285
+
286
+ # Gelişmiş örnek (event'lerle)
287
+ node examples/window-selector-example.js --advanced
288
+
289
+ # Çoklu seçim
290
+ node examples/window-selector-example.js --multiple
291
+
292
+ # Detaylı analiz
293
+ node examples/window-selector-example.js --analysis
294
+
295
+ # Yardım
296
+ node examples/window-selector-example.js --help
297
+ ```
298
+
299
+ ## ⚡ Nasıl Çalışır?
300
+
301
+ 1. **Window Detection**: macOS `CGWindowListCopyWindowInfo` API'si ile açık pencereleri tespit eder
302
+ 2. **Cursor Tracking**: Real-time olarak imleç pozisyonunu takip eder
303
+ 3. **Overlay Rendering**: NSWindow ile transparant overlay penceresi oluşturur
304
+ 4. **Hit Testing**: İmlecin hangi pencere üstünde olduğunu hesaplar
305
+ 5. **Visual Feedback**: Pencereyi highlight eden mavi kapsayıcı çizer
306
+ 6. **User Interaction**: Merkeze yerleştirilen button ile seçim yapar
307
+ 7. **Data Collection**: Seçilen pencerenin tüm bilgilerini toplar
308
+
309
+ ## 🔧 Troubleshooting
310
+
311
+ ### Build Hataları
312
+ ```bash
313
+ # Xcode Command Line Tools'u yükle
314
+ xcode-select --install
315
+
316
+ # Node-gyp'i yeniden build et
317
+ npm run clean
318
+ npm run build
319
+ ```
320
+
321
+ ### İzin Hataları
322
+ 1. **System Preferences > Security & Privacy > Privacy** bölümüne git
323
+ 2. **Screen Recording** ve **Accessibility** sekmelerinde Terminal'i etkinleştir
324
+ 3. Uygulamayı yeniden başlat
325
+
326
+ ### Runtime Hataları
327
+ ```javascript
328
+ // İzinleri kontrol et
329
+ const permissions = await selector.checkPermissions();
330
+ if (!permissions.screenRecording) {
331
+ console.log('Screen recording permission required');
332
+ }
333
+ ```
334
+
335
+ ## 🌟 Gelişmiş Örnekler
336
+
337
+ ### Auto Bring-to-Front (Otomatik Focus)
338
+ ```javascript
339
+ const WindowSelector = require('./window-selector');
340
+
341
+ async function autoBringToFront() {
342
+ const selector = new WindowSelector();
343
+
344
+ // Otomatik focus modunu aktif et
345
+ selector.setBringToFrontEnabled(true);
346
+
347
+ selector.on('windowEntered', (window) => {
348
+ console.log(`🔝 Auto-focused: ${window.appName} - "${window.title}"`);
349
+ });
350
+
351
+ await selector.startSelection();
352
+ console.log('🖱️ Move cursor over windows - they will come to front automatically!');
353
+ }
354
+ ```
355
+
356
+ ### Manuel Window Focus
357
+ ```javascript
358
+ const WindowSelector = require('./window-selector');
359
+
360
+ async function manualFocus() {
361
+ const selector = new WindowSelector();
362
+
363
+ selector.on('windowEntered', async (window) => {
364
+ console.log(`Found: ${window.appName} - "${window.title}"`);
365
+
366
+ // Manuel olarak pencereyi en öne getir
367
+ const success = await selector.bringWindowToFront(window.id);
368
+ if (success) {
369
+ console.log('✅ Window brought to front!');
370
+ }
371
+ });
372
+
373
+ await selector.startSelection();
374
+ }
375
+ ```
376
+
377
+ ### Otomatik Pencere Kaydı
378
+ ```javascript
379
+ const WindowSelector = require('./window-selector');
380
+ const MacRecorder = require('./index');
381
+
382
+ async function recordSelectedWindow() {
383
+ const selector = new WindowSelector();
384
+ const recorder = new MacRecorder();
385
+
386
+ try {
387
+ // Pencere seç
388
+ const window = await selector.selectWindow();
389
+ console.log(`Recording: ${window.title}`);
390
+
391
+ // Seçilen pencereyi kaydet
392
+ const outputPath = `./recordings/${window.appName}-${Date.now()}.mov`;
393
+ await recorder.startRecording(outputPath, {
394
+ windowId: window.id,
395
+ captureCursor: true,
396
+ includeMicrophone: true
397
+ });
398
+
399
+ // 10 saniye kaydet
400
+ setTimeout(async () => {
401
+ await recorder.stopRecording();
402
+ console.log(`Recording saved: ${outputPath}`);
403
+ }, 10000);
404
+
405
+ } finally {
406
+ await selector.cleanup();
407
+ }
408
+ }
409
+ ```
410
+
411
+ ### Pencere Monitoring
412
+ ```javascript
413
+ const WindowSelector = require('./window-selector');
414
+
415
+ async function monitorWindowChanges() {
416
+ const selector = new WindowSelector();
417
+ const visitedWindows = new Set();
418
+
419
+ selector.on('windowEntered', (window) => {
420
+ const key = `${window.appName}-${window.title}`;
421
+ if (!visitedWindows.has(key)) {
422
+ visitedWindows.add(key);
423
+ console.log(`Yeni pencere keşfedildi: ${window.title} (${window.appName})`);
424
+ }
425
+ });
426
+
427
+ await selector.startSelection();
428
+
429
+ // İptal etmek için Ctrl+C
430
+ process.on('SIGINT', async () => {
431
+ console.log(`\nToplam keşfedilen pencere: ${visitedWindows.size}`);
432
+ await selector.cleanup();
433
+ process.exit(0);
434
+ });
435
+ }
436
+ ```
437
+
438
+ ## 📄 Lisans
439
+
440
+ Bu modül ana projenin lisansı altındadır.
441
+
442
+ ## 🤝 Katkıda Bulunma
443
+
444
+ 1. Fork edin
445
+ 2. Feature branch oluşturun (`git checkout -b feature/amazing-feature`)
446
+ 3. Commit edin (`git commit -m 'Add amazing feature'`)
447
+ 4. Push edin (`git push origin feature/amazing-feature`)
448
+ 5. Pull Request açın
449
+
450
+ ## ⭐ Özellik İstekleri
451
+
452
+ - [ ] Pencere gruplandırma
453
+ - [ ] Hotkey desteği
454
+ - [ ] Pencere filtreleme
455
+ - [ ] Çoklu seçim modu
456
+ - [ ] Screenshot alma
457
+ - [ ] Window history
458
+
459
+ ---
460
+
461
+ **Not**: Bu modül sadece macOS'ta çalışır ve sistem izinleri gerektirir.
@@ -0,0 +1,71 @@
1
+ #!/usr/bin/env node
2
+
3
+ const WindowSelector = require('./window-selector');
4
+
5
+ async function autoBringToFrontDemo() {
6
+ console.log('🤖 Auto Bring-To-Front Demo');
7
+ console.log('============================\n');
8
+
9
+ const selector = new WindowSelector();
10
+
11
+ try {
12
+ console.log('🔄 Enabling auto bring-to-front feature...');
13
+ selector.setBringToFrontEnabled(true);
14
+
15
+ console.log('✅ Auto mode enabled!');
16
+ console.log('🖱️ Now move your cursor over different windows');
17
+ console.log('🔝 Each window should automatically come to front\n');
18
+
19
+ let windowCount = 0;
20
+ let lastWindowId = null;
21
+
22
+ selector.on('windowEntered', (window) => {
23
+ if (window.id !== lastWindowId) {
24
+ windowCount++;
25
+ console.log(`[${windowCount}] 🎯 AUTO-FRONT: ${window.appName} - "${window.title}"`);
26
+ console.log(` 📍 Position: (${window.x}, ${window.y})`);
27
+ console.log(` 📏 Size: ${window.width} × ${window.height}`);
28
+ console.log(` 🔝 Window should come to front automatically!\n`);
29
+ lastWindowId = window.id;
30
+ }
31
+ });
32
+
33
+ selector.on('windowLeft', (window) => {
34
+ console.log(`🚪 Left: ${window.appName} - "${window.title}"\n`);
35
+ });
36
+
37
+ await selector.startSelection();
38
+
39
+ console.log('Demo started! Move cursor over different app windows to see them come to front.');
40
+ console.log('Press Ctrl+C to stop\n');
41
+
42
+ // Auto-stop after 60 seconds
43
+ setTimeout(async () => {
44
+ console.log('\n⏰ Demo completed!');
45
+ console.log(`📊 Total windows auto-focused: ${windowCount}`);
46
+ selector.setBringToFrontEnabled(false);
47
+ await selector.cleanup();
48
+ process.exit(0);
49
+ }, 60000);
50
+
51
+ // Manual stop
52
+ process.on('SIGINT', async () => {
53
+ console.log('\n\n🛑 Stopping demo...');
54
+ console.log(`📊 Total windows auto-focused: ${windowCount}`);
55
+ selector.setBringToFrontEnabled(false);
56
+ await selector.cleanup();
57
+ process.exit(0);
58
+ });
59
+
60
+ // Prevent exit
61
+ setInterval(() => {}, 1000);
62
+
63
+ } catch (error) {
64
+ console.error('❌ Error:', error.message);
65
+ await selector.cleanup();
66
+ }
67
+ }
68
+
69
+ if (require.main === module) {
70
+ autoBringToFrontDemo();
71
+ }
package/binding.gyp CHANGED
@@ -6,7 +6,8 @@
6
6
  "src/mac_recorder.mm",
7
7
  "src/screen_capture.mm",
8
8
  "src/audio_capture.mm",
9
- "src/cursor_tracker.mm"
9
+ "src/cursor_tracker.mm",
10
+ "src/window_selector.mm"
10
11
  ],
11
12
  "include_dirs": [
12
13
  "<!@(node -p \"require('node-addon-api').include\")"
@@ -0,0 +1,159 @@
1
+ #!/usr/bin/env node
2
+
3
+ const WindowSelector = require('./window-selector');
4
+
5
+ async function testBringToFront() {
6
+ console.log('🔝 Bring To Front Test');
7
+ console.log('======================\n');
8
+
9
+ const selector = new WindowSelector();
10
+
11
+ try {
12
+ // Test 1: Manual bring to front
13
+ console.log('📋 Test 1: Manual window bring-to-front');
14
+ console.log('Move cursor over a window and press SPACE to bring it to front\n');
15
+
16
+ let currentWindow = null;
17
+
18
+ selector.on('windowEntered', (window) => {
19
+ currentWindow = window;
20
+ console.log(`\n🏠 Window: ${window.appName} - "${window.title}" (ID: ${window.id})`);
21
+ console.log(' 📍 Position:', `(${window.x}, ${window.y})`);
22
+ console.log(' 📏 Size:', `${window.width} × ${window.height}`);
23
+ console.log(' 💡 Press SPACE to bring this window to front');
24
+ console.log(' 💡 Press A to enable AUTO bring-to-front');
25
+ console.log(' 💡 Press D to disable AUTO bring-to-front');
26
+ });
27
+
28
+ selector.on('windowLeft', (window) => {
29
+ console.log(`🚪 Left: ${window.appName} - "${window.title}"`);
30
+ currentWindow = null;
31
+ });
32
+
33
+ // Keyboard controls
34
+ const readline = require('readline');
35
+ readline.emitKeypressEvents(process.stdin);
36
+ if (process.stdin.isTTY) {
37
+ process.stdin.setRawMode(true);
38
+ }
39
+
40
+ process.stdin.on('keypress', async (str, key) => {
41
+ if (key.name === 'space' && currentWindow) {
42
+ console.log(`\n🔝 Bringing window to front: ${currentWindow.appName} - "${currentWindow.title}"`);
43
+ try {
44
+ const success = await selector.bringWindowToFront(currentWindow.id);
45
+ if (success) {
46
+ console.log(' ✅ Window brought to front successfully!');
47
+ } else {
48
+ console.log(' ❌ Failed to bring window to front');
49
+ }
50
+ } catch (error) {
51
+ console.log(' ❌ Error:', error.message);
52
+ }
53
+ } else if (key.name === 'a') {
54
+ console.log('\n🔄 Enabling AUTO bring-to-front mode...');
55
+ selector.setBringToFrontEnabled(true);
56
+ console.log(' ✅ Auto mode ON - Windows will come to front automatically');
57
+ } else if (key.name === 'd') {
58
+ console.log('\n🔄 Disabling AUTO bring-to-front mode...');
59
+ selector.setBringToFrontEnabled(false);
60
+ console.log(' ✅ Auto mode OFF - Manual control only');
61
+ } else if (key.ctrl && key.name === 'c') {
62
+ process.exit(0);
63
+ }
64
+ });
65
+
66
+ console.log('🚀 Starting window selection...\n');
67
+ console.log('📋 Controls:');
68
+ console.log(' SPACE - Bring current window to front');
69
+ console.log(' A - Enable AUTO bring-to-front');
70
+ console.log(' D - Disable AUTO bring-to-front');
71
+ console.log(' Ctrl+C - Exit\n');
72
+
73
+ await selector.startSelection();
74
+
75
+ // Keep running
76
+ process.on('SIGINT', async () => {
77
+ console.log('\n🛑 Stopping...');
78
+ await selector.cleanup();
79
+ process.exit(0);
80
+ });
81
+
82
+ // Prevent exit
83
+ setInterval(() => {}, 1000);
84
+
85
+ } catch (error) {
86
+ console.error('❌ Error:', error.message);
87
+ console.error(error.stack);
88
+ } finally {
89
+ // Cleanup
90
+ await selector.cleanup();
91
+ }
92
+ }
93
+
94
+ async function testAutoBringToFront() {
95
+ console.log('🤖 Auto Bring To Front Test');
96
+ console.log('============================\n');
97
+
98
+ const selector = new WindowSelector();
99
+
100
+ try {
101
+ // Enable auto bring-to-front
102
+ console.log('🔄 Enabling auto bring-to-front...');
103
+ selector.setBringToFrontEnabled(true);
104
+
105
+ let windowCount = 0;
106
+
107
+ selector.on('windowEntered', (window) => {
108
+ windowCount++;
109
+ console.log(`\n[${windowCount}] 🔝 AUTO FRONT: ${window.appName} - "${window.title}"`);
110
+ console.log(` 📍 Position: (${window.x}, ${window.y})`);
111
+ console.log(` 📏 Size: ${window.width} × ${window.height}`);
112
+ console.log(' 🚀 Window should automatically come to front!');
113
+ });
114
+
115
+ console.log('✅ Auto bring-to-front enabled');
116
+ console.log('🖱️ Move cursor over different windows');
117
+ console.log('🔝 Each window should automatically come to front');
118
+ console.log('⏱️ Test will run for 30 seconds\n');
119
+
120
+ await selector.startSelection();
121
+
122
+ // Auto-stop after 30 seconds
123
+ setTimeout(async () => {
124
+ console.log('\n⏰ Test completed!');
125
+ console.log(`📊 Total windows auto-focused: ${windowCount}`);
126
+ selector.setBringToFrontEnabled(false);
127
+ await selector.cleanup();
128
+ process.exit(0);
129
+ }, 30000);
130
+
131
+ } catch (error) {
132
+ console.error('❌ Error:', error.message);
133
+ await selector.cleanup();
134
+ }
135
+ }
136
+
137
+ // Main function
138
+ async function main() {
139
+ const args = process.argv.slice(2);
140
+
141
+ if (args.includes('--auto')) {
142
+ await testAutoBringToFront();
143
+ } else if (args.includes('--help')) {
144
+ console.log('Bring To Front Tests:');
145
+ console.log('====================');
146
+ console.log('node bring-to-front-test.js [option]');
147
+ console.log('');
148
+ console.log('Options:');
149
+ console.log(' --manual Manual bring-to-front test (default)');
150
+ console.log(' --auto Auto bring-to-front test');
151
+ console.log(' --help Show this help');
152
+ } else {
153
+ await testBringToFront();
154
+ }
155
+ }
156
+
157
+ if (require.main === module) {
158
+ main().catch(console.error);
159
+ }