Skip to content

Commit 37207b0

Browse files
authored
Merge pull request #9 from SOORAJTS2001/feat/add-documentation
Feat/add documentation
2 parents f6bb50e + b9c73b8 commit 37207b0

12 files changed

+245
-0
lines changed

README.md

Lines changed: 245 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,245 @@
1+
# Misclick <img src="browser_extension/static/misclick_with_mouse_transparent.png" alt="Misclick Logo" width="80" align="right"/>
2+
3+
<p align="center">
4+
<img src="mobile_page/static/mouse_pointer.png" alt="Mouse Pointer"/>
5+
</p>
6+
<p align="center">"<b>Wrong mouse, for a reason</b>"</p>
7+
<p align="center">
8+
<!-- Stars -->
9+
<img src="https://img.shields.io/github/stars/SOORAJTS2001/daring-daffodils?style=for-the-badge" alt="GitHub Stars"/>
10+
11+
<!-- Forks -->
12+
<img src="https://img.shields.io/github/forks/SOORAJTS2001/daring-daffodils?style=for-the-badge" alt="GitHub Forks"/>
13+
14+
<!-- Issues -->
15+
<img src="https://img.shields.io/github/issues/SOORAJTS2001/daring-daffodils?style=for-the-badge" alt="GitHub Issues"/>
16+
17+
<!-- License -->
18+
<img src="https://img.shields.io/github/license/SOORAJTS2001/daring-daffodils?style=for-the-badge" alt="GitHub License"/>
19+
</p>
20+
Sure, you have a perfectly good keyboard and mouse… but why not run Python in your browser with a mobile?
21+
What about doing a scroll, drag and maybe a click or that's all ?
22+
23+
That is Misclick - A way to control your mouse, **but in opposite way**
24+
25+
---
26+
27+
## 📑 Table of Contents
28+
29+
- [What can it do](#what-can-it-do)
30+
- [How to install](#how-to-install)
31+
- [How to use](#how-to-use)
32+
- [How it is working](#how-it-is-working)
33+
- [Limitations](#limitations)
34+
35+
---
36+
37+
## What can it do
38+
39+
- Oh, just casually pair your phone with your browser over WebSocket — because Bluetooth and USB are *too mainstream*.
40+
- Control your browser’s mouse with your phone, but in reverse. Yes, swipe left to go right. Because logic is overrated.
41+
- What’s on the menu?
42+
- Swipe left, swipe right — like Tinder, but for your cursor.
43+
- Swipe up or swipe down.
44+
- Click links and sections — basically what your mouse already does, but now slower and more annoying.
45+
- Scroll up, scroll down — congratulations, you’ve invented scrolling.
46+
- Feeling idle? Don’t worry, the mouse entertains itself with *modes*:
47+
- **Wander Mode** – your cursor takes itself on a joyride. You’re just a spectator.
48+
- **Rage Mode** – because why not double the speed and lose control even faster?
49+
- **Shadow Mode** – cursor goes invisible. Perfect for when you *really* want to rage-quit.
50+
- Sometimes you get all of them combined, so best of luck.
51+
- Bonus: it randomly clicks on stuff, so enjoy your surprise shopping carts and unexpected **easter eggs**.
52+
- If you get redirected to another page, don’t worry — the chaos restarts automatically.
53+
- **Drag text from your browser and send it to your phone. Groundbreaking. Nobel-worthy.**
54+
- Install it as a browser extension, and enjoy the privilege of also opening a webpage on your phone. Wow.
55+
- Cross-platform. Yes, it works everywhere, so nobody is safe.
56+
- Runs locally, no hosting, no leaks — except your sanity.
57+
- No accounts, no personal info — because who would *willingly* sign up for this anyway?
58+
59+
---
60+
61+
## How to install
62+
63+
### Prerequisites
64+
65+
- Python 3.12+
66+
- A modern web browser (Chrome recommended)
67+
68+
### Steps
69+
70+
1. Clone the repository:
71+
```bash
72+
git clone https://github.com/SOORAJTS2001/daring-daffodils
73+
cd daring-daffodils
74+
2. Installing Extension
75+
1. Open [chrome://extensions/](chrome://extensions/) and enable **Developer mode** as shown below:
76+
77+
![Enable Developer Mode](./documentation/browser_developer_mode.png)
78+
2. Click Load unpacked button and select
79+
the [browser_extension](https://github.com/SOORAJTS2001/daring-daffodils/tree/main/browser_extension) folder
80+
inside
81+
the **cloned repo**
82+
![Enable Developer Mode](./documentation/load_unpacked_button.png)
83+
3. Starting up server — **Make sure your PC/Laptop and phone are connected via the same WiFi**
84+
85+
1. Option 1: Using [Makefile](https://en.wikipedia.org/wiki/Make_(software))
86+
1. Just run the command:
87+
- Linux/MacOS
88+
```bash
89+
make
90+
```
91+
- Windows
92+
- By default, Windows does not include GNU Make. Install via [this](https://www.msys2.org/)
93+
```bash
94+
make
95+
```
96+
inside the root directory, where the `Makefile` is located.
97+
2. Option 2: Manual setup
98+
1. Create your environment:
99+
```bash
100+
python3 -m venv .env
101+
```
102+
2. Activate it:
103+
- Linux/MacOS
104+
```bash
105+
source .env/bin/activate
106+
```
107+
- Windows
108+
```bash
109+
.env\Scripts\Activate.ps1
110+
```
111+
3. Install Poetry:
112+
```bash
113+
pip install poetry
114+
```
115+
4. Install dependencies:
116+
```bash
117+
poetry install
118+
```
119+
5. Start the server
120+
```bash
121+
python3 app.py
122+
```
123+
3. After the server starts, it will show you a QR
124+
code. [Open that with your phone](https://www.android.com/articles/how-do-you-scan-qr-codes-on-android/)
125+
<p align="center">
126+
<img src="documentation/server_qr_code.png" alt="Mouse Pointer"/>
127+
</p>
128+
129+
## How to use
130+
131+
<table align="center">
132+
<tr>
133+
<td align="center">
134+
<img src="documentation/mobile_page.png" alt="Mobile Page" width="300"/><br/>
135+
<b>Mobile page</b>
136+
</td>
137+
<td align="center">
138+
<img src="documentation/activating_extension.gif"
139+
alt="Activating Browser Extension" width="600"/><br/>
140+
<b>Browser extension</b>
141+
</td>
142+
</tr>
143+
<tr>
144+
<td align="center">
145+
<img src="documentation/misclick_intro.gif" alt="Browser extension - Basic movement" width="300"/><br/>
146+
<b>Browser extension - Basic movement</b>
147+
</td>
148+
<td align="center">
149+
<img src="documentation/misclick_mode.gif" alt="Browser extension - Mode Activation" width="300"/><br/>
150+
<b>Browser extension - Mode Activation</b>
151+
</td>
152+
</tr>
153+
<tr>
154+
<td align="center">
155+
<img src="documentation/browser_selection.png" alt="Browser extension - Selection" width="300"/><br/>
156+
<b>Browser extension - Selection</b>
157+
</td>
158+
<td align="center">
159+
<img src="documentation/mobile_send.png"
160+
alt="Received by phone" width="300" height="500"/><br/>
161+
<b>Text Received by phone</b>
162+
</td>
163+
</tr>
164+
</table>
165+
<p align="center">
166+
<img src="documentation/utils_not_found_error.png" alt="Mouse Pointer"/>
167+
</p>
168+
169+
**⚠️ If you see an error like above**
170+
or the mouse is not showing up:
171+
172+
- Hard refresh the page
173+
- Restart the server
174+
175+
## How it is working
176+
177+
### Architecture Diagram
178+
179+
<p align="center">
180+
<img src="documentation/architecture.png" alt="Mouse Pointer"/>
181+
</p>
182+
183+
### Tech used
184+
185+
- Pyscript/pyodide for rendering UI
186+
- `fastapi` for serving static pages and as a websocket server
187+
- `qrcode` library for generating url for mobile page
188+
- `pyodide` wrapper js to setup runtime for python in browser extension
189+
190+
### Working
191+
192+
<b>The backend is bind to the port `8000`</b>
193+
194+
#### Mobile page
195+
196+
- Once server is up, the mobile page url is shown in the terminal
197+
- On opening the mobile page, the websocket connection between the server and the frontend is established via pyscript
198+
- Inside the `mobile_page.py` it calls the Javascript native API's using pyodide/pyscript and manipulates the DOM
199+
- We have eventListeners in js, which is used for listen and trigger to user events like drag, scroll and click
200+
- We are having a proxy between the js and python for object and function transfer as
201+
explained [here](https://jeff.glass/post/pyscript-why-create-proxy/)
202+
- For every js `touchstart` event we would record it, until it ends with `touchend` and send the <b>change ratio</b>
203+
rather than coordinates via
204+
websocket to the browser
205+
206+
#### Browser extension - This is where magic happens
207+
208+
- By default, Chrome extensions cannot load remote code (JS, WASM, CSS) from CDNs because of Content Security Policy (
209+
CSP).
210+
- Hence we had to package the runtime scripts for python inside the browser, which is
211+
this [runtime](https://github.com/SOORAJTS2001/daring-daffodils/tree/main/browser_extension/runtime)
212+
- Instead of making the entire extension in python which is very very hard (due to support),we are just injecting our
213+
python files and
214+
it's dependency into every website
215+
- Upon activating (by default it has access to all web pages) it connects to our python web socket server, and
216+
shows <img src="mobile_page/static/mouse_pointer.png" alt="Mouse Pointer" height="20px"/> which turns-out to be your
217+
new cursor!
218+
- When a `delta` is received from the mobile page, it is rescaled to match the browser’s dimensions and projected onto the browser. This causes the cursor to move according to the user’s interaction.
219+
- It would get the type of event's user has sent like scroll, drag, selection and corresponding actions are performed
220+
221+
##### Clicks
222+
223+
- if a click is fired from the user side, then a `MouseEvent` is fired on browser
224+
##### Drag
225+
- Tap for 300ms and scroll is considered as the Drag
226+
##### Selection
227+
- It could send user selected text to their connected phone
228+
- Defines a rectangle using the given screen coordinates (x1, y1) and (x2, y2).
229+
- Walks through all text nodes in the document body.
230+
- For each text node, checks whether any part of its bounding client rect intersects with the defined rectangle.
231+
- If overlapping text is found:
232+
- Collects and returns the text content (whitespace-trimmed).
233+
- Visually highlights the region by overlaying a semi-transparent blue box.
234+
- The highlight box automatically disappears after 2 seconds.
235+
236+
***You may have noticed that a significant part of our project is shown as JavaScript. This is because the Python runtime in the browser extension relies on JavaScript to bootstrap and interact with WebAssembly.
237+
It mainly involves two key files:***
238+
239+
- **`pyodide.asm.js`** – Emscripten-generated “glue code” that initializes the WebAssembly (`.wasm`) binary and connects it to the browser’s JavaScript environment.
240+
- **`pyscript.js`** – JavaScript glue for PyScript. It integrates Pyodide with HTML elements like `<py-script>` and `<py-repl>`, enabling inline Python execution inside web pages or extensions.
241+
242+
***Since extensions cannot load executable code directly from the internet (for security reasons), we had to package these files locally instead of relying on CDNs.***
243+
244+
## Limitations
245+
Sometimes the extension could not be used inside sites and restricts script injection, it will throw an error
963 KB
Loading

documentation/architecture.png

363 KB
Loading
12.8 KB
Loading
1.23 MB
Loading
14.5 KB
Loading

documentation/misclick_intro.gif

9.19 MB
Loading

documentation/misclick_mode.gif

5.96 MB
Loading

documentation/mobile_page.png

3.14 MB
Loading

documentation/mobile_send.png

631 KB
Loading

0 commit comments

Comments
 (0)