Skip to content
Closed
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
88 changes: 77 additions & 11 deletions INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ python --version
</td>
<td align="center" width="25%">

**🪟 Windows 10/11**
**🪟 Windows 10/11** or **🍎 macOS**
```bash
node --version
# Check your OS
uname -s
```

</td>
Expand All @@ -43,17 +44,48 @@ git --version
</div>


### Quick Setup
### Quick Setup (Windows)

1. Clone the repository :
```bash
1. Clone the repository :
```bash
git clone https://github.com/MLSAKIIT/pixly.git
cd pixly
```
2. Open a powershell terminal as administrator and run the setup.bat file.
```bash
.\setup.bat
```

### macOS Setup

#### Prerequisites: CustomTkinter Support

Pixly uses CustomTkinter for the GUI overlay, which requires the underlying Tkinter library to be available in your Python installation. If you're using `pyenv`, you need to install Python with Tkinter support:

1. **Install tcl-tk via Homebrew**:
```bash
brew install tcl-tk
```

2. **Reinstall Python 3.11+ with Tkinter support**:
```bash
export PATH="/opt/homebrew/opt/tcl-tk/bin:$PATH"
export LDFLAGS="-L/opt/homebrew/opt/tcl-tk/lib"
export CPPFLAGS="-I/opt/homebrew/opt/tcl-tk/include"
export PKG_CONFIG_PATH="/opt/homebrew/opt/tcl-tk/lib/pkgconfig"
export PYTHON_CONFIGURE_OPTS="--with-tcltk-includes='-I/opt/homebrew/opt/tcl-tk/include' --with-tcltk-libs='-L/opt/homebrew/opt/tcl-tk/lib -ltcl9.0 -ltk9.0'"

pyenv install 3.11.7 --force
```

3. **Verify the underlying Tkinter library is working**:
```bash
python3 -m tkinter
```
If a small window appears, Tkinter is working correctly and CustomTkinter will be able to use it!

4. **Continue with Manual Setup below**

### Manual Setup
1. Clone the repository :
```bash
Expand All @@ -80,26 +112,60 @@ GEMINI_API_KEY=your_gemini_key_here

1. Make a folder called `vector_db`

2. Start the application, Create two powershell terminals
2. Start the application

**On Windows** - Create two PowerShell terminals:

Terminal 1 - Start Backend:
```bash
uv run run.py
```
Wait for the backend to start then in Terminal 2 - Start Frontend:
```bash
```bash
uv run overlay.py
```

## Debugging
**On macOS** - Create two terminal windows:

Terminal 1 - Start Backend:
```bash
uv run run.py
```
Wait for the backend to start then in Terminal 2 - Start Frontend:
```bash
uv run overlay.py
```

## Troubleshooting

### macOS: "ModuleNotFoundError: No module named '_tkinter'"

This error occurs when Python doesn't have the underlying Tkinter library, which is required for CustomTkinter to function. Follow the **macOS Setup** section above to reinstall Python with Tkinter support.

Quick fix:
```bash
brew install python-tk@3.11
# Then reinstall dependencies
uv sync
```

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

159-166 is not required

### macOS: Platform-specific dependencies

The project automatically installs platform-specific dependencies:
- **Windows**: `pywin32` for window detection
- **macOS**: `pyobjc-framework-Quartz` for window detection

No manual intervention needed - `uv sync` handles this automatically!

## Debugging

To test the various parts of the backend pipeline :
To test the various parts of the backend pipeline:

1. Start the server in Terminal 1 :
1. Start the server in Terminal 1:
```bash
uv run run.py
```
1. Start the test script in Terminal 2 :
2. Start the test script in Terminal 2:
```bash
uv run test_system.py
```
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ dependencies = [
"pillow>=10.0.0",
"dotenv>=0.9.9",
"psutil>=5.9.0",
"pywin32>=306",
"pywin32>=306; sys_platform == 'win32'",
"pyobjc-framework-Quartz>=10.0; sys_platform == 'darwin'",
"cryptography>=41.0.0",
"chromadb>=0.4.0",
"sentence-transformers>=2.2.2",
Expand Down
97 changes: 76 additions & 21 deletions services/screenshot.py
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

keep these changes

Original file line number Diff line number Diff line change
@@ -1,15 +1,29 @@
import os
import sys
import sqlite3
import hashlib
from datetime import datetime
import threading
import time
import psutil
import win32gui
import win32process
from PIL import ImageGrab
from cryptography.fernet import Fernet

# Platform-specific imports
if sys.platform == 'win32':
import win32gui
import win32process
elif sys.platform == 'darwin':
try:
from Quartz import (
CGWindowListCopyWindowInfo,
kCGWindowListOptionOnScreenOnly,
kCGNullWindowID
)
from AppKit import NSWorkspace
except ImportError:
print("Warning: pyobjc-framework-Quartz not installed. Window detection will be limited on macOS.")

class ScreenshotCapture:
def __init__(self, db_path="screenshots.db", interval=30):
"""
Expand Down Expand Up @@ -74,27 +88,68 @@ def _init_database(self):
def _get_active_window_info(self):
"""Get information about the currently active window."""
try:
# Get the active window
hwnd = win32gui.GetForegroundWindow()
window_title = win32gui.GetWindowText(hwnd)

# Get process information
_, pid = win32process.GetWindowThreadProcessId(hwnd)
process = psutil.Process(pid)
application = process.name()

return {
'application': application,
'window_title': window_title,
'pid': pid
}
if sys.platform == 'win32':
return self._get_active_window_info_windows()
elif sys.platform == 'darwin':
return self._get_active_window_info_macos()
else:
return self._get_default_window_info()
except Exception as e:
print(f"Error getting window info: {e}")
return {
'application': 'Unknown',
'window_title': 'Unknown',
'pid': 0
}
return self._get_default_window_info()

def _get_active_window_info_windows(self):
"""Get active window info on Windows."""
hwnd = win32gui.GetForegroundWindow()
window_title = win32gui.GetWindowText(hwnd)

# Get process information
_, pid = win32process.GetWindowThreadProcessId(hwnd)
process = psutil.Process(pid)
application = process.name()

return {
'application': application,
'window_title': window_title,
'pid': pid
}

def _get_active_window_info_macos(self):
"""Get active window info on macOS."""
workspace = NSWorkspace.sharedWorkspace()
active_app = workspace.activeApplication()

application = active_app['NSApplicationName']
pid = active_app['NSApplicationProcessIdentifier']

# Get window title from window list
window_title = 'Unknown'
try:
window_list = CGWindowListCopyWindowInfo(
kCGWindowListOptionOnScreenOnly,
kCGNullWindowID
)
for window in window_list:
if window.get('kCGWindowOwnerPID') == pid:
window_title = window.get('kCGWindowName', 'Unknown')
if window_title and window_title != 'Unknown':
break
except Exception as e:
print(f"Error getting window title: {e}")

return {
'application': application,
'window_title': window_title,
'pid': pid
}

def _get_default_window_info(self):
"""Return default window info when platform detection fails."""
return {
'application': 'Unknown',
'window_title': 'Unknown',
'pid': 0
}

def _capture_screenshot(self):
"""Capture a screenshot and return the image data."""
Expand Down
Loading
Loading