/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * 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/. */ #include"HeadlessWidget.h" #include"ErrorList.h" #include"HeadlessCompositorWidget.h" #include"BasicEvents.h" #include"MouseEvents.h" #include"mozilla/gfx/gfxVars.h" #include"mozilla/ClearOnShutdown.h" #include"mozilla/Maybe.h" #include"mozilla/NativeKeyBindingsType.h" #include"mozilla/Preferences.h" #include"mozilla/TextEventDispatcher.h" #include"mozilla/TextEvents.h" #include"mozilla/WritingModes.h" #include"mozilla/widget/HeadlessWidgetTypes.h" #include"mozilla/widget/PlatformWidgetTypes.h" #include"mozilla/widget/Screen.h" #include"nsIScreen.h" #include"HeadlessKeyBindings.h"
if (sActiveWindows) {
int32_t index = sActiveWindows->IndexOf(this); if (index != -1) {
RefPtr<HeadlessWidget> activeWindow = GetActiveWindow();
sActiveWindows->RemoveElementAt(index); // If this is the currently active widget and there's a previously active // widget, activate the previous widget.
RefPtr<HeadlessWidget> previousActiveWindow = GetActiveWindow(); if (this == activeWindow && previousActiveWindow &&
previousActiveWindow->mWidgetListener) {
previousActiveWindow->mWidgetListener->WindowActivated();
}
}
}
// Do nothing if this is the currently active window.
RefPtr<HeadlessWidget> activeWindow = GetActiveWindow(); if (activeWindow == this) { return;
}
// Deactivate the last active window. if (activeWindow && activeWindow->mWidgetListener) {
activeWindow->mWidgetListener->WindowDeactivated();
}
// Remove this window if it's already tracked.
int32_t index = sActiveWindows->IndexOf(this); if (index != -1) {
sActiveWindows->RemoveElementAt(index);
}
// Activate this window.
sActiveWindows->AppendElement(this); if (mWidgetListener) mWidgetListener->WindowActivated();
}
LOG(("HeadlessWidget::Show [%p] state %d\n", (void*)this, aState));
// Top-level window and dialogs are activated/raised when shown. // NB: alwaysontop windows are generally used for peripheral indicators, // so we don't focus them by default. if (aState && !mAlwaysOnTop &&
(mWindowType == WindowType::TopLevel ||
mWindowType == WindowType::Dialog)) {
RaiseWindow();
}
// This means we request activation of our toplevel window. if (aRaise == Raise::Yes) {
HeadlessWidget* topLevel = (HeadlessWidget*)GetTopLevelWidget();
// The toplevel only becomes active if it's currently visible; otherwise, it // will be activated anyway when it's shown. if (topLevel->IsVisible()) {
topLevel->RaiseWindow();
}
}
}
void HeadlessWidget::MoveInternal(int32_t aX, int32_t aY) { // Since a popup window's x/y coordinates are in relation to // the parent, the parent might have moved so we always move a // popup window. if (mBounds.IsEqualXY(aX, aY) && mWindowType != WindowType::Popup) { return;
}
// Normally in real widget backends a window event would be triggered that // would cause the window manager to handle resizing the window. In headless // the window must manually be resized.
ApplySizeModeSideEffects();
}
if (mEffectiveSizeMode == nsSizeMode_Normal) { // Store the last normal size bounds so it can be restored when entering // normal mode again.
mRestoreBounds = mBounds;
}
switch (mSizeMode) { case nsSizeMode_Normal: {
MoveInternal(mRestoreBounds.X(), mRestoreBounds.Y());
ResizeInternal(mRestoreBounds.Width(), mRestoreBounds.Height(), false); break;
} case nsSizeMode_Minimized: break; case nsSizeMode_Maximized: {
nsCOMPtr<nsIScreen> screen = GetWidgetScreen(); if (screen) {
int32_t left, top, width, height; if (NS_SUCCEEDED(
screen->GetRectDisplayPix(&left, &top, &width, &height))) {
MoveInternal(0, 0);
ResizeInternal(width, height, true);
}
} break;
} case nsSizeMode_Fullscreen: // This will take care of resizing the window.
nsBaseWidget::InfallibleMakeFullScreen(true); break; default: break;
}
mEffectiveSizeMode = mSizeMode; if (mWidgetListener) {
mWidgetListener->SizeModeChanged(mSizeMode);
}
}
nsresult HeadlessWidget::MakeFullScreen(bool aFullScreen) { // Directly update the size mode here so a later call SetSizeMode does // nothing. if (aFullScreen) { if (mSizeMode != nsSizeMode_Fullscreen) {
mLastSizeMode = mSizeMode;
}
mSizeMode = nsSizeMode_Fullscreen;
} else {
mSizeMode = mLastSizeMode;
}
// Notify the listener first so size mode change events are triggered before // resize events. if (mWidgetListener) {
mWidgetListener->SizeModeChanged(mSizeMode);
}
// Real widget backends don't seem to follow a common approach for // when and how many resize events are triggered during fullscreen // transitions. InfallibleMakeFullScreen will trigger a resize, but it // will be ignored if still transitioning to fullscreen, so it must be // triggered on the next tick.
RefPtr<HeadlessWidget> self(this);
NS_DispatchToCurrentThread(NS_NewRunnableFunction( "HeadlessWidget::MakeFullScreen", [self, aFullScreen]() -> void {
self->InfallibleMakeFullScreen(aFullScreen);
}));
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.