Since the keyboard indicator widget cannot be run on my kali system, I decided to write one myself using pyqt. I found that it would be normal if I separated the program and ran it, but not with pyqt6. It runs normally on Windows, but a very strange problem occurs on Linux. Even if I keep pressing caps lock repeatedly, it still returns the same wrong value.
import subprocess
from time import sleep
while(True):
print(subprocess.run("xset q | grep \"Caps Lock\" | awk -F': ' '{gsub(/[0-9]/,\"\",$3); print $3}'",
stdout=subprocess.PIPE,
shell=True,
text=True).stdout.strip() == 'on')
sleep(0.3)
# pip install PyQt6 pynput
from platform import system
from sys import argv, exit
from PyQt6.QtCore import Qt
from PyQt6.QtGui import QPalette, QColor, QFont
from PyQt6.QtWidgets import QApplication, QMainWindow, QLabel
from pynput import keyboard
class CapsLockDetector(QMainWindow):
def __init__(self):
super().__init__()
self.status_label = None
self.initUI()
self.setupKeyboardHook()
def initUI(self):
self.setWindowTitle('Caps Lock Detector')
self.setWindowFlags(Qt.WindowType.WindowStaysOnTopHint | Qt.WindowType.FramelessWindowHint)
self.setGeometry(0, 0, 400, 120)
palette = self.palette()
palette.setColor(QPalette.ColorRole.Window, QColor(10, 10, 10))
self.setPalette(palette)
screen_geometry = QApplication.primaryScreen().geometry()
self.move(screen_geometry.x(), screen_geometry.y())
self.status_label = QLabel(self)
self.status_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
self.setCentralWidget(self.status_label)
self.status_label.setStyleSheet("color: white;")
font = QFont("Consolas", 40)
self.status_label.setFont(font)
self.updateCapsLockStatus()
def setupKeyboardHook(self):
listener = keyboard.Listener(on_press=self.on_key_press)
listener.start()
def on_key_press(self, key):
if key == keyboard.Key.caps_lock:
self.updateCapsLockStatus()
def updateCapsLockStatus(self):
new_status: bool = None
if system() == "Windows":
import ctypes
hllDll = ctypes.WinDLL("User32.dll")
VK_CAPITAL = 0x14
new_status = hllDll.GetKeyState(VK_CAPITAL) not in [0, 65408]
elif system() == "Linux":
import subprocess
new_status = subprocess.run("xset q | grep \"Caps Lock\" | awk -F': ' '{gsub(/[0-9]/,\"\",$3); print $3}'",
stdout=subprocess.PIPE,
shell=True,
text=True).stdout.strip() == 'on'
print(new_status)
self.show()
self.status_label.setText("OFF" if not new_status else "ON")
def mousePressEvent(self, event):
self.hide()
if __name__ == '__main__':
app = QApplication(argv)
window = CapsLockDetector()
window.show()
exit(app.exec())
I wanna my program returns the correct value