Skip to content

Commit

Permalink
Config and prompts for focus simulator feature
Browse files Browse the repository at this point in the history
- Add a config option `ios-debug.focusSimulator` to turn off automatic simulator focus behaviour
- Add prompts to get the System Events and Accessibility permission as required when starting to debug on Simulator
- Disable to simulator focus monitor if it is turned off or we don't have enough permissions
  • Loading branch information
nisargjhaveri committed Jul 27, 2022
1 parent 5a9d241 commit ccf7ce6
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 4 deletions.
12 changes: 11 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,17 @@
}
}
}
]
],
"configuration": {
"title": "iOS Debugger",
"properties": {
"ios-debug.focusSimulator": {
"type": "boolean",
"default": true,
"description": "Automatically focus iOS Simulator window when attaching or continuing after a breakpoint."
}
}
}
},
"scripts": {
"vscode:prepublish": "npm run compile",
Expand Down
12 changes: 9 additions & 3 deletions src/debugConfigProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ import * as crypto from 'crypto';
import * as path from 'path';
import * as vscode from 'vscode';
import * as logger from './logger';
import { Simulator, Target, TargetType } from './commonTypes';
import { Target, TargetType } from './commonTypes';
import * as targetCommand from './targetCommand';
import { getTargetFromUDID, pickTarget, _getOrPickTarget } from './targetPicker';
import * as simulatorFocus from './simulatorFocus';

let context: vscode.ExtensionContext;

Expand Down Expand Up @@ -92,6 +93,9 @@ export class DebugConfigurationProvider implements vscode.DebugConfigurationProv
{
let pid: string|void;

// Check if we have enough permissions for the simulator focus monitor.
let enableSimulatorFocusMonitor = vscode.workspace.getConfiguration().get('ios-debug.focusSimulator') && await simulatorFocus.tryEnsurePermissions();

if (dbgConfig.iosRequest === "launch")
{
let outputBasename = getOutputBasename();
Expand Down Expand Up @@ -123,8 +127,10 @@ export class DebugConfigurationProvider implements vscode.DebugConfigurationProv

dbgConfig.pid = pid;

dbgConfig.postRunCommands = (dbgConfig.postRunCommands instanceof Array) ? dbgConfig.postRunCommands : [];
dbgConfig.postRunCommands.push(`simulator-focus-monitor ${target.name}${target.runtime}`);
if (enableSimulatorFocusMonitor) {
dbgConfig.postRunCommands = (dbgConfig.postRunCommands instanceof Array) ? dbgConfig.postRunCommands : [];
dbgConfig.postRunCommands.push(`simulator-focus-monitor ${target.name}${target.runtime}`);
}

delete dbgConfig.env;
delete dbgConfig.args;
Expand Down
62 changes: 62 additions & 0 deletions src/simulatorFocus.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import * as vscode from 'vscode';
import { _execFile } from './utils';
import * as logger from './logger';


export async function tryEnsurePermissions(): Promise<boolean> {
// We first try the command which needs both System Events and Accessibility permissions
// If it fails, we try a command which needs System Events permissions and ouputs if we have accessibility permission
// If the first command succeeds, we have all the required permissions.
// If the second fails, we don't have System Events permission.
// If the second command succeeds but prints false, we don't have accessibility permission.
// Otherwise some unknown error.

try {
await _execFile('osascript', ['-e', 'tell application "System Events" to tell application process "Simulator" to get menu bars']);

// If we reach here, we have all the required permissions.
return true;
}
catch (e) {
logger.log(e);
}

try {
let {stdout} = await _execFile('osascript', ['-e', 'tell application "System Events" to UI elements enabled']);

// if stdout is false, we need accessibility permission
if (stdout.trim() === "false") {
logger.log("Get Accessibility permission");
vscode.window.showWarningMessage(
"Select Visual Studio Code checkbox in Security and Privacy > Accessibility. This is required to automatically focus the simulator while debugging",
{action: "OPEN", title: "Turn on Accessibility"}
)
.then((action) => {
if (action && action.action === "OPEN") {
vscode.env.openExternal(vscode.Uri.parse("x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility"));
}
});
}

// If we reach here, we have System Events permission, which is enoguh for basic functionality.
return true;
}
catch (e) {
logger.log(e);

// we need AppleEvents permission first
logger.log("Get System Events permission");
vscode.window.showWarningMessage(
"Select System Events checkbox for Visual Studio Code in Security and Privacy > Automation. This is required to automatically focus the simulator while debugging",
{action: "OPEN", title: "Turn on System Events"}
)
.then((action) => {
if (action && action.action === "OPEN") {
vscode.env.openExternal(vscode.Uri.parse("x-apple.systempreferences:com.apple.preference.security?Privacy_Automation"));
}
});
}

// We don't have system events permission, nothing will work.
return false;
}

0 comments on commit ccf7ce6

Please sign in to comment.