Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
153 changes: 97 additions & 56 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,99 +1,140 @@
# Contributing

## Requirements:
You need cmake, yarn, node version 24 or nvm, and a proper C/C++ compiler toolchain of the given platform
Thank you for your interest in contributing! This guide will help you set up your development environment and understand the contribution process.

### Windows
- [Visual C++ Build Tools](https://visualstudio.microsoft.com/visual-cpp-build-tools/). If you installed nodejs with the installer, you can install these when prompted.
- An alternate way is to install the [Chocolatey package manager](https://chocolatey.org/install), and run `choco install visualstudio2017-workload-vctools` in an Administrator Powershell
## Prerequisites:
You need CMake, Yarn, Node.js version 24 (or nvm), and a proper C/C++ compiler toolchain for your platform.

## Windows
- [Visual C++ Build Tools](https://visualstudio.microsoft.com/visual-cpp-build-tools/). If you installed Node.js with the installer, you can install these when prompted.
- An alternate way is to install the [Chocolatey package manager](https://chocolatey.org/install) and run `choco install visualstudio2017-workload-vctools` in an Administrator PowerShell
- If you have multiple versions installed, you can select a specific version with `npm config set msvs_version 2017` (Note: this will also affect `node-gyp`)
- [cmake](https://cmake.org/download/),
- Node version 24 or [nvm](https://github.com/nvm-sh/nvm)
- [yarn](https://yarnpkg.com/).
### Unix/Posix
- Clang or GCC
- [CMake](https://cmake.org/download/)
- Node.js version 24 or [nvm](https://github.com/nvm-sh/nvm)
- [Yarn](https://yarnpkg.com/)

## Linux
- GCC
- Ninja or Make (Ninja will be picked if both present)
- Node version 24 or [nvm](https://github.com/nvm-sh/nvm)
- [yarn](https://yarnpkg.com/).
### MacOS
- brew install cmake nvm yarn
### ArchLinux:
- sudo pacman -S xcb-util-wm nvm yarn cmake g++
- X11 or Wayland with X11 libs api.
- Node.js version 24 or [nvm](https://github.com/nvm-sh/nvm)
- [Yarn](https://yarnpkg.com/)

### Arch Linux
```bash
sudo pacman -S xcb-util-wm nvm yarn cmake g++
```
### Ubuntu

```bash
apt-get install libx11-dev libxtst-dev libxcb-ewmh-dev libxcb1-dev cmake g++ make
```
## Apple

- Clang
- Ninja or Make (Ninja will be picked if both present)
- Node.js version 24 or [nvm](https://github.com/nvm-sh/nvm)
- [Yarn](https://yarnpkg.com/)

```bash
brew install cmake nvm yarn
```

## Run in dev mode

To build the client you need

```sh
nvm use 24 # If you already have node 24, skip it. Also do not use node 25, it has broken SEA
yarn # install depenencies
yarn build:local # builds native c++ modules
yarn # install dependencies
yarn cmake # builds native c++ modules
yarn start # starts a nestjs server
```

## Debugging Native Code
## Debugging Native .cc files

### Build the Native Module
If you want to debug native Node.js modules you need to build the module in **Debug mode**.

## 1. Build the Native Module
Run:
```bash
yarn cmake:debug
```
This command already builds the native module in Debug mode.

### Start and Attach the Debugger
## 2. Start and Attach the Debugger
- Start your app with:
```bash
yarn start
```
#### Windows:
You can only debug with VisualStudio or with `cdb`, since that toolchain was required for cmakejs. Clion wouldn't be able to pull sourcemaps. You need to attach to the remote process that was started above.
#### Linux
You can use any debugger IDE. E.g. `gdb` or CLion. You need to attach to the already running Node.js process. IDE should automatically pull sourcemaps, allowing you to place breakpoints in native C++ code.
```
- Attach to a remote process using your favorite (c++) IDE debugger, see the IDE options below

## IDE

### Enable Syntax Highlighting for Node.js Headers in Clion
CLion does not automatically pick up Node.js and N-API headers. You must add them manually:
### CLION
For .cc (c++) you can use CLion for syntaxt support and debugging. However Clion debugger would only work on Linux. On **windows CLion debugger won't work**, since CLion cannot properly work with `cl.exe` windows compiler, which emits source info to a different file. You can still use Clion for syntaxt higlight on windows thought .

**Steps:**
1. Go to **Settings → Build, Execution, Deployment → CMake**.
2. Add a new configuration.
3. Build directory: `build`
4. Add the following Options:
3. Toolchain:
- **gcc** for Linux
- **Visual Studio** for Windows and
4. Generator:
- **ninja** generator for **Linux**
- **Visual Studio 17 2020** generator for **Windows**
5. Build directory: Select `build`
6. CMake options: Add the following options (change the path to project path). It should be absolute path.

#### Arch Linux example
```cmake
-DCMAKE_CXX_FLAGS="-I/home/andrew/.nvm/versions/node/v24.20.5/include/node -I/home/andrew/it/my-projects/http-remote-pc-control/node_modules/node-addon-api"
-DCMAKE_CXX_FLAGS="-IC:\hotkey-hub\node_modules\node-api-headers\include -IC:\hotkey-hub\node_modules\node-addon-api"
```
**Generator** (adjust to your CLI match system).
Select ninja generator (unless your cli configured otherwise)
For debugging do
- Launch nodejs process
- Run (from top menu) -> Attach to process -> Find nodejs process here

#### Windows example
**CMake options** (adjust paths for your system).
```cmake
-DCMAKE_CXX_FLAGS="-IC:\Users\death\.cmake-js\node-x64\v24.20.5\include\node -IC:\Users\death\WebstormProjects\http-remote-pc-control\node_modules\node-addon-api"
Note it should be nodejs process, not the parent yarn process that started nodejs


### Visual Studio

Don't confuse it with VSCode, Visual Studio is required to syntaxt highlight debug .cc (c++) files
In order to generate VisualStudio project do:
```ps1
yarn clean
yarn cmake-js configure -G "Visual Studio 17 2022"
```
**Generator** (adjust to your CLI match system).
`Visual Studio 17 2022`.

If you just need to build and syntax support on CLION. Use settings cmake
Open `build` directory in Visual Studio as a project.
You should be able to modify file and get proper syntaxt highlight.

For debugging do
- Launch nodejs process. E.g. `yarn start`
- Debugging (from top menu) -> Attach to process -> Find nodejs process here. E.g. filter all process by `node` and find `node -r tsconfig-paths/register -r ts-node/register src/main.ts`.

### Required Directories
You need to provide **two include directories**:
### Webstorm/VSCode

- **Node.js headers**
- Example: `.../include/node`
- Contains `node.h`, `node_api.h`, etc.
- If missing, run:
```bash
npx cmake-js print-cmakejs-src
```
The use is straightforward, typecript language service should automatically pull all .ts file info and syntaxt highlight.

- **N-API headers**
- Example: `.../node_modules/node-addon-api`
- Contains `napi.h` and related files.
Note it should be nodejs process, not the parent yarn process that started nodejs

## Testing
There are Node.js tests only in this project.

## Test
There are nodejs tests and native (napi) tests. Both will run upon
```bash
yarn test
```
Mouse move test could fail if you move mouse during the test.


# Bugs

### Foreground
```txt
setForegroundWindow blocked by windows, place focus on http-remote-pc-control terminal to override
```
Fixes to try that didnt work:

1)
```
reg add "HKCU\Control Panel\Desktop" /v ForegroundLockTimeout /t REG_DWORD /d 0 /f
```
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "http-remote-pc-control",
"version": "3.1.1",
"version": "3.1.1-rc1",
"repository": "git@github.com:akoidan/http-remote-pc-control.git",
"author": "akoidan <deathangel908@gmail.com>",
"license": "MIT",
Expand Down
6 changes: 4 additions & 2 deletions packages/http-remote-pc-control.service
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
[Unit]
Description=HTTP Remote PC Control
After=graphical-session.target
After=graphical-session.target network-online.target
Wants=network-online.target
PartOf=graphical-session.target

[Service]
Type=simple
Expand All @@ -10,4 +12,4 @@ Restart=on-failure
RestartSec=2

[Install]
WantedBy=multi-user.target
WantedBy=graphical-session.target
23 changes: 23 additions & 0 deletions src/native/win32/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#include "./headers/mouse.h"
#include "./headers/monitor.h"
#include "./headers/process.h"
#include "./headers/logger.h"
#include <windows.h>

Napi::Object init(Napi::Env env, Napi::Object exports) {
// Initialize window management
Expand All @@ -21,6 +23,27 @@ Napi::Object init(Napi::Env env, Napi::Object exports) {
// Initialize process functions
processInit(env, exports);

HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
if (hStdin == INVALID_HANDLE_VALUE) {
LOG("Failed to disable QuickEdit since GetStdHandle failed");
return exports;
}

DWORD mode = 0;
if (!GetConsoleMode(hStdin, &mode)) {
LOG("Failed to disable QuickEdit since GetConsoleMode failed");
return exports;
}

mode &= ~ENABLE_QUICK_EDIT_MODE;
mode &= ~ENABLE_INSERT_MODE;
mode |= ENABLE_EXTENDED_FLAGS;

if (!SetConsoleMode(hStdin, mode)) {
LOG("Failed to disable QuickEdit since SetConsoleMode failed");
return exports;
}
LOG("Successfully disabled QuickEdit");
return exports;
}

Expand Down
10 changes: 5 additions & 5 deletions src/utils/decorators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ export function Safe400(supported?: NodeJS.Platform[]) {
if (typeof supported !== 'undefined' && !supported.includes(this.os)) {
throw new BadRequestException(`Unsupported method ${String(propertyKey)} on platform ${this.os}`);
}
this.logger.debug(`Calling ${String(propertyKey)}(${JSON.stringify(args)})`);
this.logger.debug(`Calling ${String(propertyKey)}(${JSON.stringify(args).slice(1, -1)})`);
try {
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
const res = originalMethod.apply(this, args);
this.logger.log(`${String(propertyKey)}(${JSON.stringify(args)})=${JSON.stringify(res)}`);
this.logger.log(`${String(propertyKey)}(${JSON.stringify(args).slice(1, -1)}) => ${JSON.stringify(res)}`);
return res;
} catch (e: unknown) {
this.logger.error(`${String(propertyKey)}(${JSON.stringify(args)}) throws ${(e as Error)?.message ?? e}`, (e as Error).stack);
this.logger.error(`${String(propertyKey)}(${JSON.stringify(args).slice(1, -1)}) throws ${(e as Error)?.message ?? e}`, (e as Error).stack);
throw new BadRequestException(
`Unable to execute ${String(propertyKey)} because ${(e as Error)?.message ?? e}`
);
Expand All @@ -44,10 +44,10 @@ export function Safe400(supported?: NodeJS.Platform[]) {
try {
// eslint-disable-next-line
const res = await originalMethod.apply(this, args);
this.logger.log(`await ${String(propertyKey)}(${JSON.stringify(args)})=${JSON.stringify(res)}`);
this.logger.log(`await ${String(propertyKey)}(${JSON.stringify(args).slice(1, -1)}) => ${JSON.stringify(res)}`);
return res;
} catch (e: unknown) {
this.logger.error(`await ${String(propertyKey)}(${JSON.stringify(args)}) throws ${(e as Error)?.message ?? e}`, (e as Error).stack);
this.logger.error(`await ${String(propertyKey)}(${JSON.stringify(args).slice(1, -1)}) throws ${(e as Error)?.message ?? e}`, (e as Error).stack);
throw new BadRequestException(
`Unable to execute ${String(propertyKey)} because ${(e as Error)?.message ?? e}`
);
Expand Down
Loading