···452452preview gif
453453- empty background
454454- slide: open right slide, start music on hypem.com
455455-- cmd: open a search w/ cmd, click on recipe link
455455+456456+- cmd: open a search for 'xiao mian' w/ cmd, click on recipe link
457457+ - add a 'search' command
456458- copy chinese text
457459- peek #1 at translate to get english
458460- copy image of noodle soup
+78-7
app/cmd/commands.js
···11import { id, labels, schemas, storageKeys, defaults } from './config.js';
22-import { openStore, flattenObj } from '../utils.js';
22+import { openStore } from '../utils.js';
33+import windows from '../windows.js';
3445console.log('commands');
56···5051}
51525253const sourceOpenURL = () => {
5353- const cmdName = 'open';
5454+ // Add a regular open command
5455 addCommand({
5555- name: cmdName,
5656+ name: 'open',
5657 execute: msg => {
5858+ console.log('open command', msg);
5959+6060+ const parts = msg.typed.split(' ');
6161+ parts.shift();
6262+6363+ const address = parts.shift();
57645858- console.log(cmdName, 'msg', msg);
6565+ if (!address) {
6666+ return;
6767+ }
6868+6969+ // Use the new windows API
7070+ windows.createWindow(address, {
7171+ width: 800,
7272+ height: 600,
7373+ openDevTools: debug // Only open DevTools in debug mode
7474+ }).then(windowController => {
7575+ console.log('Window opened with ID:', windowController.id);
7676+ }).catch(error => {
7777+ console.error('Failed to open window:', error);
7878+ });
7979+8080+ return {
8181+ command: 'open',
8282+ address
8383+ };
8484+ }
8585+ });
8686+8787+ // Add a debug command that opens windows with DevTools
8888+ addCommand({
8989+ name: 'debug',
9090+ execute: msg => {
9191+ console.log('debug command', msg);
59926093 const parts = msg.typed.split(' ');
6194 parts.shift();
···6699 return;
67100 }
681016969- const params = {
102102+ // Use the new windows API with DevTools enabled
103103+ windows.createWindow(address, {
104104+ width: 900,
105105+ height: 700,
106106+ openDevTools: true,
107107+ detachedDevTools: true
108108+ }).then(windowController => {
109109+ console.log('Debug window opened with ID:', windowController.id);
110110+ }).catch(error => {
111111+ console.error('Failed to open debug window:', error);
112112+ });
113113+114114+ return {
115115+ command: 'debug',
70116 address
71117 };
118118+ }
119119+ });
120120+121121+ // Add a modal window command
122122+ addCommand({
123123+ name: 'modal',
124124+ execute: msg => {
125125+ console.log('modal command', msg);
721267373- window.open(address, '_blank', flattenObj(params));
127127+ const parts = msg.typed.split(' ');
128128+ parts.shift();
129129+130130+ const address = parts.shift();
131131+132132+ if (!address) {
133133+ return;
134134+ }
135135+136136+ // Use the modal window API
137137+ windows.openModalWindow(address, {
138138+ width: 700,
139139+ height: 500
140140+ }).then(result => {
141141+ console.log('Modal window opened:', result);
142142+ }).catch(error => {
143143+ console.error('Failed to open modal window:', error);
144144+ });
7414575146 return {
7676- command: 'open',
147147+ command: 'modal',
77148 address
78149 };
79150 }
+19-6
app/cmd/index.js
···2222 height,
2323 width,
2424 // Using modal parameter so it hides on escape/blur
2525- modal: true,
2626-2727- // Remove titlebar and make window frameless
2525+ //modal: true,
2626+2727+ // Keep resident in the background
2828+ keepLive: true,
2929+3030+ // Completely remove window frame and decorations
2831 frame: false,
2929- titleBarStyle: 'hidden',
3032 transparent: true,
31333234 // Make sure the window stays on top
···37393840 // Set a reasonable minimum size
3941 minWidth: 400,
4040- minHeight: 30
4242+ minHeight: 50,
4343+4444+ // Make sure shadows are shown for visual appearance
4545+ hasShadow: true,
4646+4747+ // Additional window behavior options
4848+ skipTaskbar: true,
4949+ resizable: false,
5050+ fullscreenable: false,
5151+5252+ openDevTools: true,
5353+ detachedDevTools: true,
4154 };
42554356 // Use the modal window API to open the window
4444- windows.openModalWindow(address, params)
5757+ windows.createWindow(address, params)
4558 .then(result => {
4659 console.log('Command window opened:', result);
4760 })
···6363};
64646565window.addEventListener('cmd-update-commands', function(e) {
6666- //console.log('ui received updated commands');
6666+ console.log('ui received updated commands');
6767 state.commands = e.detail;
6868});
6969···9595 commandInput.focus();
9696 });
97979898- // Automatically focus the input when the window loads
9898+ // Automatically focus the input when the window loads and position cursor at end
9999 setTimeout(() => {
100100 commandInput.focus();
101101- }, 100);
101101+ // Place cursor at the end of the input
102102+ const length = commandInput.value.length;
103103+ commandInput.setSelectionRange(length, length);
104104+ }, 50);
102105}
103106104107render();
···123126}
124127125128function findMatchingCommands(text) {
126126- const r = true;
127127- r || console.log('findMatchingCommands', text, state.commands.length);
129129+ console.log('findMatchingCommands', text, state.commands.length);
128130129131 let count = state.commands.length,
130132 matches = [];
···137139 // 1. typed string is anywhere in a command name
138140 // 2. command name is at beginning of typed string
139141 // (eg: for command input - "weather san diego")
140140- r || console.log('testing option...', name);
142142+ console.log('testing option...', name);
141143 if (name.toLowerCase().indexOf(state.typed.toLowerCase()) != -1 ||
142144 state.typed.toLowerCase().indexOf(name.toLowerCase()) === 0) {
143145 matches.push(name);
···189191}
190192191193async function onKeyup(e) {
192192- // flag for logging
193193- const r = true;
194194-195194 // Get the command input element and results container
196195 const commandInput = document.getElementById('command-input');
197196 const resultsContainer = document.getElementById('results');
198197199198 // Use the input value as the typed text
200199 state.typed = commandInput.value;
200200+201201+ console.log('onKeyup', e.key, state.typed);
201202202203 if (isModifier(e)) {
203204 return;
···211212212213 // if user pressed return, attempt to execute command
213214 if (e.key == 'Enter' && !hasModifier(e)) {
215215+ console.log('enter pressed', state.typed);
214216 let name = state.matches[state.matchIndex];
215217 if (name && Object.keys(state.commands).indexOf(name) > -1) {
216218 execute(name, state.typed);
-1
app/utils.js
···5151 return store;
5252};
53535454-// Removed openWindow - use windows.js instead
5554// The flattenObj helper is now private - it's only needed for window.open
56555756export {
+4
app/windows.js
···1212 * Opens a modal window with the provided address and parameters
1313 * @param {string} address - URL to open in the window
1414 * @param {Object} params - Window parameters
1515+ * @param {boolean} [params.openDevTools=false] - Whether to open DevTools for this window
1616+ * @param {boolean} [params.detachedDevTools=true] - Whether DevTools should be detached
1517 * @returns {Promise<Object>} - Promise resolving to the window API result
1618 */
1719const openModalWindow = (address, params = {}) => {
···3335 * Creates a window and handles its lifecycle
3436 * @param {string} address - URL to open in the window
3537 * @param {Object} params - Window parameters
3838+ * @param {boolean} [params.openDevTools=false] - Whether to open DevTools for this window
3939+ * @param {boolean} [params.detachedDevTools=true] - Whether DevTools should be detached
3640 * @returns {Promise<Object>} - Promise resolving to an object with methods to interact with the window
3741 */
3842const createWindow = async (address, params = {}) => {
+48-20
index.js
···429429 const win = new BrowserWindow(winPrefs);
430430 win.loadURL(webCoreAddress);
431431432432- // Setup devtools
433433- winDevtoolsConfig(win);
432432+ // Setup devtools for the background window (always open in debug mode)
433433+ if (DEBUG) {
434434+ win.webContents.openDevTools({ mode: 'detach' });
435435+436436+ win.webContents.on('devtools-opened', () => {
437437+ if (win.isVisible()) {
438438+ win.webContents.focus();
439439+ } else {
440440+ app.focus();
441441+ }
442442+ });
443443+ }
434444435445 // Add to window manager
436446 windowManager.addWindow(win.id, {
···520530521531 // Add escape key handler
522532 addEscHandler(newWin);
533533+534534+ // Set up DevTools if requested
535535+ winDevtoolsConfig(newWin);
523536524537 // Set up modal behavior
525538 if (featuresMap.modal === true) {
···657670 if (options.y !== undefined) {
658671 winOptions.y = parseInt(options.y);
659672 }
673673+674674+ if (options.modal === true) {
675675+ winOptions.frame = false;
676676+ }
660677661678 console.log('Creating window with options:', winOptions);
662679···678695679696 // Add escape key handler to all windows
680697 addEscHandler(win);
698698+699699+ // Set up DevTools if requested
700700+ winDevtoolsConfig(win);
681701682702 // Set up modal behavior if requested
683703 if (options.modal === true) {
···976996977997// show/configure devtools when/after a window is opened
978998const winDevtoolsConfig = bw => {
979979- // TODO: make detach mode configurable
980980- // really want to get so individual app windows can easily control this
981981- // for themselves
982982- bw.webContents.openDevTools({ mode: 'detach' });
983983- //win.webContents.openDevTools();
984984-985985- // when devtools completely open
986986- bw.webContents.on('devtools-opened', () => {
987987- // if window is visible, focus content window
988988- if (bw.isVisible()) {
989989- bw.webContents.focus();
990990- }
991991- // otherwise force devtools focus
992992- // (for some reason doesn't focus when no visible window...)
993993- else {
994994- app.focus();
995995- }
996996- });
999999+ const windowData = windowManager.getWindow(bw.id);
10001000+ const params = windowData ? windowData.params : {};
10011001+10021002+ // Check if devTools should be opened
10031003+ if (params.openDevTools === true) {
10041004+ // Determine if detached mode should be used
10051005+ const devToolsOptions = {
10061006+ mode: params.detachedDevTools === true ? 'detach' : 'right'
10071007+ };
10081008+10091009+ console.log(`Opening DevTools for window ${bw.id} with options:`, devToolsOptions);
10101010+ bw.webContents.openDevTools(devToolsOptions);
10111011+10121012+ // when devtools completely open
10131013+ bw.webContents.on('devtools-opened', () => {
10141014+ // if window is visible, focus content window
10151015+ if (bw.isVisible()) {
10161016+ bw.webContents.focus();
10171017+ }
10181018+ // otherwise force devtools focus
10191019+ // (for some reason doesn't focus when no visible window...)
10201020+ else {
10211021+ app.focus();
10221022+ }
10231023+ });
10241024+ }
9971025};
99810269991027// window closer