pax_global_header 0000666 0000000 0000000 00000000064 14735252137 0014523 g ustar 00root root 0000000 0000000 52 comment=7e9babdc79d7eeba8ca80e5279b01521135d6396
Solaar-1.1.14/ 0000775 0000000 0000000 00000000000 14735252137 0013030 5 ustar 00root root 0000000 0000000 Solaar-1.1.14/.coveragerc 0000664 0000000 0000000 00000000427 14735252137 0015154 0 ustar 00root root 0000000 0000000 [run]
branch = True
source =
hid_parser
hidapi
keysyms
logitech_receiver
solaar
omit =
*/tests/*
*/setup.py
*/__main__.py
[report]
exclude_lines =
pragma: no cover
if __name__ == '__main__':
if typing.TYPE_CHECKING
fail_under = 40
Solaar-1.1.14/.git-blame-ignore-revs 0000664 0000000 0000000 00000000466 14735252137 0017136 0 ustar 00root root 0000000 0000000 # yapf bulk change
72a8d311bce64b1536c08e754d22bb91efb66460
# isort bulk change
e6369e0c3c240715a0a2daede6c3b225ed63cf60
# pre-commit bulk change
33521558ed7007c24b24127f1448c2c23ecbfb35
# flake8 bulk change
627185079f65c9cc471194b7927c833682e4a7a3
# yapf style update
27c90fa736d8a7a1ef6acda4345d3599862e185c
Solaar-1.1.14/.github/ 0000775 0000000 0000000 00000000000 14735252137 0014370 5 ustar 00root root 0000000 0000000 Solaar-1.1.14/.github/ISSUE_TEMPLATE/ 0000775 0000000 0000000 00000000000 14735252137 0016553 5 ustar 00root root 0000000 0000000 Solaar-1.1.14/.github/ISSUE_TEMPLATE/bug_report.md 0000664 0000000 0000000 00000003215 14735252137 0021246 0 ustar 00root root 0000000 0000000 ---
name: Bug report
about: Create a report to help us improve
title: ''
labels: bug
assignees: ''
---
**Information**
- Solaar version (`solaar --version` or `git describe --tags` if cloned from this repository):
- Distribution:
- Kernel version (ex. `uname -srmo`): `KERNEL VERSION HERE`
- Output of `solaar show`:
```
SOLAAR SHOW OUTPUT HERE
```
- Contents of `~/.config/solaar/config.yaml` (or `~/.config/solaar/config.json` if `~/.config/solaar/config.yaml` not present):
```
CONTENTS HERE
```
- Errors or warrnings from Solaar:
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Additional context**
Add any other context about the problem here.
Solaar-1.1.14/.github/ISSUE_TEMPLATE/feature_request.md 0000664 0000000 0000000 00000001745 14735252137 0022307 0 ustar 00root root 0000000 0000000 ---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: enhancement
assignees: ''
---
**Information**
- Solaar version (`solaar --version` and `git describe --tags`):
- Distribution:
- Kernel version (ex. `uname -srmo`):
- Output of `solaar show` for the target device (if applicable):
```
OUTPUT HERE
```
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.
Solaar-1.1.14/.github/workflows/ 0000775 0000000 0000000 00000000000 14735252137 0016425 5 ustar 00root root 0000000 0000000 Solaar-1.1.14/.github/workflows/checks.yml 0000664 0000000 0000000 00000000427 14735252137 0020413 0 ustar 00root root 0000000 0000000 name: checks
on: [push, pull_request]
jobs:
pre-commit:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
- name: Run pre-commit
uses: pre-commit/action@v3.0.0
Solaar-1.1.14/.github/workflows/gh-pages.yml 0000664 0000000 0000000 00000001756 14735252137 0020654 0 ustar 00root root 0000000 0000000 name: Deploy to GitHub Pages
on:
push:
branches:
- master
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: 'pages'
cancel-in-progress: false
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Install dependencies
run: |
pip install mkdocs mkdocs-rtd-dropdown mkdocs-mermaid2-plugin mkdocstrings[python]
- name: Build and deploy
run: |
mkdocs build
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: 'site'
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
Solaar-1.1.14/.github/workflows/tests.yml 0000664 0000000 0000000 00000003640 14735252137 0020315 0 ustar 00root root 0000000 0000000 name: tests
on: [push, pull_request]
jobs:
ubuntu-tests:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.8, 3.12]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install Ubuntu dependencies
run: |
make install_apt
- name: Install Python dependencies
run: |
make install_pip PIP_ARGS='.["test"]'
- name: Run tests on Ubuntu
run: |
make test
- name: Upload coverage to Codecov
if: github.ref == 'refs/heads/master'
uses: codecov/codecov-action@v4.5.0
with:
directory: ./coverage/reports/
env_vars: OS, PYTHON
files: ./coverage.xml
flags: unittests
name: codecov-umbrella
token: ${{ secrets.CODECOV_TOKEN }}
macos-tests:
runs-on: macos-latest
strategy:
matrix:
python-version: [3.8, 3.12]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Set up macOS dependencies
run: |
make install_brew
- name: Install Python dependencies
run: |
make install_pip PIP_ARGS='.["test"]'
- name: Run tests on macOS
run: |
export DYLD_LIBRARY_PATH=$(brew --prefix hidapi)/lib:$DYLD_LIBRARY_PATH && pytest --cov --cov-report=xml
- name: Upload coverage to Codecov
if: github.ref == 'refs/heads/master'
uses: codecov/codecov-action@v4.5.0
with:
directory: ./coverage/reports/
env_vars: OS, PYTHON
files: ./coverage.xml
flags: unittests
name: codecov-umbrella
token: ${{ secrets.CODECOV_TOKEN }}
Solaar-1.1.14/.gitignore 0000664 0000000 0000000 00000000360 14735252137 0015017 0 ustar 00root root 0000000 0000000 *.pyc
*.pyo
__pycache__/
*.log
*.mo
/lib/Solaar.egg-info/
/lib/solaar.egg-info/
/lib/solaar/commit
/build/
/sdist/
/dist/
/deb_dist/
/MANIFEST
.coverage
/htmlcov/
/docs/captures/
/share/logitech_icons/
/share/locale/
/po/*.po~
/.idea/
Solaar-1.1.14/.pre-commit-config.yaml 0000664 0000000 0000000 00000000731 14735252137 0017312 0 ustar 00root root 0000000 0000000 repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.3.0
hooks:
- id: check-ast
- id: check-builtin-literals
- id: check-merge-conflict
- id: check-yaml
- id: check-toml
- id: debug-statements
- id: end-of-file-fixer
- id: trailing-whitespace
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.2.2
hooks:
- id: ruff
name: ruff lint
args: [--fix, --exit-non-zero-on-fix]
- id: ruff-format
name: ruff format
Solaar-1.1.14/.python-version 0000664 0000000 0000000 00000000005 14735252137 0016030 0 ustar 00root root 0000000 0000000 3.11
Solaar-1.1.14/CHANGELOG.md 0000664 0000000 0000000 00000114472 14735252137 0014652 0 ustar 00root root 0000000 0000000 # 1.1.14
* Handle fake feature enums in show
* Fix battery entries in config.yaml
* Add ratchet setting for smart shift enhanced devices
* Refactor Gesture into enum
* Replace ERROR NamedInts by IntEnum (#2645)
* Refactor hidpp20 to use enum
* Update Polish, Swedish, Norwegian Nynorsk (nn), and Norwegian Bokmål (nb) translations
* Use IntEnum for firmware and cidgroup constances
* Change pairing error values to intenums
* Fix initialization bug for PackedRangeControl
* Add tests for feature class, process_notification, and key_is_down
* Check all bits for extended report rate
* Add type hints
* Improve about dialog
* Reduce dependencies
* Refactor code
* Improve testing
* Allow unknown keys in Key rule conditions
* Improve documentation for cli actions
* Cycle sw_id to better guard against duplication of messages
* Handle error return on root feature
* Clean up documentation
* Improve github interactions
* Add information about Onboard Profiles overriding some settings
* Add wording to README.md that Solaar is not a device driver
* Clean up imports
* Handle unknown device kinds
* Fix broken links to Solaar logo
* Use mkdocs for public documentation
* Clean up setup.py
* Remove Dead links in the AppStream file
* Update about.py
* Remove check on driver
* Improve base module
* Remove unnecessary receiver info 'hid_driver'
* Convert HIDPPNotification to dataclass
* Be defensive when converting battery status to string
* Automatically detect packages in /lib
* Clean up locale code
* Improve rules documentation
* Refactor creation of devices
* Add headings to structure rules.md
* Unify imports in logitech package
* Don't ping device when getting name or codename
* Use dataclasses and enums where useful
* Introduce Device protocol and type hints
* Add typing_extensions dependency
* Move hidpp10 independent functions to module level
* Fix macOS compatibility and reenable CI tests
* Unify imports in hidapi package
* Move screenshots into dedicated folder and add high-level graph of components
* Update French and Chinese translations
* Drop support for end-of-life Python 3.7
# 1.1.13
* Update Polish and Russian translations.
* Fix bug in suspend and resume callback
* Add choices universe for backlight setting
* Add simplify diversion.py and add unit tests
* Get and use current host number for K375sFnSwap because of bug in firmware of MX Keys S
* Fix bug with logo in about window
* Don't ping device just to get logging information
* Optimize write for per-key lighting
* Add and initialize per-key lighting to a special no-change value
* Remove some Python 2 compatibility code
* Update French translation
* Refactor rule loading for testability
# 1.1.12
* Check for existence of keys file before opening
* Perform translation for all translatable strings.
* Add included hid_parser to packages installed
* Improve label and description for LED zone settings
* Add message about Onboard Profiles to LED Zone settings
* Initialize device registers to empty list
* Use bluez dbus signals to disconnect and connect bluetooth devices
* Handle a different signal for onboard profiles directory in ROM
* Introduce small delay in getting pairing information to let receiver settle after pairing
* Improve testing for settings_templates, settings, hidpp20, and device and fix small bugs found
* Add extended adjustable DPI setting
* Improve and extend infrastructure for testing setting_templates
* Update Greek, Polish, Russian, and Traditional Chinese translations
* Implement and test per-key lighting
* Refactor and test pair_window in GUI
* Handle situation when read of a setting fails in GUI
* Permit continuing when a read during pushing fails
* Fix bug in LEDZoneSetting when effect is not implemented
* Add tests for LEDEffect structures in hidpp20
* Handle BRIGHTNESS_CONTROL notifications
* Add settings for BRIGHTNESS_CONTROL and RGB_EFFECTS features
* Fix small bugs found from testing in settings
* Use f-strings for more exceptions and log message
* Tests for setting_templates
* Simple change in settings to improve testability
* Use feature_request from the device everywhere in hidpp20
* Fix bug in backlight 2 durations
* Replace deprecated code constructs
* Set up test data and classes to help test HID++ interactions
* Use pytest to test code for logitech_receiver modules
* Align init methods for all receiver classes
* Start refactoring of code base
* Allow sub-second delays in Later
* Fix bug in setting configuration cookie due to bad documentation
* Use ruff for code styling and linting
* Upgrade string formating to f-string
* Document battery-icons=solaar option
* Tell devices to delay device sending first messages until configuration is done
* Optimize some functions in FeaturesArray
* Fix bug in creating features array
* Fix bug in building battery line in show
* Refactor diversion_rules
* Fix bug in determining tray icon
* Fix bug in getting friendly name
* Move status information to Device and Receiver objects
* Add tests for get_kind_from_index and base product information
* Update EX100 documentation
* Use object attributes instead of dictionary in status objects
* Create subclasses of receiver for different variants
* Add requirement for CONFIG_HIDRAW to documentation
* Add some low-level tests for some hidpp20 functions, profiles, and lighting and some hidpp10 tests
* Fix app name casing in UI
* Add missing receiver type for Lightspeed receivers
* Add new device types
* Refactor device and receiver instantiation
* Simplify naming of distribution files
* Clean up some logging code
* Remove duplicated code to read register
* Introduce Hidpp20 and Hidpp10 class
* Remove unnecessary calls of del
* Fix bug when reading BACKLIGHT setting from device
* Replace invalid hidpp10 and hidpp20 usages
* Use only timer thread to save config.yaml
* Improve README
* Copy newer version of hid_parser
* Reorder code in settings
* Update installation documentation
* Add missing license blocks
* Clean up listener and notifications code
* Add locks to prevent multiple persisters for device
* Clean up configuration, device, and receiver code
* Move battery constants common to HID++ 1.0 and 2.0 to common
* Move mapping of device kind into hidpp20
* Move pairing information gathering to receiver
* update contributors
* Expand allowable profile numbers
* Clean up __init__ in logitech_receiver
* Modify pre-commit args to make ruff change files
* Fix bug in hidpp20 get host names
* Use ruff for formatting and linting
* Fix bug in rule Set action
* Add notify module to logitech_receiver
* Implement setting_changed callback and pass in to new devices and receivers
* Add callback to call when changing a setting
* Move exceptions, hidpp20 and hidpp10 constants into new modules
* Streamline status code
* Upgrade debugging in udev
* Fix deprecated GitHub actions
* Extend makefile and tests
* Improve features array
* Move ui_async to common.py
* Improve module imports
* Add tests of common module
# 1.1.11
* Rename light icons and install them in correct place
* Setup macOS tests using GitHub action (#2284)
* Better checking for setting in record_setting
* Fix invalid func name set logo name
* Simplify installation of udev rules
* Add document on implementation
* Tidy up scrolling appearance in configuration panel
* Correctly handle profile button with no action
* Don't unlock setting when changed by external means
* Refactor code to record change to setting
* Add GitHub action for tests
* Introduce tests with pytest
* Simplify logger instantiation
* Update label and tooltip for divert-gkeys setting
* Don't lock setting when an error occurs
* Catch assertion errors when reading setting values from devices
* Support LED Zone control feature
* Dump and load device profiles
* Select among profiles.
* Support backlight levels and duration
* Use "Report Rate" instead of "Polling" for movement report rate
* Support extended report rate setting
* Add stable branch to release.sh (#2236)
* Fix changelog parsing in release.sh
* Update installation.md with new udev rules location
* Downgrade assertion on missing notification flag to warning
* Write empty file if there are no rules to save
* Be defensive in device error messages
* Add descriptions of M650, PRO X 2, G915, MX Anywhere 2S, G305, and MX Keys S
* Report hidraw node in debugging messages
* Add names for new Logitech features
* Update Spanish, French, and Polish translations
* Defend against lightspeed receivers that contact devices for basic information
* Remove incorrect feature for M325 mice
* Add K845 keyboard
* Add partial support for macOS and minimal support for Windows
* Correctly enumerate devices on receiver
* Add wording in documentation about Logitech reusing model numbers
* Better handling and installation of icons
* Catch errors when pinging to try to put device online
* Be more cautious when creating log messages to avoid exceptions
* Correctly handle NoSuchDevice exception when pinging device
* Fix test in rules for device equality
* Add installation instructions for pipx and add not about other GTK system packages
* Fix bug in NamedInt
* Add support for MK550
* Install udev rule files to correct placces
* Expand expected ping responses
* Update codename when device status changes
# 1.1.10
* Add information about NixOS flake package
* Permit bluetooth devices in hidconsole
* Add descriptor for Logitech MX Revolution Mouse M-RCL 124
* Improve determination for short and long messages
* Add descriptor for G500s
* Fix bug in scan-registers
* Add single depress and release options for rule mouse click action
* Add rule condition for hostname
* Update keysym generation to current list of keysyms
* Allow device 0 in hidconsole
* Upgrade messages when no supported device found
* Documentation update for the gnome extension for better Solaar rule support
* Remove udev-acl tag from udev rules
* Add support for process condition in Wayland
* Update French, Chinese, and German translations
* Add G733 Headset
* Restore tools/clean.sh
* Add Bluetooth Keyboard C714
* Update several device descriptions
* Update scan-registers.sh
* Remove assertion on last byte of ping responses
* Add symbolic version of solaar icon
* Fix bug when finding name or codename
* Update documentation
* Put version in initial INFO logging message
# 1.1.9
* Add descriptors for G535 wireless gaming headset and wireless keyboard EX110
* Update Greek translation
* Fix minor issues in documentation
* Remove some deprecated GTK code
* Use zero exit code for kill interrupts
* Add rule Test condition for battery charging
* Get wpid for 28Mz devices from udev when enumerating
* Add Device condition to rules
* Don't show wireless link or battery information when unknown or not present
* Add desccriptor for G9x and LX7 mice
* Fix bug in determining kind of devices for 27Mz receivers
* Set initial lock status of smooth scrolling features to ignore
* Fix glitch in configuration file update when changing versions
* Add more debugging output for rules
* Clean up pinging code
* Put initial ping of direct-connected devices inside listener thread
* Read and check before write of range settings
* Improve pairing determination
* Cut off determination of receiver devices when all have been found
* Remove derived configuration fields when Solaar version changes
* Allow device descriptors without name and codename
* Filter and escape technical detail fields
* Add setting for ADC power managemen
* Correctly determine whether to ping with a long HID++ message
* Add description for K470 keyboard from the MK470 combo (#1945)
* Add setting value for mouse gestures
* Update German and French translations
* Remove old clean.sh and monitor.py tools
* Retry opening device if permissions error encountered
* Better handlling of IO errors at device creation
* Add KeyIsDown rule condition to check whether a diverted key is down
* Clean up device and receiver creation
# 1.1.8
* Add parameter to thumb wheel rule conditions
* Rename Serbian translation file
* Update Polish translation
* Improve handling of wheel notifications
* Only record changes of scroll wheel ratchet
* Don't mark setting as absent if there are device errors
* More robust access to keyword exception fields
* Add support for config change feature
* Clean up GTK code
* Update documentation on mouse gestures and known issues
* Get commit information from git describe and dpkg-parsechangelog
* Update pre-commit tools to current versions
* Update installation instructions
* Add 8-character commit hash to version information
* Update solaar.desktop (#1857)
* Get release in setup.py by reading lib/solaar/__init__.py
* Remove version number from docs/_config.yml
* Update solaar.desktop
* Update es.po
* Clarify status of C542 receiver
* Update devices directory
* Add description of several devices
* Show name of disconnecting receiver or device in disconnect warning
* Reduce standard size of rule editor window
* Remove unnecessary dependency on typing_extensions
# 1.1.7
* Add dependency on typing_extension to setup.py
* Don't defer saves in CLI and don't require Gtk in CLI
* Be more permissive in recognizing HID++ report descriptors
* Update Polish and Croatian translations
* Switch scroll ratcheting in response to scroll ratchet button notification
* Add setting to turn scroll ratchet on and off
* Eliminate visual glitch when updating range setting
* Make hid-parser an optional dependency
# 1.1.6
* Only update remaining pairings after successful pairing
* Check for presence of status attribute when resuming
* Update Polish and Croation translations
* Don't add non-existant key in raw xy processing
* Add special keys from MX Mechanical Mini
* Fix processing of HID++ 1.0 battery reports
* Use report descriptors to determine suitable devices
* Handle exceptions when processing configuration file
* Add Logitech PRO Gaming Keyboard
* Fix bad entries in divert-keys when found
* Correctly convert old-style diversions to new style and remove old ones
* Add optional save argument to write_key_value methods
* Use device name in configuration entries if device modelId is zeroes
* Don't show normal DJ messages in debug log
* Add Later rule action
* Correctly record battery feature when ADC produces error
* Print feature call errors in solaar show instead of terminating
* Use ADC notifications to set device inactive and active
* Add one to feature count to count ROOT feature
* Don't check modifiers for KeyPress actions that are not clicks
* Augment comments on what Solaar cannot do
* Fix bug in printing closed handle
* Use only product records to determine which receivers unpair
* Add conditional delay to get around race with Linux HID++ driver
# 1.1.5
* Add G213 Prodigy Gaming Keyboard
* Update Turkish, Croation, and zh_CN translations
* Move old device descriptions to new locations and clean up
* Increase minimum stopped time between mouse movements
* Fix bug with non-recognized empty mouse movement
* Allow config panel to scroll
* Add descriptions for K360 4004, MX Master 4017, Lightspeed C541, and G915 407D
* Change security tooltip for unencrypted wireless connections
* Add Norwegian Bokmal translation
* Update documentation on continuously running GUI, diverted keys, and changing hosts
* Solaar config no longer applies settings
* Add description of rule components to rule editor
* Ignore first movement for mouse gestures when reprog controls version is 5 or more
* Add Active rule condition to test whether a device is active
* Terminate iteration over receiver devices when all have been found
* Downgrade Set prolem messages from error to warning
* Log informational messages and above to a temporary file
* Don't produce warnings when editing rules in rule editor
* Fix bug that didn't save rules file if there were no rules
* Allow devices with connection number larger than max_devices
* Show more registers in solaar probe
* Show feature versions in solaar show
* Fix problems with deleting devices on exit
* Update German translation
* Update device documentation directory
* Add descriptors for G502 Proteus Spectrum Optical Mouse and G935 headset
* Record feature versions
* Add Serbian translation
* Fix circular import in rules
* Keep track of devices and use in rules
* Update zh_CN and zh_TW translations
* Convert old-style mouse gestures and sliding dpi settings to new style
* Allow multiple keys for mouse gestures and sliding dpi
* Defer saving configuration file for a while to cut down on the number if times it is saved
* Use correct functions for unified battery and battery voltage features.
* Add defensive check for missing keys array in mouse gestures setting
* Better presentation of battery information
* Add support for ADC MEASUREMENT battery feature
* Add information on how to find divertable key names in solaar show output
* Better warnings for feature call errors with reprogrammable key and gesture settings
* Increase entry size for ChoiceControlBig
# 1.1.4
* Update Croatian translation
* Handle unanticipated values for persistent remappable action as default
* Improve system tray interface documentation
* Remove blank lines from system tray popup
* Update Polish translation
* Add depress and release options to KeyPress rule action
* Only close existing devices for receiver
* Differentiate debug messages for different setting types
* Implement packed range setting in config panel
* Only produce warning for unimplemented display of setting
* Add sidetone and equalizer settings for headsets
* Add packed ranges setting
* Use built-ins for conversions between int and byte string
* Don't add HI_RES wheel ecodes to evdev device codes
* Handle null key in persistent remappable actions when device does not respond
* Consult polling rate feature for polling rate
* Eliminate extra file handles
* Close file handles for receiver-connected devices
* Access to more keys in KeyPress rule action when in other keyboard groups
* Update Turkish translation
* Put battery levels in tray menu labels
* Reduce warnings for inaccessible keys in KeyPress rule action
* Better determination of keycodes and insert needed shifts in KeyPress actions.
* Be careful when processing notifications for partly set up devices.
* Clear out fields for empty persistent remappable action.
* Fix message generation when device is offline.
* Fix bug in feature lookup.
* Add support for G533 Headset and G502 Gaming Mouse
* Improve device features handling.
* Keep trying settings that have worked in the past.
* Store None in persisters for non-persisting settings.
* Only create configuration entries for off-line devices if they have a serial number.
# 1.1.3
* Update documentation files
* Lower remove python 3.7 constructs and lower python dependency to 3.6
* Fix bug in xtest mouse scrolling
* Allow mouse gesture setting for non-mice, e.g., trackballs
* Print message when there is another Solaar process running
* Fix determination of whether to force read before writing boolean setting
* Add recent diversion features to default list in rules UI
* Add setting to divert hires scroll wheel
* Don't use device kind to determine how to handle notifications
* Update Polish, Russian, and zh_CN translations
* Remove pggettext so as to not require Python 3.8
* Remove Python 2 unicode support
* Store keys in configuration file as int instead of str
* Use yaml for configuration file instead of json.
* Remove process-dependent rules from built-in rules.
* Handle situation where GTK application cannot be set up in CLI.
* Remove obsolete upower signals.
* Appinfo/metadata fixes including using correct APP_ID.
* Fix bugs in solaar config.
* Add full set of mouse buttons in persistent remappable actions setting.
* Improve rule behaviour under Wayland and when Xtest or X11 not available.
* Fix up and document dependencies (evdev, Python, ...).
# 1.1.2
* Update documentation on supported devices and translations
* Include evdev as a dependency
* Try to use uinput for fake input if XTest extension not available
* Add Nano receiver C542 for M190 mice
* Broaden range of HID++ Bluetooth devices
* Add setting to divert gestures
* Rule editor can edit all rule components
* Configuration via solaar config takes effect in Solaar UI if it is running
* Add setting to disable Onboard Profiles and decouple from Polling Rate setting
* Add setting for PERSISTENT_REMAPPABLE_ACTION, common keyboard and mouse cases only
* Split Test rule condition into Test and TestBytes and support in rule editor
* Fix bug in speed-change setting
* Support Backlight3 feature
* Ensure that settings are pushed in resume
* Update German, Polish, and zh_CN translations
* Determine device number for direct-connected devices from protocol
* fix bug in add and delete button actions in rule editor
* dispose of no-op notifications quickly
* add rule condition for checking device settings
* use local file for conversion from key names to keysyms
* get keyboard group and use to get correct keycodes (X11 only)
* improve how rules work under Wayland
* add settings for M-Key LEDs and MR-Key LED
* fix bug in unpacking M and MR key notification
* add G815 keyboard and MX518 mouse
* add new special keys for recent keyboards
* track M and MR keys for use in rules
* make sure that device is online when searching for devices in solaar show
* don't check for device kind in dpi sliding setting
* fix problem with devices that report 0 DPI
* handle missing divert-setting in action RW for settings
* add id property (unitId or serial) and don't use ? for unknown serial
* fix contains for NamedInts and eliminate use of has_element
* check for xtest and disable modifier checking if not available
* improve determination of gesture information
* add Set rules to rule GUI
* add gesture params to Set rules
* hide system tray when there are no devices to control
* add G733 headset, G9 mouse, G502 Hero mouse
* Use greyscale solaar icon in tray when using symbolic icons
* Fix bugs in solaar config
* Use classes for settings to hep with modularity
* Accept '~' and Toggle for toggling boolean settings in cli and rules
* handle errors when writing to devices
* refactor config_panel.py to use classes for widgets
* add rules action to set Solaar settings
* decrease amount of logging at each debug level
* don't stretch toggles in settings
* use key structure for key remapping setting
* optimize ReprogrammableKey implementation
* keep track of settings that are absent from device
* add G512 keyboard and G402 mouse
* reformat descriptors.py
* use feature numbers for reprogrammable key versions
* don't use new_from_icon_set in menu as it is deprecated
# 1.1.1
* Keep left pane in Solaar main window the same size
* Fix crash when checking a process condition when X11 not running
* Add version number to output of solaar show
* Fix crash when pinging a device with unknown protocol
* Display battery percentage estimates from battery voltage
* Add minimal support for Logitech PRO X Wireless Gaming Headset
* Push settings when device requests software reconfiguration
* Fix read for key/button diversion setting
* Add modalias information to Solaar metainfo
* Don't do on-screen notifications when devices are powered on
* Add setting to switch crown between smooth and ratchet scrolling
* Add write_prefix_bytes argument to Boolean validator
* Update Russian and Spanish translations
* New shell script tools to help determine capabilities of receivers
* Add special keys for MX Keys for Business and MX Keys Mini
* Improve tray menu ordering
* Add --tray-icon-size option to get around bugs in some tray implementations
# 1.1.0
* Fix bug when adding receiver to tray menu
* Add Catalan translation.
* Add toggle command to solaar config to toggle boolean settings
* Don't select windows with no PID when looking for focus window
* Catch errors when applying settings so that other settings are not affected
* Add support for Bolt receivers and devices, including pairing
* Revise method for creating system tray menu
* Remove obsolete code (mostly Python 2 compatibility code)
* Add support for PRO X Wireless Mouse, G914 TKL keyboard
* Ignore more notifications that come to a device listener
* Handle more device connection protocols
* Update usage and rules documentation
* Change emojis to text in documentation
* Pare down device documentation so as not to require frequent updates
* Add information about M500S mouse
* Reimplement MOUSE GESTURE and DPI SLIDING settings
* Add setting for DPI CHANGE button to switch sensitivity
* Use file name instead of icon name for tray to avoid XFCE bug
* Update documentation on implemented features and mouse gestures
* Update Polish, Japanese, and Spanish translations
* Make Quit and About strings more translatable
# 1.0.7
* Don't use time_ns so as not to require Python 3.7
* Correctly determine setting box in change_click method
* Handle fake Nano connection notifications
* Lock on actual handle, not just on handle number
* Mark Nano receiver C52F as not unpairing
* Upgrade pairing/unpairing documentation
* Don't signal status change when battery changes from None to None.
* Add Japanese translation
* Use first word of name for code name if no other code name available.
* Better determination of when to add SW ID.
* Check for more HID++ feature request failing.
* Fix bug with new_fn_inversion setting.
* Use correct device number for directly connected devices
* Add debug message when candidate device found
* Update Polish, Taiwanese, and Brazilian Portuguese translations
* Add MouseProcess a rule condition like Process but for the window under the mouse
* Add parameters for binary settings to support prefixes
* Add locks to serialize requests to devices
* Fix bug when reprog key requests returns None
* Fix bug for empty process name and class
* Rules can now trigger on both pressing and releasing a diverted key
* Upgrade mouse gestures to allow sequences of movements
* Fix gkeys diversion faked read
* Add support for Logitech g pro x superlight receiver
* Convert HID++ 2.0 device kinds to enhanced HID++ 1.0 device kinds
* Update about window, bug report templates, and supported kernels.
# 1.0.6
* Update sliding DPI to look for suitable keys
* Add mouse gestures that can trigger rules
* Complain if receivers do not support connection notification
* In polling rate setting, only modify onboard profiles when actually writing polling rate
* Add ability to ignore settings.
* Use symbols for receiver sub-registers
* Add support for wired G700
* Do not set attention icon
* Replace deprecated GTK stock menu icons
* Better handling of icons in tray and tray menus
* Receiver c52e does not unpair
* Match active WM_CLASS as well as active process name in rules
* Correctly set icon theme value when regular battery icons are not available
* Handle exception when device is not available when device is being added
* Perform initial activation of devices in listener threads
* Keep track of serial numbers in the configuration file
* Don't update settings for non-active devices
* Set the current host name if not stored on the device
* Add setting for SMART SHIFT ENHANCED feature
* Don't unnecessarily use long messages for HID++ 1.0 commands
* Correctly select choices in solaar config and use 1-origin addressing
* Add quirk for G915 TKL keyboard because its host mode interferes with its Fn keys
* Show command outputs both saved and on-device settings
* Update documentation
* Fix bug in hidconsole
* Update French translation
# 1.0.5
* Update documentation on devices forgetting settings.
* Improve help messages
* Fix bug in finding receiver to pair
* Solaar config command can set keyed settings.
* Add setting for polling rate
* Use long HID++ messages for all 2.0 requests
* Update German, Italian, and Polish translations
* Solaar config command no longer selects paired but unconnected devices
* Show HID++ 1.0 remaining pairings value in solaar show for devices that support it
* Add option to not use battery icons in system tray.
* Update Polish and Dutch translation.
* Add Czech translation.
* Remove information on SUSE package as it is very old.
* Turn GKEY notifications into Gn key keypresses that can trigger rules.
* Push device settings to devices after suspend when device is immediately active.
* Reduce unnecessary saving of configuration file.
* Better handling of disconnected devices.
* Implement GUI to edit rules.
* Implement rule-base processing of HID++ feature notifications (depends on X11).
* Add settings for diversion of crown and remappable keys.
* Access widgets by name instead of by index.
* Implement UNIFIED_BATTERY feature and use in battery reports.
* Add a clickable lock icon that determines where each setting can be changed.
# 1.0.4
* Update pt_BR translation
* Support USB and BT connected devices that are not in descriptors.py
* Use FRIENDLY NAME for codename if needed and available.
* Extract manufacturer and product ID from Udev HID information.
* Add Bluetooth and USB product IDs to device descriptors records.
* Support Bluetooth-connected devices.
* Add model ID and unit ID to device identification.
* Support changing DPI by pressing DPI Switch button and sliding horizontally
* Add device-specific notification handlers.
* Add MX Vertical USB information.
* Udev rule adds seat permissions for all Logitech devices.
* Support USB-connected devices in GUI.
* Make probe and config work for USB-connected devices.
* Improve strings and display for settings.
* Correctly handle non-unifying connection notifications.
* Update GUI strings for several settings.
* Better support for EX100 and devices that connect to it.
* Partial support for feature GESTURE_2.
* Simplify interface for settings.
* Use DJ connection notifications to set device active status
* Udev rule sets seat write permissions for hidraw nodes for device as well as receivers.
* Handle USB devices that use HID++ protocol in CLI.
* Use device hidraw nodes where possible.
* Handle receivers with serial numbers that don't provide number of pairings.
* Ignore exceptions when setting locale.
* Correctly discover settings that share a name.
* Don't show pop-up notifications at startup.
* Keep battery voltage updated in GUI.
* Add Portuguese translation.
* Update several translations.
* Add Lightspeed receivers c545 and c541.
* Reimplement REPROG_CONTROLS data structure.
# 1.0.3
* Clean up documentation files.
* Update documentation on installation.
* Update Swedish and French translations.
* Add Norwegian Nynorsk and Danish translations.
* Fix bug handling DJ pairing notifications.
* Add Norwegian Bokmål translation.
* Remove deprecated solaar-cli application.
* Don't install udev or autostart files from python (or pip).
* Solaar needs Python 3.6+ and probably needs kernel 5.2+
* Handle exceptions on dynamic settings when device is not connected.
* Fix infinite loop on some low-level write errors
* Add support for EX100 keyboard/mouse and receiver (046d:c517)
* Add two settings for THUMB_WHEEL feature - inversion and reporting via HID++
* Update German translation
* Use REPORT RATE feature when available to determine polling rate.
* Improve config command speed when not printing all settings
* Improve config command handling and checking of arguments
* Add setting for CHANGE_HOST feature
* Add argument to settings for values that are not to persist
* Add argument to settings to not wait for reply when writing a value to device
* Add argument to not wait for reply from request to device
* Add settings for MULTIPLATFORM and DUALPLATFORM features
* Remove Logitech documents from documentation directory
* Change config command to not read all settings when only printing or showing one
* Display hosts info in 'solaar show' if device supports it
* Remove non-working smooth-scroll from M510 v1
* Add yapf and flake8 code style checks
* Fix feature k375s Fn inversion
* Update controls (keys and buttons) and tasks (actions)
* Improved way to specify feature settings.
* Don't abort on device notifications with unexpected device numbers, just warn.
* Keep track of non-features so as not to ask device multiple times.
* Implement KEYBOARD DISABLE KEYS feature.
* Don't create notifications for DJ device activity reports.
* Update a few special keys and actions.
* Add keyed choice settings in configuration panel.
* Support remappable keys from reprogrammable keys v4 feature.
* Add setting class for keyed choice.
* Only check for features once per device.
* Use settings interface to show feature values in `solaar show` if no special code for feature.
* Remove maximum window size.
* Process battery voltage notifications.
* Display battery voltage information in main window if regular battery information not available.
* Show next battery level where available.
* Update list of implemented features and provide information on how to implement features.
* Add c53d as a Lightspeed receiver.
# 1.0.2
* Add usage document
* Don't produce error dialog for inaccessible receivers with access control lists.
* Add option --battery-icons=symbolic to use symbolic icons if available.
* Update French translation
* Update installation documentation
* Remove packaging directory tree as it is not maintained
* Pip installs udev rule and solaar autostart when doing install without --user flag
* Use Solaar icon instead of a missing battery icon
* Use only standard icons for battery levels. Symbolic icons do not change to white in dark themes because of problems external to Solaar.
* Better reporting of battery levels when charging for some devices.
* Add information on K600 TV, M350 WIPD 4080, and MX Keys
* Remove assertion requiring receivers to still be in window when they are updated.
* Augment long description of Solaar showing up in repositories.
* Update installation directions.
* Install udev rule as well as autostart file when doing system install.
* Add support for Ayatana AppIndicator.
* Use setuptools icon directory on system installs when not using pip.
* Add receiver C517 and several older devices.
* Improved translations for polish.
* Bypass bug in appindicator when solaar is file in current directory.
* Don't check that device kind matches feature kind.
* Better determination of icons for battery levels.
* Use Ayatana AppIndicator if available.
* Improve error reporting when required system packages are not install.
* Better tooltip description
* Add release script to help when creating releases
* Look up tray icon filenames to get around a bug in libappindicator.
* Make the default behavior be to show the main window at startup.
* Support c537 nano receiver
* Add logind signals for suspend/resume.
* Remove solaar-gnome3 package
* Ignore features for devices that don't follow feature specification
* Add probe command to command-line interface to dump receiver registers
* Don't terminate on malformed or unknown messages
* Create fewer internal notifications for messages from devices
* Add a button to the main window to terminate (quit) Solaar
* Set up nano receivers as receivers with no unpairing and with re-pairing
* Set up c534 as receiver with max 2 pairings, no unpairing, re-pairing
* Better support receivers that do not unpair or when pairing replace existing pairings
* Add information about receiver pairing to receiver data structure
* Better support devices that only allow a limited number of total re-pairings
* Add --window option to control main window visibility and tray usage
* Ignore receiver if USB id is not retrieved
* Fix bug with double deleting when devices are disconnected
* Determine some receiver information from data structure for USB ids
* Treat battery level of 0 as unknown
* Fix bug on devices with no serial number
* Drop support for python2, and use python3 throughout
* Fix bug in remembering features discovered from device reports
* Show icons in main window device list
* Count offline devices when determining whether pairing is possible
* Update French, Dutch, German, and Croatian translations
* Better icons for battery levels
* Support DPI, Backlight 2, Battery Voltage features
* Support M585, M590, M330, MX Master 2s and 3, new M310, new K800, craft keyboard
* Documentation improvements
* Clean up directory structure and remove unused files
# 1.0.1
* Updated the repo url.
* Fixed typo which was crashing the application.
* Improved the HID write routine which was causing issues on some devices.
* Fix non-unifying receivers in Linux 5.2.
* Add new Lightspeed receiver (used in the G305)
# 1.0.0
* Too many to track...
# 0.9.3
* Merged solaar-cli functionality into main solaar.
* Scrolling over the systray icon switches between multiple peripherals.
* Swedish translation courtesy of Daniel Zippert and Emelie Snecker
* French translation courtesy of Papoteur, David Geiger and Damien Lallement.
* Fixed some untranslated strings.
# 0.9.2
* Added support for hand detection on the K800.
* Added support for V550 and V450 Nano.
* Fixed side-scrolling with the M705 Marathon.
* Fixed identification of the T650 Touchpad.
* Added internationalization support and romanian translation.
* Polish translation courtesy of Adrian Piotrowicz.
# 0.9.1
* When devices report a battery alert, only show the alert once.
* Make sure devices in the window tree are sorted by registration index.
* Added an autostart .desktop file.
* Replaced single-instance code with GtkApplication.
* Fixed identification of the M505 mouse.
* Fixed an occasional windowing layout bug with the C52F Nano Receiver.
# 0.9.0
* New single-window UI.
* Performance MX leds show the current battery charge.
* Support the VX Nano mouse.
* Faster and more accurate detection of devices.
* If upower is accessible through DBus, handle suspend/resume.
* Replaced Solaar icons with SVGs.
* Running solaar-cli in parallel with solaar is now less likely to cause issues.
* Bugfixes to saving and applying device settings.
* Properly handle ^C when running in console.
# 0.8.9
* Improved support for gnome-shell/Unity.
* Persist devices settings between runs.
* Fixed reading of MK700 keyboard battery status.
* Use battery icons from the current theme instead of custom ones.
* Debian/Ubuntu packages now depend on an icon theme, to make sure
no missing icons appear in the application window.
* Fixed missing icons under Kubuntu.
* Many more bug-fixes and reliability improvements.
# 0.8.8
* Partial support for some Nano receivers.
* Improved support for some devices: M510, K800, Performance MX.
* Improved battery support for some HID++ 1.0 devices.
* Properly handle device loss on computer sleep/wake.
* Better handling of receiver adding and removal at runtime.
* Removed a few more unhelpful notifications.
* Incipient support for multiple connected receivers.
* More Python 3 fixes.
# 0.8.7
* Don't show the "device disconnected" notification, it can be annoying and
not very useful.
* More robust detection of systray icon visibility.
# 0.8.6
* Ensure the Gtk application is single-instance.
* Fix identifying available dpi values.
* Fixed locating application icons when installed in a custom prefix.
* Fixed some icon names for the oxygen theme.
* Python 3 fixes.
Solaar-1.1.14/COPYRIGHT 0000664 0000000 0000000 00000001210 14735252137 0014315 0 ustar 00root root 0000000 0000000 Copyright 2012, 2013
Daniel Pavel
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, version 2.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
Solaar-1.1.14/LICENSE.txt 0000664 0000000 0000000 00000043254 14735252137 0014663 0 ustar 00root root 0000000 0000000 GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
Copyright (C)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.
Solaar-1.1.14/MANIFEST.in 0000664 0000000 0000000 00000000227 14735252137 0014567 0 ustar 00root root 0000000 0000000 include COPYRIGHT LICENSE.txt README.md CHANGELOG.md lib/solaar/version lib/solaar/commit
recursive-include rules.d *
recursive-include share/locale *
Solaar-1.1.14/Makefile 0000664 0000000 0000000 00000003523 14735252137 0014473 0 ustar 00root root 0000000 0000000 UDEV_RULE_FILE = 42-logitech-unify-permissions.rules
UDEV_RULES_SOURCE := rules.d/$(UDEV_RULE_FILE)
UDEV_RULES_SOURCE_UINPUT := rules.d-uinput/$(UDEV_RULE_FILE)
UDEV_RULES_DEST := /etc/udev/rules.d/
PIP_ARGS ?= .
.PHONY: install_ubuntu install_macos
.PHONY: install_apt install_brew install_pip
.PHONY: install_udev install_udev_uinput reload_udev uninstall_udev
.PHONY: format lint test
install_ubuntu: install_apt install_udev_uinput install_pip
install_macos: install_brew install_pip
install_apt:
@echo "Installing Solaar dependencies via apt"
sudo apt update
sudo apt install libdbus-1-dev libglib2.0-dev libgtk-3-dev libgirepository1.0-dev
install_dnf:
@echo "Installing Solaar dependencies via dn"
sudo dnf install gtk3 python3-gobject python3-dbus python3-pyudev python3-psutil python3-xlib python3-yaml
install_brew:
@echo "Installing Solaar dependencies via brew"
brew update
brew install hidapi gtk+3 pygobject3 gobject-introspection
install_pip:
@echo "Installing Solaar via pip"
python -m pip install --upgrade pip
pip install $(PIP_ARGS)
install_pipx:
@echo "Installing Solaar via pipx"
pipx install --system-site-packages $(PIP_ARGS)
install_udev:
@echo "Copying Solaar udev rule to $(UDEV_RULES_DEST)"
sudo cp $(UDEV_RULES_SOURCE) $(UDEV_RULES_DEST)
make reload_udev
install_udev_uinput:
@echo "Copying Solaar udev rule (uinput) to $(UDEV_RULES_DEST)"
sudo cp $(UDEV_RULES_SOURCE_UINPUT) $(UDEV_RULES_DEST)
make reload_udev
reload_udev:
@echo "Reloading udev rules"
sudo udevadm control --reload-rules
uninstall_udev:
@echo "Removing Solaar udev rules from $(UDEV_RULES_DEST)"
sudo rm -f $(UDEV_RULES_DEST)/$(UDEV_RULE_FILE)
make reload_udev
format:
@echo "Formatting Solaar code"
ruff format .
lint:
@echo "Linting Solaar code"
ruff check . --fix
test:
@echo "Running Solaar tests"
pytest --cov --cov-report=xml
Solaar-1.1.14/README.md 0000664 0000000 0000000 00000006213 14735252137 0014311 0 ustar 00root root 0000000 0000000 #
Solaar
Solaar is a Linux manager for many Logitech keyboards, mice, and other devices
that connect wirelessly to a Unifying, Bolt, Lightspeed or Nano receiver
as well as many Logitech devices that connect via a USB cable or Bluetooth.
Solaar is not a device driver and responds only to special messages from devices
that are otherwise ignored by the Linux input system.
More Information -
Usage -
Capabilities -
Rules -
Manual Installation
[](https://codecov.io/gh/pwr-Solaar/Solaar)
[](../LICENSE.txt)
Solaar supports:
- pairing/unpairing of devices with receivers
- configuring device settings
- custom button configuration
- running rules in response to special messages from devices
For more information see
the main Solaar documentation page. -
## Installation Packages
Up-to-date prebuilt packages are available for some Linux distros
(e.g., Fedora) in their standard repositories.
If a recent version of Solaar is not
available from the standard repositories for your distribution, you can try
one of these packages:
- Arch solaar package in the [extra repository][arch]
- Ubuntu/Kubuntu package in [Solaar stable ppa][ppa stable]
- NixOS Flake package in [Svenum/Solaar-Flake][nix flake]
Solaar is available from some other repositories
but may be several versions behind the current version:
- a [Debian package][debian], courtesy of Stephen Kitt
- a Ubuntu package is available from [universe repository][ubuntu universe repository]
- a [Gentoo package][gentoo], courtesy of Carlos Silva and Tim Harder
- a [Mageia package][mageia], courtesy of David Geiger
[ppa stable]: https://launchpad.net/~solaar-unifying/+archive/ubuntu/stable
[arch]: https://www.archlinux.org/packages/extra/any/solaar/
[gentoo]: https://packages.gentoo.org/packages/app-misc/solaar
[mageia]: http://mageia.madb.org/package/show/release/cauldron/application/0/name/solaar
[ubuntu universe repository]: http://packages.ubuntu.com/search?keywords=solaar&searchon=names&suite=all§ion=all
[nix flake]: https://github.com/Svenum/Solaar-Flake
[debian]: https://packages.debian.org/search?keywords=solaar&searchon=names&suite=all§ion=all
Solaar-1.1.14/RELEASE.md 0000664 0000000 0000000 00000001214 14735252137 0014430 0 ustar 00root root 0000000 0000000 # Solaar releases
## Please read before making a release
We support two type of releases: normal releases (ex. `1.0.0`) and release
candidates (ex. `1.0.0rc1`). Release candidates must have a `rcX` suffix.
Release routine:
- Update version in `lib/solaar/version`
- Add release changes to `CHANGELOG.md`
- Add release information to `share/solaar/io.github.pwr_solaar.solaar.metainfo.xml`
- Create a commit that starts with `release VERSION`
- Push commit to Solaar repository
- Invoke `./release.sh`
- Git tags are signed so you must have GPG set up
- You are required to have a github token with `public_repo` access
in `~/.github-token`
Solaar-1.1.14/Release_Notes.md 0000664 0000000 0000000 00000024303 14735252137 0016104 0 ustar 00root root 0000000 0000000 # Notes on Major Changes in Releases
## Version 1.1.13
* Solaar will drop support for Python 3.7 immediately after version 1.1.13.
* Version 1.1.12 does not push settings to many devices after a resume resulting in the device reverting to its default behaviour. This is fixed in 1.1.13.
## Version 1.1.12
* Solaar now processes DBus disconnection and connection messages from Bluez and re-initializes devices when they reconnect, to handle to a change introduced in Bluez 5.73. The HID++ driver does not re-initialize devices, which causes problems with smooth scrolling. Until the issue is resolved having Scroll Wheel Resolution set to true (and not ignored) may be helpful.
* The credits for translations have not been kept up to date. Translators who are not listed can update docs/i18n.ml and lib/solaar/ui/about.py.
* Solaar now has settings for features BRIGHTNESS_CONTROL, RGB_EFFECTS, and PER_KEY_LIGHTING features. The names of keys in the Per-key Lighting setting are for the standard US keyboard. Users who wish to modify these names should look at the section Keyboard Key Names and Locations in `https://pwr-solaar.github.io/Solaar/capabilities`
* A unit test test suite is being constructed using pytest.
* The Solaar code for communicating with receivers and devices has been significantly modified to improve testability and organization. Errors may have been introduced for uncommon hardware.
* The Later rule action uses precision timing for delays of less than one second.
* Solaar now indentifies supported devices by whether they support the HID protocols that Solaar needs. If a device does not show up at all when running Solaar, it almost certainly cannot be supported by Solaar.
## Version 1.1.11
* Solaar can dump device profiles in YAMLfor devices that support profiles and load profiles back from an edited file. See [the capabilities page](https://pwr-solaar.github.io/Solaar/capabilities) for more information.
* Solaar has settings for each LED Zone that a device supports under feature Color LED Effects.
* Solaar has settings for extended report rate, backlight levels, durations, and profile selection.
* Solaar now partly works in MacOS. Please open new issues for problems. Solaar may work in Windows. Please open new issues for problems. See https://github.com/pwr-Solaar/Solaar/pull/1971 for more information. Fixing problems in MacOS or Windows may take considerable time.
* Solaar works better when the Python package hid-parser is available. Distriubtions should try have this package installed.
## Version 1.1.10
* The mouse click rule action can now just simulate depressing or releasing the button.
* There is a new rule condition to check the hostname.
## Version 1.1.9
* Solaar now exits with at 0 exit code when killed.
* Two Solaar settings can interfere with the implementation of smooth scrolling in modern Linux HID++ drivers. These settings are initially set to ignore so that this interference does not happen.
* The Device rule condition checks for the device that produced a notification.
* The KeyIsDown rule condition checks whether a *diverted* rule key is down.
## Version 1.1.8
* The thumb wheel rule conditions take an optional parameter that checks for total signed thumb wheel movement.
## Version 1.1.7
* Solaar responds to scroll wheel ratchet notifications by changing its scroll wheel ratcheting.
* Solaar processing of report descriptors is optional, depending on whether the package hid-parser is available.
## Version 1.1.6
* Solaar requires Python version 3.7.
* Solaar uses report descriptors to recognize unknown devices that use HID++.
* The Later rule action takes an integer delay in seconds and one or more rule components. The action immediately completes while also scheduling the rule components for later exection.
## Version 1.1.5
* The Active rule condition takes the serial number or unitID of a device and checks whether the device is active. A device is active if it is connected (via a receiver, USB or Bluetooth), not turned off, and not in a power-saving state. This condition can be used to check whether changing a setting on the device will have any effect, as devices respond to messages only when active.
* Solaar logs warnings and errors to a file in the user's temporary file directory. This file is deleted when Solaar exists normally. If Solaar is run with `-dd` or `-ddd` informational messages are also logged in the file.
* If the first element of a Mouse Gesture rule condition is a key or button name then that name must be the same as the name of the key or button that initiated the mouse gesture.
* The Sliding DPI and Mouse Gestures are now set up using the Key/Button Diversion setting. Changing a key or button to Sliding DPI makes it initiate the sliding DPI changing. Changing a key or button to Mouse Gestures makes it initiate a mouse gesture. There can be multiple keys or buttons for sliding DPI and multiple keys or buttons for mouse gestures.
* Solaar waits a few seconds to save settings changes to its configuration file. If you interrupt Solaar soon after changing a setting the change might not be saved.
## Version 1.1.4
* There are settings for sidetone and equalizer gains for headsets.
* The KeyPress action can now either deppress, release, or click (default) keys.
* The KeyPress action now inserts shift and level 3 keypresses if simulating a key symbol requires one or both of them. So producing a "B" no longer requires adding a shift keysymbol.
## Version 1.1.3
* Solaar uses yaml for configuration files, converting the json configuration file to yaml if necessary.
* Solaar rules work better under Wayland but still cannot access the current process nor the current keyboard modifiers.
* Solaar uses uinput for simulating input in Wayland. See https://pwr-solaar.github.io/Solaar/rules for instructions on setting up uinput correctly.
## Version 1.1.2
* Solaar now depends on Python evdev. It can be installed if needed via `pip install --user evdev` or, in most distributions, by installing the python3-evdev package.
* Solaar rules partly work under Wayland. There is no access to the current process in Wayland. Simulated input uses uinput if XTest extension not available, requiring read and write permissions on /dev/uinput.
* There is a setting to divert gestures so that they can trigger rules.
* There is a setting to disable Onboard Profiles, which can interfere with the Polling Rate and M-Key LEDs settings. The Polling Rate setting no longer disables onboard profiles.
* There is a setting for the Persistent Remappable Keys feature.
* There is a new rule condition that tests device settings.
* There are new settings to set M-Key LEDs and MR-Key LED.
* There is a new kind of Solaar rule action to change settings for devices.
## Version 1.1.1
* There is a new setting to switch keyboard crowns between smooth and ratchet scrolling.
## Version 1.1.0
* Solaar now supports Bolt receivers and devices that connect to them, including authentication of devices when pairing.
* A setting has been added for the DPI CHANGE button to switch movement sensitivity.
## Version 1.0.7
* Solaar rules can now trigger on both pressing and releasing a diverted key.
* The new rule condition MouseProcess is like the Process condition except for the process of the window under the mouse.
* Mouse gestures have been upgraded. A mouse gesture is now a sequence of movements separated by no movement periods while the mouse gesture button is held down. The MouseGesture rule condition matches mouse gesture sequences. The old mouse-up, etc., tests are converted to MouseGesture conditions.
## Version 1.0.6
* The sliding DPI setting now looks for suitable keys to use to trigger its effects.
* If a mouse has a suitable button it can generate mouse gestures, which trigger rule processing. Mouse gestures need to be turned on and the button diverted to produce mouse gestures.
* Settings can now be ignored by clicking on the icon at the right-hand edge of a setting until the dialog error icon (usually a red icon) appears. Solaar will not try to restore the value for an ignored setting.
* Icon handling in the tray and the tray menu has been updated to work better with some system tray implementations.
* The process rule condition also matches against the current X11 WM_CLASS.
* The SMART SHIFT ENHANCED feature is supported.
## Version 1.0.5
* Solaar has rules that can perform actions such as pressing keys or scrolling when certain HID++ feature notifications happen. Users can change these rules either by editing ~/.config/solaar/rules.yaml or via a GUI. Rules depend on X11 and so are only available under X11. This is an experimental feature for Solaar and may undergo changes in the future.
* Each setting has a clickable lock icon that determines whether the setting can be changed.
## Version 1.0.4
* Devices that connect directly via Bluetooth or USB are now supported. These devices show up in the GUI as separate lines, not under a receiver. A device that is directly connected and also paired to a receiver will show up twice, but the entry under the receiver will not be active. With this change identifying devices becomes more difficult so occasionally check your Solaar configuration file (at ~/.config/solaar/config.json) to see that there is only one entry for each of your devices.
* There are new settings for gestures, thumb wheels, adjusting the wheel ratchet behavior, and changing DPI using a DPI Switch button.
* Solaar's Udev rule now adds seat permissions for all Logitech devices. Users who install Solaar themselves will have to install the new Udev rule and activate the rule. One way to do this is to restart the user's computer.
## Version 1.0.3
* The separate deprecated solaar-cli command has been removed.
* Devices can be switched between hosts using the Change Host setting. The device will try to connect to the other host. Some devices will detect that there is no active host on the other connections and reconnect back.
## Version 1.0.2
* The separate unneeded solaar-gnome3 command has been removed. The packaging directories have been removed.
* Non-unifying receivers are modelled better. Many of them cannot unpair but instead new pairings replace existing pairings.
* Battery icon selection has been simplified.
Solaar-1.1.14/bin/ 0000775 0000000 0000000 00000000000 14735252137 0013600 5 ustar 00root root 0000000 0000000 Solaar-1.1.14/bin/solaar 0000775 0000000 0000000 00000003520 14735252137 0015007 0 ustar 00root root 0000000 0000000 #!/usr/bin/env python3
# -*- python-mode -*-
# -*- coding: UTF-8 -*-
## Copyright (C) 2012-2013 Daniel Pavel
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License along
## with this program; if not, write to the Free Software Foundation, Inc.,
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
def init_paths():
"""Make the app work in the source tree."""
import os.path
import sys
# Python 3 might have problems converting back to UTF-8 in case of Unicode surrogates
decoded_path = None
try:
decoded_path = sys.path[0]
sys.path[0].encode(sys.getfilesystemencoding())
except UnicodeError:
sys.stderr.write(
"ERROR: Solaar cannot recognize encoding of filesystem path, "
"this may happen due to non UTF-8 characters in the pathname.\n"
)
sys.exit(1)
root = os.path.join(os.path.realpath(decoded_path), "..")
prefix = os.path.normpath(root)
src_lib = os.path.join(prefix, "lib")
share_lib = os.path.join(prefix, "share", "solaar", "lib")
for location in src_lib, share_lib:
init_py = os.path.join(location, "solaar", "__init__.py")
if os.path.exists(init_py):
sys.path[0] = location
break
if __name__ == "__main__":
init_paths()
import solaar.gtk
solaar.gtk.main()
Solaar-1.1.14/docs/ 0000775 0000000 0000000 00000000000 14735252137 0013760 5 ustar 00root root 0000000 0000000 Solaar-1.1.14/docs/.gitignore 0000664 0000000 0000000 00000000124 14735252137 0015745 0 ustar 00root root 0000000 0000000 # ignore documentation-specific files
.jekyll-metadata
Gemfile
Gemfile.lock
_site/
Solaar-1.1.14/docs/20121210110342697.pdf 0000664 0000000 0000000 00000532070 14735252137 0016273 0 ustar 00root root 0000000 0000000 %PDF-1.4
%
4 0 obj
<>
stream
JFIF ,, C
2!=,.$2I@LKG@FEPZsbPUmVEFdemw{N`}s~| C;!!;|SFS|||||||||||||||||||||||||||||||||||||||||||||||||| "
} !1AQa"q2#BR$3br
%&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz
w !1AQaq"2B #3Rbr
$4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ? 𢁠[`s ج נ((((((PEPEPEPEPEPc=h- ( ( 1EPEPEPEPEPEP`QZ( ( ( ( (
(
(
(
(
(
(
(
(KE &)hP@( ( ( ( ( ( ( ( ( (
(
(
(
(
(
(
(
(
(KE QE QE QE QE QE QE QE QE & ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (PEPEPEPEPEPEPEPEPEPEPE QE QE QE QE QE QE Rw((((((((((((( ( ( ( ( ( )1KE QE b LQZ(0=(
Z(6ؿ: Mv`zR@
اGFPmR@)0=)hh{j f ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (+c<~! jW t C5@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@~ D Ԭ v
N
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (/ß?6Jy?6J ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (xQE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QEᱍ#}R9 Xޓ CjԠ((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
ڵ++_?6Z ( ( ( ( ( ( ( ( ( ( ( EѻQ@88HҀEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPW
cjլF=A ֠(((((((((((((((((((((((((((((((()H :(((((()I :(((((((((((((((((((((Lh ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(2|21C ֬a$f ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( #5Rg GQSA uɠF욊k֙ %;NW&9eQ9a:Iݖrq* ^9'&iV*2rM?ZAEFҁ~cU^HE(*0rؽE GCU*O"F.NȵEPHQE TfdjnoiQERI.'\EV[lE.J1rصEU{WX=hYa=ZM;x8RA2ʹ{ҹ-QA!EPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPH- QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE ,ʹ?\Rq@EPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPG??묟z̓?ѭz ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( <}5jPU}*k22.ߧZ3!ܩniu:c(OSU wJ}Ny' D<߽Uh#L,FAb;c+Ko9]<IJxJ\,"ʁq CTOLQz2F`Aΰ]qW)03s@)S6kvd<:ӚBzz
@AA~?]I
!$[ p+@9(8 >d+A39bTN
^,UA4{OGZYHj:w[0(2
#oGPN8QAP+%0\`^[6L W(jm;'cAQ7 P5~Ls'Gp*6d`6O|օ
U؎8#l%@4PBAEPHQE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QEო+H?Zc2A<