|
9 | 9 |
|
10 | 10 | from dataclasses import dataclass |
11 | 11 | from typing import ( |
| 12 | + Any, |
12 | 13 | List, |
13 | 14 | Optional, |
14 | 15 | ) |
|
29 | 30 | import garbageHandler |
30 | 31 |
|
31 | 32 |
|
| 33 | +def __getattr__(attrName: str) -> Any: |
| 34 | + """Module level `__getattr__` used to preserve backward compatibility. |
| 35 | + """ |
| 36 | + if attrName == "post_windowMessageReceipt" and globalVars._allowDeprecatedAPI: |
| 37 | + from winAPI.messageWindow import post_windowMessageReceipt |
| 38 | + log.warning( |
| 39 | + "core.post_windowMessageReceipt is deprecated, " |
| 40 | + "use winAPI.messageWindow.post_windowMessageReceipt instead." |
| 41 | + ) |
| 42 | + return post_windowMessageReceipt |
| 43 | + raise AttributeError(f"module {repr(__name__)} has no attribute {repr(attrName)}") |
| 44 | + |
| 45 | + |
| 46 | + |
32 | 47 | # inform those who want to know that NVDA has finished starting up. |
33 | 48 | postNvdaStartup = extensionPoints.Action() |
34 | 49 |
|
|
37 | 52 | #: The thread identifier of the main thread. |
38 | 53 | mainThreadId = threading.get_ident() |
39 | 54 |
|
40 | | -#: Notifies when a window message has been received by NVDA. |
41 | | -#: This allows components to perform an action when several system events occur, |
42 | | -#: such as power, screen orientation and hardware changes. |
43 | | -#: Handlers are called with three arguments. |
44 | | -#: @param msg: The window message. |
45 | | -#: @type msg: int |
46 | | -#: @param wParam: Additional message information. |
47 | | -#: @type wParam: int |
48 | | -#: @param lParam: Additional message information. |
49 | | -#: @type lParam: int |
50 | | -# TODO: move to winAPI.messageWindow |
51 | | -post_windowMessageReceipt = extensionPoints.Action() |
52 | | - |
53 | 55 | _pump = None |
54 | 56 | _isPumpPending = False |
55 | 57 |
|
@@ -549,131 +551,9 @@ def onEndSession(evt): |
549 | 551 | # the GUI mainloop must be running for this to work so delay it |
550 | 552 | wx.CallAfter(audioDucking.initialize) |
551 | 553 |
|
552 | | - from winAPI.messageWindow import WindowMessage |
553 | | - from winAPI.sessionTracking import ( |
554 | | - handleSessionChange, |
555 | | - registerSessionNotification, |
556 | | - unregisterSessionNotification, |
557 | | - WindowsTrackedSession, |
558 | | - ) |
559 | | - import winUser |
560 | | - # #3763: In wxPython 3, the class name of frame windows changed from wxWindowClassNR to wxWindowNR. |
561 | | - # NVDA uses the main frame to check for and quit another instance of NVDA. |
562 | | - # To remain compatible with older versions of NVDA, create our own wxWindowClassNR. |
563 | | - # We don't need to do anything else because wx handles WM_QUIT for all windows. |
564 | | - import windowUtils |
565 | | - # TODO: move to winAPI.messageWindow |
566 | | - class MessageWindow(windowUtils.CustomWindow): |
567 | | - className = u"wxWindowClassNR" |
568 | | - # Windows constants for power / display changes |
569 | | - # TODO: move to winAPI |
570 | | - PBT_APMPOWERSTATUSCHANGE = 0xA |
571 | | - UNKNOWN_BATTERY_STATUS = 0xFF |
572 | | - AC_ONLINE = 0X1 |
573 | | - NO_SYSTEM_BATTERY = 0X80 |
574 | | - #States for screen orientation |
575 | | - # TODO: move to winAPI, turn to Enum |
576 | | - ORIENTATION_NOT_INITIALIZED = 0 |
577 | | - ORIENTATION_PORTRAIT = 1 |
578 | | - ORIENTATION_LANDSCAPE = 2 |
579 | | - |
580 | | - def __init__(self, windowName=None): |
581 | | - super(MessageWindow, self).__init__(windowName) |
582 | | - self.oldBatteryStatus = None |
583 | | - self.orientationStateCache = self.ORIENTATION_NOT_INITIALIZED |
584 | | - self.orientationCoordsCache = (0,0) |
585 | | - self.handlePowerStatusChange() |
586 | | - |
587 | | - # Call must be paired with a call to unregisterSessionNotification |
588 | | - self._isSessionTrackingRegistered = registerSessionNotification(self.handle) |
589 | | - |
590 | | - def warnIfSessionTrackingNotRegistered(self) -> None: |
591 | | - if self._isSessionTrackingRegistered: |
592 | | - return |
593 | | - failedToRegisterMsg = _( |
594 | | - # Translators: This is a warning to users, shown if NVDA cannot determine if |
595 | | - # Windows is locked. |
596 | | - "NVDA failed to register session tracking. " |
597 | | - "While this instance of NVDA is running, " |
598 | | - "your desktop will not be secure when Windows is locked. " |
599 | | - "Restart NVDA? " |
600 | | - ) |
601 | | - if wx.YES == gui.messageBox( |
602 | | - failedToRegisterMsg, |
603 | | - # Translators: This is a warning to users, shown if NVDA cannot determine if |
604 | | - # Windows is locked. |
605 | | - caption=_("NVDA could not start securely."), |
606 | | - style=wx.ICON_ERROR | wx.YES_NO, |
607 | | - ): |
608 | | - restart() |
609 | | - |
610 | | - def destroy(self): |
611 | | - """ |
612 | | - NVDA must unregister session tracking before destroying the message window. |
613 | | - """ |
614 | | - if self._isSessionTrackingRegistered: |
615 | | - # Requires an active message window and a handle to unregister. |
616 | | - unregisterSessionNotification(self.handle) |
617 | | - super().destroy() |
618 | | - |
619 | | - def windowProc(self, hwnd, msg, wParam, lParam): |
620 | | - post_windowMessageReceipt.notify(msg=msg, wParam=wParam, lParam=lParam) |
621 | | - if msg == WindowMessage.POWERBROADCAST and wParam == self.PBT_APMPOWERSTATUSCHANGE: |
622 | | - self.handlePowerStatusChange() |
623 | | - elif msg == winUser.WM_DISPLAYCHANGE: |
624 | | - self.handleScreenOrientationChange(lParam) |
625 | | - elif msg == WindowMessage.WTSSESSION_CHANGE: |
626 | | - # If we are receiving WTSSESSION_CHANGE events, _isSessionTrackingRegistered should be True |
627 | | - handleSessionChange(WindowsTrackedSession(wParam), lParam) |
628 | | - |
629 | | - def handleScreenOrientationChange(self, lParam): |
630 | | - # TODO: move to winAPI |
631 | | - import ui |
632 | | - # Resolution detection comes from an article found at https://msdn.microsoft.com/en-us/library/ms812142.aspx. |
633 | | - #The low word is the width and hiword is height. |
634 | | - width = winUser.LOWORD(lParam) |
635 | | - height = winUser.HIWORD(lParam) |
636 | | - self.orientationCoordsCache = (width,height) |
637 | | - if width > height: |
638 | | - # If the height and width are the same, it's actually a screen flip, and we do want to alert of those! |
639 | | - if self.orientationStateCache == self.ORIENTATION_LANDSCAPE and self.orientationCoordsCache != (width,height): |
640 | | - return |
641 | | - #Translators: The screen is oriented so that it is wider than it is tall. |
642 | | - ui.message(_("Landscape" )) |
643 | | - self.orientationStateCache = self.ORIENTATION_LANDSCAPE |
644 | | - else: |
645 | | - if self.orientationStateCache == self.ORIENTATION_PORTRAIT and self.orientationCoordsCache != (width,height): |
646 | | - return |
647 | | - #Translators: The screen is oriented in such a way that the height is taller than it is wide. |
648 | | - ui.message(_("Portrait")) |
649 | | - self.orientationStateCache = self.ORIENTATION_PORTRAIT |
650 | | - |
651 | | - def handlePowerStatusChange(self): |
652 | | - # TODO: move to winAPI |
653 | | - #Mostly taken from script_say_battery_status, but modified. |
654 | | - import ui |
655 | | - import winKernel |
656 | | - sps = winKernel.SYSTEM_POWER_STATUS() |
657 | | - if not winKernel.GetSystemPowerStatus(sps) or sps.BatteryFlag is self.UNKNOWN_BATTERY_STATUS: |
658 | | - return |
659 | | - if sps.BatteryFlag & self.NO_SYSTEM_BATTERY: |
660 | | - return |
661 | | - if self.oldBatteryStatus is None: |
662 | | - #Just initializing the cache, do not report anything. |
663 | | - self.oldBatteryStatus = sps.ACLineStatus |
664 | | - return |
665 | | - if sps.ACLineStatus == self.oldBatteryStatus: |
666 | | - #Sometimes, this double fires. This also fires when the battery level decreases by 3%. |
667 | | - return |
668 | | - self.oldBatteryStatus = sps.ACLineStatus |
669 | | - if sps.ACLineStatus & self.AC_ONLINE: |
670 | | - #Translators: Reported when the battery is plugged in, and now is charging. |
671 | | - ui.message(_("Charging battery. %d percent") % sps.BatteryLifePercent) |
672 | | - else: |
673 | | - #Translators: Reported when the battery is no longer plugged in, and now is not charging. |
674 | | - ui.message(_("Not charging battery. %d percent") %sps.BatteryLifePercent) |
| 554 | + from winAPI.messageWindow import _MessageWindow |
675 | 555 | import versionInfo |
676 | | - messageWindow = MessageWindow(versionInfo.name) |
| 556 | + messageWindow = _MessageWindow(versionInfo.name) |
677 | 557 |
|
678 | 558 | # initialize wxpython localization support |
679 | 559 | wxLocaleObj = wx.Locale() |
|
0 commit comments