Skip to content

Polling-Based Focus Detection #150

@hannesdelbeke

Description

@hannesdelbeke

⚠️ Polling-Based Focus Detection

[!warning] Performance Concern
15 FPS timer constantly polls window state, causing continuous CPU usage even when idle.

Current Issue:

tick = int(1000 / FOCUS_FRAMERATE)  # ~66ms
self.timer.start(tick)

def on_update(self):
    # Runs every 66ms
    if self.blender_focus_toggled():
        bqt.manager._blender_window_change(self._active_window_hwnd)

Problems:

  • Continuous CPU usage even when idle
  • 66ms latency in focus detection
  • Doesn't scale well with many widgets
  • Battery drain on laptops

[!tip] Event-Driven Alternative
Use OS-native event hooks instead of polling

Windows:

# Use Win32 message hooks for WM_ACTIVATE
def install_focus_hook():
    WH_CALLWNDPROC = 4
    callback = WINFUNCTYPE(c_long, c_int, c_uint, c_long)

    def hook_proc(nCode, wParam, lParam):
        if msg.message == WM_ACTIVATE:
            on_focus_changed(wParam != WA_INACTIVE)
        return CallNextHookEx(None, nCode, wParam, lParam)

    hook = callback(hook_proc)
    SetWindowsHookEx(WH_CALLWNDPROC, hook, None, GetCurrentThreadId())

macOS:

# Use NSNotificationCenter
from AppKit import NSWorkspace, NSNotificationCenter

def setup_focus_observer():
    nc = NSNotificationCenter.defaultCenter()
    nc.addObserver_selector_name_object_(
        self,
        'applicationDidBecomeActive:',
        'NSApplicationDidBecomeActiveNotification',
        None
    )

Impact: Could reduce idle CPU usage to near-zero.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions