# latest import ctypes import logging import signal import sys from PySide6.QtCore import QPoint, Qt from PySide6.QtGui import QColor from PySide6.QtWidgets import ( QApplication, QCheckBox, QColorDialog, QLabel, QPushButton, QSlider, QVBoxLayout, QWidget, ) logging.basicConfig(level=logging.INFO, format="%(levelname)s %(message)s") try: ctypes.windll.user32.SetProcessDPIAware() except Exception: pass DWMWA_USE_IMMERSIVE_DARK_MODE = 20 DWMWA_WINDOW_CORNER_PREFERENCE = 33 DWMWCP_ROUND = 2 class WindowConfig: width = 800 height = 500 opacity = 0.99 radius = 11 resize_margin = 8 minimum_width = 300 minimum_height = 200 background_alpha = 190 border_alpha = 190 class GlassWindow(QWidget): def __init__(self): super().__init__( None, Qt.FramelessWindowHint | Qt.Window | Qt.WindowStaysOnTopHint, ) self.cfg = WindowConfig() self.background_color = QColor(155, 155, 155) self._drag_offset = None self._resize_edges = None self._resize_start_pos = QPoint() self._resize_start_geo = self.geometry() self.setAttribute(Qt.WA_TranslucentBackground, True) self.setWindowOpacity(self.cfg.opacity) self.resize(self.cfg.width, self.cfg.height) self.setMinimumSize( self.cfg.minimum_width, self.cfg.minimum_height, ) self.setMouseTracking(True) self.panel = QWidget(self) self.panel.setObjectName("panel") layout = QVBoxLayout(self.panel) layout.setContentsMargins(24, 24, 24, 24) layout.setSpacing(16) title = QLabel("") title.setStyleSheet( "background:transparent;color:white;font-size:24px;font-weight:600;" ) body = QLabel("opacity") body.setStyleSheet("background:transparent;color:transparent;") layout.addWidget(title) layout.addWidget(body) layout.addStretch() self.slider = QSlider( Qt.Horizontal, self.panel, ) self.slider.setRange(0, 255) self.slider.setFixedWidth(255) self.slider.setValue( self.cfg.background_alpha, ) self.slider.valueChanged.connect( self.update_panel_style, ) self.color_button = QPushButton( self.panel, ) self.color_button.setFixedSize(22, 22) self.color_button.clicked.connect( self.pick_background_color, ) self.pin_button = QPushButton( "🗗", self.panel, ) self.pin_button.setCheckable(True) self.pin_button.setChecked(True) self.pin_button.setFixedSize(28, 28) self.pin_button.setCursor(Qt.ArrowCursor) self.pin_button.setToolTip("Always on Top") self.pin_button.toggled.connect( self.toggle_always_on_top, ) self.setCursor(Qt.ArrowCursor) self.panel.setCursor(Qt.ArrowCursor) self.slider.setCursor(Qt.ArrowCursor) self.color_button.setCursor(Qt.ArrowCursor) self.pin_button.setCursor(Qt.ArrowCursor) self.pin_button.setObjectName("pinButton") self.update_panel_style() def toggle_always_on_top( self, enabled: bool, ): geometry = self.geometry() self.setWindowFlag( Qt.WindowStaysOnTopHint, enabled, ) self.show() self.setGeometry(geometry) def pick_background_color(self): dialog = QColorDialog( self.background_color, self, ) dialog.setOption( QColorDialog.DontUseNativeDialog, True, ) dialog.setWindowTitle( "background", ) dialog.setStyleSheet(""" QColorDialog{ background:#030303; color:#f2f2f2; } QWidget{ background:#090909; color:#f2f2f2; } QLabel{ background:transparent; color:#f2f2f2; } QGroupBox{ color:#f2f2f2; border:1px solid #3a3a3a; margin-top:8px; } QGroupBox::title{ left:8px; padding:0 4px; } QPushButton{ background:#2a2a2a; color:white; border:1px solid #444; border-radius:4px; padding:5px 12px; } QPushButton:hover{ background:#343434; } QPushButton:pressed{ background:#404040; } QLineEdit, QSpinBox, QComboBox{ background:#2a2a2a; color:white; border:1px solid #444; selection-background-color:#5DFFCE; } QTabBar::tab{ background:#2a2a2a; color:white; padding:6px 10px; } QTabBar::tab:selected{ background:#404040; } """) if dialog.exec(): self.background_color = dialog.currentColor() self.update_panel_style() # v4 def update_panel_style(self, value=None): if value is not None: self.cfg.background_alpha = value r = self.background_color.red() g = self.background_color.green() b = self.background_color.blue() luminance = (0.2126 * r + 0.7152 * g + 0.0722 * b) / 255.0 groove = f"rgba({r},{g},{b},{max(28, self.cfg.background_alpha - 135)})" fill = f"rgba({r},{g},{b},{min(255, self.cfg.background_alpha + 45)})" if luminance > 0.60: handle = "#1b1b1d" handle_hover = "#121214" handle_pressed = "#09090b" handle_border = "rgba(255,255,255,32)" else: handle = "#f7f7f8" handle_hover = "#ffffff" handle_pressed = "#ececee" handle_border = "rgba(0,0,0,28)" self.setStyleSheet(f""" #panel {{ background: rgba({r},{g},{b},{self.cfg.background_alpha}); border: 1px solid rgba(255,255,255,.2); border-radius: {self.cfg.radius}px; }} QPushButton {{ margin: 2px; background: rgb({r},{g},{b}); border: 1px solid rgba(255,255,255,24); border-radius: 4px; }} QPushButton:hover {{ border: 1px solid rgba(255,255,255,48); }} QSlider {{ background: transparent; }} QSlider::groove:horizontal {{ height: 4px; background: {groove}; border: none; border-radius: 2px; }} QSlider::sub-page:horizontal {{ background: {fill}; border-radius: 2px; }} QSlider::add-page:horizontal {{ background: {groove}; border-radius: 2px; }} QSlider::handle:horizontal {{ width: 14px; height: 14px; margin: -5px 0; background: {handle}; border: 1px solid {handle_border}; border-radius: 7px; }} QSlider::handle:horizontal:hover {{ background: {handle_hover}; }} QSlider::handle:horizontal:pressed {{ background: {handle_pressed}; }} QPushButton {{ margin: 2px; background: rgb({r},{g},{b}); border: 1px solid rgba(255,255,255,24); border-radius: 4px; }} QPushButton#pinButton {{ color: rgba(255,255,255,180); }} QPushButton#pinButton:checked {{ background: #064C2C1C; border: 1px solid rgba(255,255,255,40); color: white; font-weight: 600; }} """) def resizeEvent(self, event): self.panel.setGeometry(self.rect()) margin = 24 slider_y = self.panel.height() - self.slider.height() - margin spacing_slider_color = 10 spacing_color_pin = 8 self.slider.move( self.panel.width() - self.slider.width() - 67 - margin, slider_y, ) self.color_button.move( self.slider.x() + self.slider.width() + spacing_slider_color, slider_y + (self.slider.height() - self.color_button.height()) // 2, ) self.pin_button.move( self.color_button.x() + self.color_button.width() + spacing_color_pin, slider_y + (self.slider.height() - self.pin_button.height()) // 2, ) super().resizeEvent(event) def showEvent(self, event): super().showEvent(event) hwnd = int(self.winId()) try: dark = ctypes.c_int(1) ctypes.windll.dwmapi.DwmSetWindowAttribute( hwnd, DWMWA_USE_IMMERSIVE_DARK_MODE, ctypes.byref(dark), ctypes.sizeof(dark), ) corner = ctypes.c_int(DWMWCP_ROUND) ctypes.windll.dwmapi.DwmSetWindowAttribute( hwnd, DWMWA_WINDOW_CORNER_PREFERENCE, ctypes.byref(corner), ctypes.sizeof(corner), ) except Exception as ex: logging.warning("DWM setup failed: %s", ex) # v2 def _hit_test(self, pos): m = self.cfg.resize_margin + 6 x = pos.x() y = pos.y() w = self.width() h = self.height() left = x <= m right = x >= w - m top = y <= m bottom = y >= h - m return left, top, right, bottom def mousePressEvent(self, e): if e.button() != Qt.LeftButton: return super().mousePressEvent(e) edges = self._hit_test(e.position().toPoint()) if any(edges): self._resize_edges = edges self._resize_start_pos = e.globalPosition().toPoint() self._resize_start_geo = self.geometry() return self._drag_offset = ( e.globalPosition().toPoint() - self.frameGeometry().topLeft() ) def mouseMoveEvent(self, e): pos = e.position().toPoint() if self._resize_edges is not None: dx = e.globalPosition().toPoint().x() - self._resize_start_pos.x() dy = e.globalPosition().toPoint().y() - self._resize_start_pos.y() geo = self._resize_start_geo x = geo.x() y = geo.y() w = geo.width() h = geo.height() left, top, right, bottom = self._resize_edges if left: x += dx w -= dx if right: w += dx if top: y += dy h -= dy if bottom: h += dy if w < self.minimumWidth(): if left: x -= self.minimumWidth() - w w = self.minimumWidth() if h < self.minimumHeight(): if top: y -= self.minimumHeight() - h h = self.minimumHeight() self.setGeometry(x, y, w, h) return if self._drag_offset is not None: self.move(e.globalPosition().toPoint() - self._drag_offset) return left, top, right, bottom = self._hit_test(pos) if (left and top) or (right and bottom): self.setCursor(Qt.SizeFDiagCursor) elif (right and top) or (left and bottom): self.setCursor(Qt.SizeBDiagCursor) elif left or right: self.setCursor(Qt.SizeHorCursor) elif top or bottom: self.setCursor(Qt.SizeVerCursor) else: self.setCursor(Qt.ArrowCursor) # v1 def mouseReleaseEvent(self, e): self._drag_offset = None self._resize_edges = None super().mouseReleaseEvent(e) def keyPressEvent(self, e): if e.key() == Qt.Key_Escape: self.close() else: super().keyPressEvent(e) def main(): signal.signal(signal.SIGINT, signal.SIG_DFL) app = QApplication(sys.argv) w = GlassWindow() w.show() sys.exit(app.exec()) if __name__ == "__main__": main()