/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
class nsBaseWidget; struct IVirtualDesktopManager; class WinWindowOcclusionTrackerTest; class WinWindowOcclusionTrackerInteractiveTest;
namespace base { class Thread;
} // namespace base
namespace mozilla {
namespace widget {
class OcclusionUpdateRunnable; class SerializedTaskDispatcher; class UpdateOcclusionStateRunnable;
// This class handles window occlusion tracking by using HWND. // Implementation is borrowed from chromium's NativeWindowOcclusionTrackerWin. class WinWindowOcclusionTracker final { public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WinWindowOcclusionTracker)
/// Can only be called from the main thread. static WinWindowOcclusionTracker* Get();
/// Can only be called from the main thread. staticvoid Ensure();
/// Can only be called from the main thread. staticvoid ShutDown();
/// Can be called from any thread. static MessageLoop* OcclusionCalculatorLoop();
/// Can be called from any thread. staticbool IsInWinWindowOcclusionThread();
// Enables notifying to widget via NotifyOcclusionState() when the occlusion // state has been computed. void Enable(nsBaseWidget* aWindow, HWND aHwnd);
// Disables notifying to widget via NotifyOcclusionState() when the occlusion // state has been computed. void Disable(nsBaseWidget* aWindow, HWND aHwnd);
// Called when widget's visibility is changed void OnWindowVisibilityChanged(nsBaseWidget* aWindow, bool aVisible);
// This class computes the occlusion state of the tracked windows. // It runs on a separate thread, and notifies the main thread of // the occlusion state of the tracked windows. class WindowOcclusionCalculator {
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WindowOcclusionCalculator) public: // Creates WindowOcclusionCalculator instance. staticvoid CreateInstance();
// Registers event hooks, if not registered. void MaybeRegisterEventHooks();
// This is the callback registered to get notified of various Windows // events, like window moving/resizing. staticvoid CALLBACK EventHookCallback(HWINEVENTHOOK aWinEventHook,
DWORD aEvent, HWND aHwnd, LONG aIdObject, LONG aIdChild,
DWORD aEventThread,
DWORD aMsEventTime);
// EnumWindows callback used to iterate over all hwnds to determine // occlusion status of all tracked root windows. Also builds up // |current_pids_with_visible_windows_| and registers event hooks for newly // discovered processes with visible hwnds. staticBOOL CALLBACK
ComputeNativeWindowOcclusionStatusCallback(HWND hwnd, LPARAM lParam);
// EnumWindows callback used to update the list of process ids with // visible hwnds, |pids_for_location_change_hook_|. staticBOOL CALLBACK UpdateVisibleWindowProcessIdsCallback(HWND aHwnd,
LPARAM aLParam);
// Determines which processes owning visible application windows to set the // EVENT_OBJECT_LOCATIONCHANGE event hook for and stores the pids in // |pids_for_location_change_hook_|. void UpdateVisibleWindowProcessIds();
// Computes the native window occlusion status for all tracked root gecko // windows in |root_window_hwnds_occlusion_state_| and notifies them if // their occlusion status has changed. void ComputeNativeWindowOcclusionStatus();
// Schedules an occlusion calculation , if one isn't already scheduled. void ScheduleOcclusionCalculationIfNeeded();
// Registers a global event hook (not per process) for the events in the // range from |event_min| to |event_max|, inclusive. void RegisterGlobalEventHook(DWORD aEventMin, DWORD aEventMax);
// Registers the EVENT_OBJECT_LOCATIONCHANGE event hook for the process with // passed id. The process has one or more visible, opaque windows. void RegisterEventHookForProcess(DWORD aPid);
// Registers/Unregisters the event hooks necessary for occlusion tracking // via calls to RegisterEventHook. These event hooks are disabled when all // tracked windows are minimized. void RegisterEventHooks(); void UnregisterEventHooks();
// EnumWindows callback for occlusion calculation. Returns true to // continue enumeration, false otherwise. Currently, always returns // true because this function also updates currentPidsWithVisibleWindows, // and needs to see all HWNDs. bool ProcessComputeNativeWindowOcclusionStatusCallback(
HWND aHwnd, std::unordered_set<DWORD>* aCurrentPidsWithVisibleWindows);
// Processes events sent to OcclusionEventHookCallback. // It generally triggers scheduling of the occlusion calculation, but // ignores certain events in order to not calculate occlusion more than // necessary. void ProcessEventHookCallback(HWINEVENTHOOK aWinEventHook, DWORD aEvent,
HWND aHwnd, LONG aIdObject, LONG aIdChild);
// EnumWindows callback for determining which processes to set the // EVENT_OBJECT_LOCATIONCHANGE event hook for. We set that event hook for // processes hosting fully visible, opaque windows. void ProcessUpdateVisibleWindowProcessIdsCallback(HWND aHwnd);
// Returns true if the window is visible, fully opaque, and on the current // virtual desktop, false otherwise. bool WindowCanOccludeOtherWindowsOnCurrentVirtualDesktop(
HWND aHwnd, LayoutDeviceIntRect* aWindowRect);
// Returns true if aHwnd is definitely on the current virtual desktop, // false if it's definitely not on the current virtual desktop, and Nothing // if we we can't tell for sure.
Maybe<bool> IsWindowOnCurrentVirtualDesktop(HWND aHwnd);
// Map of root app window hwnds and their occlusion state. This contains // both visible and hidden windows. // It is accessed from WinWindowOcclusionTracker::UpdateOcclusionState() // without using mutex. The access is safe by using // SerializedTaskDispatcher.
std::unordered_map<HWND, OcclusionState> mRootWindowHwndsOcclusionState;
// Values returned by SetWinEventHook are stored so that hooks can be // unregistered when necessary.
std::vector<HWINEVENTHOOK> mGlobalEventHooks;
// Map from process id to EVENT_OBJECT_LOCATIONCHANGE event hook.
std::unordered_map<DWORD, HWINEVENTHOOK> mProcessEventHooks;
// Pids of processes for which the EVENT_OBJECT_LOCATIONCHANGE event hook is // set.
std::unordered_set<DWORD> mPidsForLocationChangeHook;
// Used as a timer to delay occlusion update.
RefPtr<CancelableRunnable> mOcclusionUpdateRunnable;
// Used to determine if a window is occluded. As we iterate through the // hwnds in z-order, we subtract each opaque window's rect from // mUnoccludedDesktopRegion. When we get to a root window, we subtract // it from mUnoccludedDesktopRegion, and if mUnoccludedDesktopRegion // doesn't change, the root window was already occluded.
LayoutDeviceIntRegion mUnoccludedDesktopRegion;
// Keeps track of how many root windows we need to compute the occlusion // state of in a call to ComputeNativeWindowOcclusionStatus. Once we've // determined the state of all root windows, we can stop subtracting // windows from mUnoccludedDesktopRegion;. int mNumRootWindowsWithUnknownOcclusionState;
// This is true if the task bar thumbnails or the alt tab thumbnails are // showing. bool mShowingThumbnails = false;
// Used to keep track of the window that's currently moving. That window // is ignored for calculation occlusion so that tab dragging won't // ignore windows occluded by the dragged window.
HWND mMovingWindow = 0;
// Only used on Win10+.
RefPtr<IVirtualDesktopManager> mVirtualDesktopManager;
// Used to serialize tasks related to mRootWindowHwndsOcclusionState.
RefPtr<SerializedTaskDispatcher> mSerializedTaskDispatcher;
// This is an alias to the singleton WinWindowOcclusionTracker mMonitor, // and is used in ShutDown().
Monitor& mMonitor;
// Returns true if we are interested in |hwnd| for purposes of occlusion // calculation. We are interested in |hwnd| if it is a window that is // visible, opaque, bounded, and not a popup or floating window. If we are // interested in |hwnd|, stores the window rectangle in |window_rect|. staticbool IsWindowVisibleAndFullyOpaque(HWND aHwnd,
LayoutDeviceIntRect* aWindowRect);
// Updates root windows occclusion state. If aShowAllWindows is true, // all non-hidden windows will be marked visible. This is used to force // rendering of thumbnails. void UpdateOcclusionState(std::unordered_map<HWND, OcclusionState>* aMap, bool aShowAllWindows);
public: // This is called with session changed notifications. If the screen is locked // by the current session, it marks app windows as occluded. void OnSessionChange(WPARAM aStatusCode);
// This is called when the display is put to sleep. If the display is sleeping // it marks app windows as occluded. void OnDisplayStateChanged(bool aDisplayOn);
private: // Marks all root windows as either occluded, or if hwnd IsIconic, hidden. void MarkNonIconicWindowsOccluded();
// Has ShutDown been called on us? We might have survived if our thread join // timed out. bool mHasAttemptedShutdown = false;
// Map of HWND to widget. Maintained on main thread, and used to send // occlusion state notifications to Windows from // mRootWindowHwndsOcclusionState.
std::unordered_map<HWND, nsWeakPtr> mHwndRootWindowMap;
// This is set by UpdateOcclusionState(). It is currently only used by tests. int mNumVisibleRootWindows = 0;
// If the screen is locked, windows are considered occluded. bool mScreenLocked = false;
// If the display is off, windows are considered occluded. bool mDisplayOn = true;
// Used to serialize tasks related to mRootWindowHwndsOcclusionState.
RefPtr<SerializedTaskDispatcher> mSerializedTaskDispatcher;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.