Files
msi-keyboard-color-selector/msi-keyboard-color-selector.py
2025-09-11 18:34:41 -05:00

196 lines
9.3 KiB
Python
Executable File

#!/usr/bin/python
import sys
import os
import re
from PySide6.QtSvg import QSvgRenderer
from PySide6.QtWidgets import QApplication, QSystemTrayIcon, QMenu, QInputDialog, QWidget, QVBoxLayout, QPushButton, QLabel
from PySide6.QtGui import QIcon, QAction, QPixmap, QPainter, QColor
from PySide6.QtCore import Qt, QTimer
import base64
class NotificationWindow(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("Notification")
self.setGeometry(200, 200, 400, 200)
layout = QVBoxLayout()
self.label = QLabel("You clicked the tray icon!")
ok_button = QPushButton("OK")
ok_button.clicked.connect(self.close)
layout.addWidget(self.label)
layout.addWidget(ok_button)
self.setLayout(layout)
class SystemTrayApp:
# Only these models are supported for now
# GE63, GE73, GE75, GS63, GS73, GS75, GX63, GT63, GL63, GS65
msi_model = "GS65"
def __init__(self):
self.app = QApplication(sys.argv)
self.app.setQuitOnLastWindowClosed(False)
self.notification_window = NotificationWindow()
# Create the system tray icon
self.tray = QSystemTrayIcon()
# - To load from a file
#self.tray.setIcon(QIcon("Linux-icon.png"))
# still to-do
# - To load from embedded svg file
renderer = QSvgRenderer()
renderer.load(SystemTrayApp.svg_systray_icon.encode('utf-8'))
pixmap = QPixmap(24, 24)
pixmap.fill(QColor(0,0,0,0)) # QColor(0,0,0,0) is for transparency
painter = QPainter(pixmap)
renderer.render(painter)
painter.end()
self.tray.setIcon(QIcon(pixmap))
self.tray.setToolTip("MSI Keyboard Color Selector")
self.tray.setVisible(True)
# Create the menu
self.menu = QMenu()
# Add 10 options to the menu
self.create_actions()
# Set the menu for the system tray icon
self.tray.setContextMenu(self.menu)
# When the icon is cliced call tray_icon_activated method.
self.tray.activated.connect(self.tray_icon_activated)
def create_actions(self):
# These presets are defined in the msi-perkeyrgb program
#aqua chakra default disco drain freeway plain rainbow-split roulette
actions = [
("Aqua", self.aqua),
("Chakra", self.chakra),
("Default", self.default),
("Disco", self.disco),
("Drain", self.drain),
("Freeway", self.freeway),
("Plain", self.plain),
("Rainbow-Split", self.rainbow_split),
("Roulette", self.roulette),
("Custom Hex HTML Color", self.html_color),
("Quit", self.app.quit)
]
for label, func in actions:
action = QAction(label, self.tray)
action.triggered.connect(func)
self.menu.addAction(action)
def aqua(self):
print("Aqua preset selected")
self.tray.showMessage("Notification", "Aqua Preset Selected", QSystemTrayIcon.Information, 3000)
command = "msi-perkeyrgb -m " + SystemTrayApp.msi_model + " -p aqua"
os.system(command)
def chakra(self):
print("Chakra preset selected")
self.tray.showMessage("Notification", "Chakra Preset Selected", QSystemTrayIcon.Information, 3000)
command = "msi-perkeyrgb -m " + SystemTrayApp.msi_model + " -p chakra"
os.system(command)
def default(self):
print("Default preset selected")
self.tray.showMessage("Notification", "Default Preset Selected", QSystemTrayIcon.Information, 3000)
command = "msi-perkeyrgb -m " + SystemTrayApp.msi_model + " -p default"
os.system(command)
def disco(self):
print("Disco preset selected")
self.tray.showMessage("Notification", "Disco Preset Selected", QSystemTrayIcon.Information, 3000)
command = "msi-perkeyrgb -m " + SystemTrayApp.msi_model + " -p disco"
os.system(command)
def drain(self):
print("Drain preset selected")
self.tray.showMessage("Notification", "Drain Preset Selected", QSystemTrayIcon.Information, 3000)
command = "msi-perkeyrgb -m " + SystemTrayApp.msi_model + " -p drain"
os.system(command)
def freeway(self):
print("Freeway preset selected")
self.tray.showMessage("Notification", "Freeway Preset Selected", QSystemTrayIcon.Information, 3000)
command = "msi-perkeyrgb -m " + SystemTrayApp.msi_model + " -p freeway"
os.system(command)
def plain(self):
print("Plain preset selected")
self.tray.showMessage("Notification", "Plain Preset Selected", QSystemTrayIcon.Information, 3000)
command = "msi-perkeyrgb -m " + SystemTrayApp.msi_model + " -p plain"
os.system(command)
def rainbow_split(self):
print("Rainbow-Split preset selected")
self.tray.showMessage("Notification", "Rainbow-Split Preset Selected", QSystemTrayIcon.Information, 3000)
command = "msi-perkeyrgb -m " + SystemTrayApp.msi_model + " -p rainbow-split"
os.system(command)
def roulette(self):
print("Roulette preset selected")
self.tray.showMessage("Notification", "Roulette Preset Selected", QSystemTrayIcon.Information, 3000)
command = "msi-perkeyrgb -m " + SystemTrayApp.msi_model + " -p roulette"
os.system(command)
def html_color(self):
text, ok = QInputDialog.getText(None, "Input", "Enter a Hex HTML color: Example: 00ff00 for Green:")
if ok:
pattern = r'^[0-9A-Fa-f]{6}$'
if (re.match(pattern, text)):
print("Custom Hex HTML color: {text} selected")
notification_message = "Custom Hex HTML Color '" + text + "' selected"
self.tray.showMessage("Notification", notification_message, QSystemTrayIcon.Information, 4000)
command = "msi-perkeyrgb -m " + SystemTrayApp.msi_model + " -s " + text.lower()
os.system(command)
else:
print("Invalid Hexadecimal HTML color entered")
print("Just enter a RGB color in hexadecimal without the #")
print("Forexample:")
print("FF0000 = Red")
print("00FF00 = Green")
print("0000FF = Blue")
def tray_icon_activated(self, reason):
print("tray_icon_activated has been called")
# if reason == QSystemTrayIcon.Trigger:
# self.notification_window.show()
def run(self):
sys.exit(self.app.exec())
svg_systray_icon = """
<svg width="32" version="1.1" xmlns="http://www.w3.org/2000/svg" height="32" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape">
<defs id="defs5455">
<linearGradient inkscape:collect="always" id="linearGradient4303">
<stop style="stop-color:#c6cdd1" id="stop4305"/>
<stop offset="1" style="stop-color:#e0e5e7" id="stop4307"/>
</linearGradient>
<linearGradient inkscape:collect="always" xlink:href="#linearGradient4303" id="linearGradient4696" y1="540.79797" y2="522.79797" x2="0" gradientUnits="userSpaceOnUse"/>
</defs>
<metadata id="metadata5458"/>
<g inkscape:label="Capa 1" inkscape:groupmode="layer" id="layer1" transform="matrix(1 0 0 1 -384.57143 -515.798)">
<rect width="31.999975" x="384.57144" y="522.79797" height="18" style="fill:url(#linearGradient4696);opacity:0.99" id="rect4688"/>
<rect width="32" x="384.57144" y="539.79797" height="1" style="fill:#abb4ba" id="rect4733"/>
<rect width="1" x="414.57141" y="523.79822" height="1" style="fill:#31c281" id="rect4462-0-90-5"/>
<rect width="1" x="411.57135" y="523.79822" height="1" style="fill:#31c281" id="rect4975-0"/>
<rect width="1" x="408.57141" y="523.79822" height="1" style="fill:#31c281" id="rect4977-0"/>
<path inkscape:connector-curvature="0" style="fill:#536161" id="rect4758" d="m 1,12 0,3 3,0 0,-3 z m 4,0 0,3 3,0 0,-3 z m 4,0 0,3 3,0 0,-3 z m 4,0 0,3 3,0 0,-3 z m 4,0 0,3 3,0 0,-3 z m 4,0 0,3 3,0 0,-3 z m 4,0 0,3 6,0 0,-3 z m -24,4 0,3 5,0 0,-3 z m 6,0 0,3 3,0 0,-3 z m 4,0 0,3 3,0 0,-3 z m 4,0 0,3 3,0 0,-3 z m 4,0 0,3 3,0 0,-3 z m 4,0 0,3 3,0 0,-3 z m 4,0 0,3 4,0 0,-3 z m -26,4 0,3 3,0 0,-3 z m 4,0 0,3 3,0 0,-3 z m 4,0 0,3 10,0 0,-3 z m 11,1 0,2 3,0 0,-2 z m 4,-1 0,3 3,0 0,-3 z m 4,1 0,2 3,0 0,-2 z" transform="matrix(1 0 0 1 384.57143 515.798)"/>
<path style="fill:#334545" id="rect4768" d="M 1 14 L 1 15 L 4 15 L 4 14 L 1 14 z M 5 14 L 5 15 L 8 15 L 8 14 L 5 14 z M 9 14 L 9 15 L 12 15 L 12 14 L 9 14 z M 13 14 L 13 15 L 16 15 L 16 14 L 13 14 z M 17 14 L 17 15 L 20 15 L 20 14 L 17 14 z M 21 14 L 21 15 L 24 15 L 24 14 L 21 14 z M 25 14 L 25 15 L 31 15 L 31 14 L 25 14 z M 1 18 L 1 19 L 6 19 L 6 18 L 1 18 z M 7 18 L 7 19 L 10 19 L 10 18 L 7 18 z M 11 18 L 11 19 L 14 19 L 14 18 L 11 18 z M 15 18 L 15 19 L 18 19 L 18 18 L 15 18 z M 19 18 L 19 19 L 22 19 L 22 18 L 19 18 z M 23 18 L 23 19 L 26 19 L 26 18 L 23 18 z M 27 18 L 27 19 L 31 19 L 31 18 L 27 18 z M 1 22 L 1 23 L 4 23 L 4 22 L 1 22 z M 5 22 L 5 23 L 8 23 L 8 22 L 5 22 z M 9 22 L 9 23 L 19 23 L 19 22 L 9 22 z M 20 22 L 20 23 L 23 23 L 23 22 L 20 22 z M 24 22 L 24 23 L 27 23 L 27 22 L 24 22 z M 28 22 L 28 23 L 31 23 L 31 22 L 28 22 z " transform="matrix(1 0 0 1 384.57143 515.798)"/>
</g>
</svg>
"""
if __name__ == "__main__":
tray_app = SystemTrayApp()
tray_app.run()