зеркало из https://github.com/mozilla/gecko-dev.git
Bug 533200: [OS/2] Replace nsFrameWindow with os2FrameWindow r=wuno
This commit is contained in:
Родитель
454cbf1f10
Коммит
9495bc48b9
|
@ -61,7 +61,7 @@ CPPSRCS = \
|
|||
nsBidiKeyboard.cpp \
|
||||
nsClipboard.cpp \
|
||||
nsFilePicker.cpp \
|
||||
nsFrameWindow.cpp \
|
||||
os2FrameWindow.cpp \
|
||||
nsLookAndFeel.cpp \
|
||||
nsOS2Uni.cpp \
|
||||
nsPrintOS2.cpp \
|
||||
|
|
|
@ -1,505 +0,0 @@
|
|||
/* vim: set sw=2 sts=2 et cin: */
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Mozilla OS/2 libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* John Fairhurst, <john_fairhurst@iname.com>.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Rich Walsh <dragtext@e-vertise.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK *****
|
||||
*
|
||||
* This Original Code has been modified by IBM Corporation.
|
||||
* Modifications made by IBM are
|
||||
* Copyright (c) International Business Machines Corporation, 2000
|
||||
*
|
||||
*/
|
||||
//=============================================================================
|
||||
|
||||
#include "nsFrameWindow.h"
|
||||
#include "nsIRollupListener.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
extern nsIRollupListener* gRollupListener;
|
||||
extern nsIWidget* gRollupWidget;
|
||||
extern PRBool gRollupConsumeRollupEvent;
|
||||
extern PRUint32 gOS2Flags;
|
||||
|
||||
#ifdef DEBUG_FOCUS
|
||||
extern int currentWindowIdentifier;
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
// nsFrameWindow Setup
|
||||
//=============================================================================
|
||||
|
||||
nsFrameWindow::nsFrameWindow() : nsWindow()
|
||||
{
|
||||
mPrevFrameProc = 0;
|
||||
mWindowType = eWindowType_toplevel;
|
||||
mNeedActivation = PR_FALSE;
|
||||
}
|
||||
|
||||
nsFrameWindow::~nsFrameWindow()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Create frame & client windows for an nsFrameWindow object
|
||||
|
||||
nsresult nsFrameWindow::CreateWindow(nsWindow* aParent,
|
||||
HWND aParentWnd,
|
||||
const nsIntRect& aRect,
|
||||
PRUint32 aStyle)
|
||||
{
|
||||
// top-level widget windows (i.e nsFrameWindow) are created for
|
||||
// windows of types eWindowType_toplevel, *_dialog, & *_invisible
|
||||
mIsTopWidgetWindow = PR_TRUE;
|
||||
|
||||
// Create a frame window with a MozillaWindowClass window as its client.
|
||||
PRUint32 fcfFlags = GetFCFlags();
|
||||
mFrameWnd = WinCreateStdWindow(HWND_DESKTOP,
|
||||
0,
|
||||
(ULONG*)&fcfFlags,
|
||||
kWindowClassName,
|
||||
"Title",
|
||||
aStyle,
|
||||
NULLHANDLE,
|
||||
0,
|
||||
&mWnd);
|
||||
NS_ENSURE_TRUE(mFrameWnd, NS_ERROR_FAILURE);
|
||||
|
||||
// Hide from the Window List until shown.
|
||||
SetWindowListVisibility(PR_FALSE);
|
||||
|
||||
// This prevents a modal dialog from being covered by its disabled parent.
|
||||
if (aParentWnd != HWND_DESKTOP) {
|
||||
WinSetOwner(mFrameWnd, aParentWnd);
|
||||
}
|
||||
|
||||
// Set the frame control HWNDs as properties for use by fullscreen mode.
|
||||
HWND hTemp = WinWindowFromID(mFrameWnd, FID_TITLEBAR);
|
||||
WinSetProperty(mFrameWnd, "hwndTitleBar", (PVOID)hTemp, 0);
|
||||
hTemp = WinWindowFromID(mFrameWnd, FID_SYSMENU);
|
||||
WinSetProperty(mFrameWnd, "hwndSysMenu", (PVOID)hTemp, 0);
|
||||
hTemp = WinWindowFromID(mFrameWnd, FID_MINMAX);
|
||||
WinSetProperty(mFrameWnd, "hwndMinMax", (PVOID)hTemp, 0);
|
||||
|
||||
// Establish a minimum height or else some dialogs will be truncated.
|
||||
PRInt32 minHeight;
|
||||
if (fcfFlags & FCF_SIZEBORDER) {
|
||||
minHeight = 2 * WinQuerySysValue(HWND_DESKTOP, SV_CYSIZEBORDER);
|
||||
} else if (fcfFlags & FCF_DLGBORDER) {
|
||||
minHeight = 2 * WinQuerySysValue(HWND_DESKTOP, SV_CYDLGFRAME);
|
||||
} else {
|
||||
minHeight = 2 * WinQuerySysValue(HWND_DESKTOP, SV_CYBORDER);
|
||||
}
|
||||
if (fcfFlags & FCF_TITLEBAR) {
|
||||
minHeight += WinQuerySysValue(HWND_DESKTOP, SV_CYTITLEBAR);
|
||||
}
|
||||
|
||||
// Store the frame's adjusted dimensions, move & resize accordingly,
|
||||
// then calculate the client's dimensions.
|
||||
mBounds = aRect;
|
||||
if (mBounds.height < minHeight) {
|
||||
mBounds.height = minHeight;
|
||||
}
|
||||
PRInt32 pmY = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN)
|
||||
- mBounds.y - mBounds.height;
|
||||
WinSetWindowPos(mFrameWnd, 0, mBounds.x, pmY,
|
||||
mBounds.width, mBounds.height, SWP_SIZE | SWP_MOVE);
|
||||
UpdateClientSize();
|
||||
|
||||
// Subclass the frame; the client will be subclassed by Create().
|
||||
mPrevFrameProc = WinSubclassWindow(mFrameWnd, fnwpFrame);
|
||||
WinSetWindowPtr(mFrameWnd, QWL_USER, this);
|
||||
|
||||
DEBUGFOCUS(Create nsFrameWindow);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
PRUint32 nsFrameWindow::GetFCFlags()
|
||||
{
|
||||
PRUint32 style = FCF_TITLEBAR | FCF_SYSMENU | FCF_TASKLIST |
|
||||
FCF_CLOSEBUTTON | FCF_NOBYTEALIGN | FCF_AUTOICON;
|
||||
|
||||
if (mWindowType == eWindowType_dialog) {
|
||||
if (mBorderStyle == eBorderStyle_default) {
|
||||
style |= FCF_DLGBORDER;
|
||||
} else {
|
||||
style |= FCF_SIZEBORDER | FCF_MINMAX;
|
||||
}
|
||||
}
|
||||
else {
|
||||
style |= FCF_SIZEBORDER | FCF_MINMAX;
|
||||
}
|
||||
|
||||
if (gOS2Flags & kIsDBCS) {
|
||||
style |= FCF_DBE_APPSTAT;
|
||||
}
|
||||
if (mWindowType == eWindowType_invisible) {
|
||||
style &= ~FCF_TASKLIST;
|
||||
}
|
||||
|
||||
if (mBorderStyle != eBorderStyle_default &&
|
||||
mBorderStyle != eBorderStyle_all) {
|
||||
if (mBorderStyle == eBorderStyle_none ||
|
||||
!(mBorderStyle & eBorderStyle_resizeh)) {
|
||||
style &= ~FCF_SIZEBORDER;
|
||||
style |= FCF_DLGBORDER;
|
||||
}
|
||||
if (mBorderStyle == eBorderStyle_none ||
|
||||
!(mBorderStyle & eBorderStyle_border)) {
|
||||
style &= ~(FCF_DLGBORDER | FCF_SIZEBORDER);
|
||||
}
|
||||
if (mBorderStyle == eBorderStyle_none ||
|
||||
!(mBorderStyle & eBorderStyle_title)) {
|
||||
style &= ~(FCF_TITLEBAR | FCF_TASKLIST);
|
||||
}
|
||||
if (mBorderStyle == eBorderStyle_none ||
|
||||
!(mBorderStyle & eBorderStyle_close)) {
|
||||
style &= ~FCF_CLOSEBUTTON;
|
||||
}
|
||||
if (mBorderStyle == eBorderStyle_none ||
|
||||
!(mBorderStyle & (eBorderStyle_menu | eBorderStyle_close))) {
|
||||
style &= ~FCF_SYSMENU;
|
||||
}
|
||||
|
||||
// Looks like getting rid of the system menu also does away
|
||||
// with the close box. So, we only get rid of the system menu
|
||||
// if you want neither it nor the close box.
|
||||
|
||||
if (mBorderStyle == eBorderStyle_none ||
|
||||
!(mBorderStyle & eBorderStyle_minimize)) {
|
||||
style &= ~FCF_MINBUTTON;
|
||||
}
|
||||
if (mBorderStyle == eBorderStyle_none ||
|
||||
!(mBorderStyle & eBorderStyle_maximize)) {
|
||||
style &= ~FCF_MAXBUTTON;
|
||||
}
|
||||
}
|
||||
|
||||
return style;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// Window Operations
|
||||
//=============================================================================
|
||||
|
||||
// For frame windows, 'Show' is equivalent to 'Show & Activate'
|
||||
|
||||
NS_METHOD nsFrameWindow::Show(PRBool aState)
|
||||
{
|
||||
if (!mWnd) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRUint32 ulFlags;
|
||||
if (!aState) {
|
||||
ulFlags = SWP_HIDE | SWP_DEACTIVATE;
|
||||
} else {
|
||||
ulFlags = SWP_SHOW;
|
||||
|
||||
// Don't activate the window unless the parent is visible
|
||||
if (WinIsWindowVisible(WinQueryWindow(mFrameWnd, QW_PARENT))) {
|
||||
ulFlags |= SWP_ACTIVATE;
|
||||
}
|
||||
|
||||
PRUint32 ulStyle = WinQueryWindowULong(mFrameWnd, QWL_STYLE);
|
||||
if (!(ulStyle & WS_VISIBLE)) {
|
||||
PRInt32 sizeMode;
|
||||
GetSizeMode(&sizeMode);
|
||||
if (sizeMode == nsSizeMode_Maximized) {
|
||||
ulFlags |= SWP_MAXIMIZE;
|
||||
} else if (sizeMode == nsSizeMode_Minimized) {
|
||||
ulFlags |= SWP_MINIMIZE;
|
||||
} else {
|
||||
ulFlags |= SWP_RESTORE;
|
||||
}
|
||||
}
|
||||
if (ulStyle & WS_MINIMIZED) {
|
||||
ulFlags |= (SWP_RESTORE | SWP_MAXIMIZE);
|
||||
}
|
||||
}
|
||||
|
||||
WinSetWindowPos(mFrameWnd, 0, 0, 0, 0, 0, ulFlags);
|
||||
SetWindowListVisibility(aState);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_METHOD nsFrameWindow::GetClientBounds(nsIntRect& aRect)
|
||||
{
|
||||
RECTL rcl = { 0, 0, mBounds.width, mBounds.height };
|
||||
WinCalcFrameRect(mFrameWnd, &rcl, TRUE); // provided == frame rect
|
||||
aRect.x = rcl.xLeft;
|
||||
aRect.y = mBounds.height - rcl.yTop;
|
||||
aRect.width = mSizeClient.width;
|
||||
aRect.height = mSizeClient.height;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void nsFrameWindow::UpdateClientSize()
|
||||
{
|
||||
RECTL rcl = { 0, 0, mBounds.width, mBounds.height };
|
||||
WinCalcFrameRect(mFrameWnd, &rcl, TRUE); // provided == frame rect
|
||||
mSizeClient.width = rcl.xRight - rcl.xLeft;
|
||||
mSizeClient.height = rcl.yTop - rcl.yBottom;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// When WM_ACTIVATE is received with the "gaining activation" flag set,
|
||||
// the frame's wndproc sets mNeedActivation. Later, when an nsWindow
|
||||
// gets a WM_FOCUSCHANGED msg with the "gaining focus" flag set, it
|
||||
// invokes this method on nsFrameWindow to fire an NS_ACTIVATE event.
|
||||
|
||||
void nsFrameWindow::ActivateTopLevelWidget()
|
||||
{
|
||||
// Don't fire event if we're minimized or else the window will
|
||||
// be restored as soon as the user clicks on it. When the user
|
||||
// explicitly restores it, SetSizeMode() will call this method.
|
||||
|
||||
if (mNeedActivation) {
|
||||
PRInt32 sizeMode;
|
||||
GetSizeMode(&sizeMode);
|
||||
if (sizeMode != nsSizeMode_Minimized) {
|
||||
mNeedActivation = PR_FALSE;
|
||||
DEBUGFOCUS(NS_ACTIVATE);
|
||||
DispatchActivationEvent(NS_ACTIVATE);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Just ignore this callback; the correct stuff is done in the frame wp.
|
||||
|
||||
PRBool nsFrameWindow::OnReposition(PSWP pSwp)
|
||||
{
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void nsFrameWindow::SetWindowListVisibility(PRBool aState)
|
||||
{
|
||||
HSWITCH hswitch = WinQuerySwitchHandle(mFrameWnd, 0);
|
||||
if (hswitch) {
|
||||
SWCNTRL swctl;
|
||||
WinQuerySwitchEntry(hswitch, &swctl);
|
||||
swctl.uchVisibility = aState ? SWL_VISIBLE : SWL_INVISIBLE;
|
||||
swctl.fbJump = aState ? SWL_JUMPABLE : SWL_NOTJUMPABLE;
|
||||
WinChangeSwitchEntry(hswitch, &swctl);
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// nsFrameWindow's Window Procedure
|
||||
//=============================================================================
|
||||
|
||||
// Subclass for frame window
|
||||
|
||||
MRESULT EXPENTRY fnwpFrame(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
|
||||
{
|
||||
// check to see if we have a rollup listener registered
|
||||
if (gRollupListener && gRollupWidget) {
|
||||
if (msg == WM_TRACKFRAME || msg == WM_MINMAXFRAME ||
|
||||
msg == WM_BUTTON1DOWN || msg == WM_BUTTON2DOWN ||
|
||||
msg == WM_BUTTON3DOWN) {
|
||||
// Rollup if the event is outside the popup
|
||||
if (!nsWindow::EventIsInsideWindow((nsWindow*)gRollupWidget)) {
|
||||
gRollupListener->Rollup(PR_UINT32_MAX, nsnull);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsFrameWindow* pFrame = (nsFrameWindow*)WinQueryWindowPtr(hwnd, QWL_USER);
|
||||
return pFrame->FrameMessage(msg, mp1, mp2);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Process messages from the frame
|
||||
|
||||
MRESULT nsFrameWindow::FrameMessage(ULONG msg, MPARAM mp1, MPARAM mp2)
|
||||
{
|
||||
MRESULT mresult = 0;
|
||||
PRBool bDone = PR_FALSE;
|
||||
|
||||
switch (msg) {
|
||||
case WM_WINDOWPOSCHANGED: {
|
||||
PSWP pSwp = (PSWP)mp1;
|
||||
|
||||
// Note that client windows never get 'move' messages
|
||||
if (pSwp->fl & SWP_MOVE && !(pSwp->fl & SWP_MINIMIZE)) {
|
||||
POINTL ptl = { pSwp->x, pSwp->y + pSwp->cy };
|
||||
ptl.y = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN) - ptl.y;
|
||||
mBounds.x = ptl.x;
|
||||
mBounds.y = ptl.y;
|
||||
DispatchMoveEvent(ptl.x, ptl.y);
|
||||
}
|
||||
|
||||
// When the frame is sized, do stuff to recalculate client size.
|
||||
if (pSwp->fl & SWP_SIZE && !(pSwp->fl & SWP_MINIMIZE)) {
|
||||
mresult = (*mPrevFrameProc)(mFrameWnd, msg, mp1, mp2);
|
||||
bDone = PR_TRUE;
|
||||
mBounds.width = pSwp->cx;
|
||||
mBounds.height = pSwp->cy;
|
||||
UpdateClientSize();
|
||||
DispatchResizeEvent(mSizeClient.width, mSizeClient.height);
|
||||
}
|
||||
|
||||
if (pSwp->fl & (SWP_MAXIMIZE | SWP_MINIMIZE | SWP_RESTORE)) {
|
||||
nsSizeModeEvent event(PR_TRUE, NS_SIZEMODE, this);
|
||||
if (pSwp->fl & SWP_MAXIMIZE) {
|
||||
event.mSizeMode = nsSizeMode_Maximized;
|
||||
} else if (pSwp->fl & SWP_MINIMIZE) {
|
||||
event.mSizeMode = nsSizeMode_Minimized;
|
||||
} else {
|
||||
event.mSizeMode = nsSizeMode_Normal;
|
||||
}
|
||||
InitEvent(event);
|
||||
DispatchWindowEvent(&event);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// a frame window in kiosk/fullscreen mode must have its frame
|
||||
// controls reattached before it's minimized & detached after it's
|
||||
// restored; if this doesn't happen at the correct times, clicking
|
||||
// on the icon won't restore it, the sysmenu will have the wrong
|
||||
// items, and/or the minmax button will have the wrong buttons
|
||||
|
||||
case WM_ADJUSTWINDOWPOS: {
|
||||
if (mChromeHidden && ((PSWP)mp1)->fl & SWP_MINIMIZE) {
|
||||
HWND hTemp = (HWND)WinQueryProperty(mFrameWnd, "hwndMinMax");
|
||||
if (hTemp) {
|
||||
WinSetParent(hTemp, mFrameWnd, TRUE);
|
||||
}
|
||||
hTemp = (HWND)WinQueryProperty(mFrameWnd, "hwndTitleBar");
|
||||
if (hTemp) {
|
||||
WinSetParent(hTemp, mFrameWnd, TRUE);
|
||||
}
|
||||
hTemp = (HWND)WinQueryProperty(mFrameWnd, "hwndSysMenu");
|
||||
if (hTemp) {
|
||||
WinSetParent(hTemp, mFrameWnd, TRUE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_ADJUSTFRAMEPOS: {
|
||||
if (mChromeHidden && ((PSWP)mp1)->fl & SWP_RESTORE) {
|
||||
HWND hTemp = (HWND)WinQueryProperty(mFrameWnd, "hwndSysMenu");
|
||||
if (hTemp) {
|
||||
WinSetParent(hTemp, HWND_OBJECT, TRUE);
|
||||
}
|
||||
hTemp = (HWND)WinQueryProperty(mFrameWnd, "hwndTitleBar");
|
||||
if (hTemp) {
|
||||
WinSetParent(hTemp, HWND_OBJECT, TRUE);
|
||||
}
|
||||
hTemp = (HWND)WinQueryProperty(mFrameWnd, "hwndMinMax");
|
||||
if (hTemp) {
|
||||
WinSetParent(hTemp, HWND_OBJECT, TRUE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_DESTROY:
|
||||
DEBUGFOCUS(frame WM_DESTROY);
|
||||
WinSubclassWindow(mFrameWnd, mPrevFrameProc);
|
||||
WinSetWindowPtr(mFrameWnd, QWL_USER, 0);
|
||||
WinRemoveProperty(mFrameWnd, "hwndTitleBar");
|
||||
WinRemoveProperty(mFrameWnd, "hwndSysMenu");
|
||||
WinRemoveProperty(mFrameWnd, "hwndMinMax");
|
||||
WinRemoveProperty(mFrameWnd, "ulStyle");
|
||||
break;
|
||||
|
||||
case WM_INITMENU:
|
||||
// If we are in fullscreen/kiosk mode, disable maximize menu item
|
||||
if (mChromeHidden &&
|
||||
SHORT1FROMMP(mp1) == SC_SYSMENU &&
|
||||
WinQueryWindowULong(mFrameWnd, QWL_STYLE) & WS_MINIMIZED) {
|
||||
MENUITEM menuitem;
|
||||
WinSendMsg(WinWindowFromID(mFrameWnd, FID_SYSMENU), MM_QUERYITEM,
|
||||
MPFROM2SHORT(SC_SYSMENU, FALSE), MPARAM(&menuitem));
|
||||
mresult = (*mPrevFrameProc)(mFrameWnd, msg, mp1, mp2);
|
||||
WinEnableMenuItem(menuitem.hwndSubMenu, SC_MAXIMIZE, FALSE);
|
||||
bDone = PR_TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_SYSCOMMAND:
|
||||
// If we are in fullscreen/kiosk mode, don't honor maximize requests
|
||||
if (mChromeHidden &&
|
||||
SHORT1FROMMP(mp1) == SC_MAXIMIZE &&
|
||||
WinQueryWindowULong(mFrameWnd, QWL_STYLE) & WS_MINIMIZED) {
|
||||
bDone = PR_TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
// When the frame is activated, set a flag to be acted on after
|
||||
// PM has finished changing focus. When deactivated, dispatch
|
||||
// the event immediately because it doesn't affect the focus.
|
||||
case WM_ACTIVATE:
|
||||
DEBUGFOCUS(WM_ACTIVATE);
|
||||
if (mp1) {
|
||||
mNeedActivation = PR_TRUE;
|
||||
} else {
|
||||
mNeedActivation = PR_FALSE;
|
||||
DEBUGFOCUS(NS_DEACTIVATE);
|
||||
DispatchActivationEvent(NS_DEACTIVATE);
|
||||
// Prevent the frame from automatically focusing any window
|
||||
// when it's reactivated. Let moz set the focus to avoid
|
||||
// having non-widget children of plugins focused in error.
|
||||
WinSetWindowULong(mFrameWnd, QWL_HWNDFOCUSSAVE, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!bDone) {
|
||||
mresult = (*mPrevFrameProc)(mFrameWnd, msg, mp1, mp2);
|
||||
}
|
||||
|
||||
return mresult;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
|
@ -1,109 +0,0 @@
|
|||
/* vim: set sw=2 sts=2 et cin: */
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Mozilla OS/2 libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* John Fairhurst, <john_fairhurst@iname.com>.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Rich Walsh <dragtext@e-vertise.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
//=============================================================================
|
||||
/*
|
||||
* nsFrameWindow is a subclass of nsWindow and is created when NS_WINDOW_CID
|
||||
* is specified. It represents a top-level widget and is implemented as two
|
||||
* native windows, a frame (WC_FRAME) and a client (MozillaWindowClass).
|
||||
*
|
||||
* Most methods inherited from nsIWidget are handled by nsWindow. For those
|
||||
* which require slightly different implementations for top-level and child
|
||||
* widgets, nsWindow relies on a flag or on virtual helper methods to handle
|
||||
* the differences properly.
|
||||
*
|
||||
* There are two items where these differences are particularly important:
|
||||
* - mWnd identifies the frame's client which is seldom acted upon directly;
|
||||
* instead, most operations involve mFrameWnd.
|
||||
* - mBounds contains the dimensions of mFrameWnd, not mWnd whose width and
|
||||
* height are stored in mSizeClient.
|
||||
*
|
||||
*/
|
||||
//=============================================================================
|
||||
|
||||
#ifndef _nsframewindow_h
|
||||
#define _nsframewindow_h
|
||||
|
||||
#include "nsWindow.h"
|
||||
#include "nssize.h"
|
||||
|
||||
//=============================================================================
|
||||
// nsFrameWindow
|
||||
//=============================================================================
|
||||
|
||||
class nsFrameWindow : public nsWindow
|
||||
{
|
||||
public:
|
||||
nsFrameWindow();
|
||||
virtual ~nsFrameWindow();
|
||||
|
||||
// from nsIWidget
|
||||
virtual nsresult CreateWindow(nsWindow* aParent,
|
||||
HWND aParentWnd,
|
||||
const nsIntRect& aRect,
|
||||
PRUint32 aStyle);
|
||||
NS_IMETHOD Show(PRBool aState);
|
||||
NS_IMETHOD GetClientBounds(nsIntRect& aRect);
|
||||
|
||||
protected:
|
||||
// from nsWindow
|
||||
virtual HWND GetMainWindow() const {return mFrameWnd;}
|
||||
virtual void ActivateTopLevelWidget();
|
||||
virtual PRBool OnReposition(PSWP pSwp);
|
||||
virtual PRInt32 GetClientHeight() {return mSizeClient.height;}
|
||||
|
||||
// nsFrameWindow
|
||||
PRUint32 GetFCFlags();
|
||||
void UpdateClientSize();
|
||||
void SetWindowListVisibility(PRBool aState);
|
||||
MRESULT FrameMessage(ULONG msg, MPARAM mp1, MPARAM mp2);
|
||||
|
||||
friend MRESULT EXPENTRY fnwpFrame(HWND hwnd, ULONG msg,
|
||||
MPARAM mp1, MPARAM mp2);
|
||||
|
||||
PFNWP mPrevFrameProc;
|
||||
nsSize mSizeClient;
|
||||
PRBool mNeedActivation;
|
||||
};
|
||||
|
||||
#endif //_nsframewindow_h
|
||||
|
||||
//=============================================================================
|
||||
|
|
@ -84,9 +84,6 @@
|
|||
#include "nsDeviceContextSpecOS2.h"
|
||||
#include "nsPrintOptionsOS2.h"
|
||||
#include "nsPrintSession.h"
|
||||
|
||||
#include "nsFrameWindow.h" // OS/2 only
|
||||
|
||||
#include "nsIdleServiceOS2.h"
|
||||
|
||||
// objects that just require generic constructors
|
||||
|
@ -95,7 +92,7 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsWindow)
|
|||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsClipboard)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsClipboardHelper)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsFilePicker)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsFrameWindow)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsChildWindow)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsLookAndFeel)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSound)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsToolkit)
|
||||
|
@ -124,7 +121,7 @@ static const nsModuleComponentInfo components[] =
|
|||
{ "OS/2 Child Window",
|
||||
NS_CHILD_CID,
|
||||
"@mozilla.org/widget/child_window/os2;1",
|
||||
nsWindowConstructor },
|
||||
nsChildWindowConstructor },
|
||||
{ "OS/2 Clipboard",
|
||||
NS_CLIPBOARD_CID,
|
||||
"@mozilla.org/widget/clipboard;1",
|
||||
|
@ -153,10 +150,10 @@ static const nsModuleComponentInfo components[] =
|
|||
NS_TOOLKIT_CID,
|
||||
"@mozilla.org/widget/toolkit/os2;1",
|
||||
nsToolkitConstructor },
|
||||
{ "OS/2 Frame Window",
|
||||
{ "OS/2 Window",
|
||||
NS_WINDOW_CID,
|
||||
"@mozilla.org/widget/window/os2;1",
|
||||
nsFrameWindowConstructor },
|
||||
nsWindowConstructor },
|
||||
{ "OS/2 Transferable",
|
||||
NS_TRANSFERABLE_CID,
|
||||
"@mozilla.org/widget/transferable;1",
|
||||
|
|
|
@ -66,6 +66,7 @@
|
|||
//=============================================================================
|
||||
|
||||
#include "nsWindow.h"
|
||||
#include "os2FrameWindow.h"
|
||||
#include "gfxContext.h"
|
||||
#include "gfxOS2Surface.h"
|
||||
#include "imgIContainer.h"
|
||||
|
@ -166,11 +167,21 @@
|
|||
// name of the window class used to clip plugins
|
||||
#define kClipWndClass "nsClipWnd"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Debug
|
||||
|
||||
#ifdef DEBUG_FOCUS
|
||||
#define DEBUGFOCUS(what) fprintf(stderr, "[%8x] %8lx (%02d) "#what"\n", \
|
||||
(int)this, mWnd, mWindowIdentifier)
|
||||
#else
|
||||
#define DEBUGFOCUS(what)
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
// Variables & Forward declarations
|
||||
//=============================================================================
|
||||
|
||||
// Rollup Listener - used by nsWindow & nsFrameWindow
|
||||
// Rollup Listener - used by nsWindow & os2FrameWindow
|
||||
nsIRollupListener* gRollupListener = 0;
|
||||
nsIMenuRollup* gMenuRollup = 0;
|
||||
nsIWidget* gRollupWidget = 0;
|
||||
|
@ -204,8 +215,8 @@ nsWindow::nsWindow() : nsBaseWidget()
|
|||
{
|
||||
mWnd = 0;
|
||||
mParent = 0;
|
||||
mIsTopWidgetWindow = PR_FALSE;
|
||||
mWindowType = eWindowType_child;
|
||||
mFrame = 0;
|
||||
mWindowType = eWindowType_toplevel;
|
||||
mBorderStyle = eBorderStyle_default;
|
||||
mWindowState = nsWindowState_ePrecreate;
|
||||
mOnDestroyCalled = PR_FALSE;
|
||||
|
@ -217,10 +228,6 @@ nsWindow::nsWindow() : nsBaseWidget()
|
|||
mCssCursorHPtr = 0;
|
||||
mThebesSurface = 0;
|
||||
|
||||
mFrameWnd = 0;
|
||||
mFrameIcon = 0;
|
||||
mChromeHidden = PR_FALSE;
|
||||
|
||||
if (!gOS2Flags) {
|
||||
InitGlobals();
|
||||
}
|
||||
|
@ -239,10 +246,6 @@ nsWindow::~nsWindow()
|
|||
// may even be illegal to call them from here.
|
||||
|
||||
mIsDestroying = PR_TRUE;
|
||||
if (mFrameIcon) {
|
||||
WinFreeFileIcon(mFrameIcon);
|
||||
mFrameIcon = 0;
|
||||
}
|
||||
|
||||
if (mCssCursorHPtr) {
|
||||
WinDestroyPointer(mCssCursorHPtr);
|
||||
|
@ -257,6 +260,12 @@ nsWindow::~nsWindow()
|
|||
nsWindowState_eInCreate);
|
||||
Destroy();
|
||||
}
|
||||
|
||||
// If it exists, destroy our os2FrameWindow helper object.
|
||||
if (mFrame) {
|
||||
delete mFrame;
|
||||
mFrame = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -316,7 +325,7 @@ void nsWindow::ReleaseGlobals()
|
|||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Init an nsWindow or nsFrameWindow & create the appropriate native window.
|
||||
// Init an nsWindow & create the appropriate native window.
|
||||
|
||||
NS_METHOD nsWindow::Create(nsIWidget* aParent,
|
||||
nsNativeWidget aNativeParent,
|
||||
|
@ -327,12 +336,11 @@ NS_METHOD nsWindow::Create(nsIWidget* aParent,
|
|||
nsIToolkit* aToolkit,
|
||||
nsWidgetInitData* aInitData)
|
||||
{
|
||||
nsresult rv;
|
||||
mWindowState = nsWindowState_eInCreate;
|
||||
|
||||
// Identify the parent's nsWindow & native window. Only one of these
|
||||
// should be supplied. Note: only nsWindow saves pParent as mParent;
|
||||
// nsFrameWindow discards it since toplevel widgets have no parent.
|
||||
// os2FrameWindow discards it since toplevel widgets have no parent.
|
||||
HWND hParent;
|
||||
nsWindow* pParent;
|
||||
if (aParent) {
|
||||
|
@ -357,7 +365,7 @@ NS_METHOD nsWindow::Create(nsIWidget* aParent,
|
|||
NS_ADDREF(mContext);
|
||||
} else {
|
||||
static NS_DEFINE_IID(kDeviceContextCID, NS_DEVICE_CONTEXT_CID);
|
||||
rv = CallCreateInstance(kDeviceContextCID, &mContext);
|
||||
nsresult rv = CallCreateInstance(kDeviceContextCID, &mContext);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
mContext->Init(nsnull);
|
||||
}
|
||||
|
@ -375,30 +383,34 @@ NS_METHOD nsWindow::Create(nsIWidget* aParent,
|
|||
NS_ADDREF(mToolkit);
|
||||
}
|
||||
|
||||
// Some basic initialization.
|
||||
PRUint32 style = WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
|
||||
if (aInitData) {
|
||||
// While we comply with the clipSiblings flag, we always set
|
||||
// clipChildren regardless of the flag for performance reasons.
|
||||
if (!aInitData->clipSiblings) {
|
||||
style &= ~WS_CLIPSIBLINGS;
|
||||
}
|
||||
mWindowType = aInitData->mWindowType;
|
||||
mBorderStyle = aInitData->mBorderStyle;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_FOCUS
|
||||
mWindowIdentifier = currentWindowIdentifier;
|
||||
currentWindowIdentifier++;
|
||||
#endif
|
||||
|
||||
// This is virtual and creates the appropriate type of window for
|
||||
// the class. It also does a few other class-specific chores.
|
||||
rv = CreateWindow(pParent, hParent, aRect, style);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
// Some basic initialization.
|
||||
if (aInitData) {
|
||||
mWindowType = aInitData->mWindowType;
|
||||
mBorderStyle = aInitData->mBorderStyle;
|
||||
}
|
||||
|
||||
// Both versions of CreateWindow() create a MozillaWindow
|
||||
// class window that needs to store this object's pointer.
|
||||
// For toplevel windows, create an instance of our helper class,
|
||||
// then have it create a frame & client window; otherwise,
|
||||
// call our own CreateWindow() method to create a child window.
|
||||
if (mWindowType == eWindowType_toplevel ||
|
||||
mWindowType == eWindowType_dialog ||
|
||||
mWindowType == eWindowType_invisible) {
|
||||
mFrame = new os2FrameWindow(this);
|
||||
NS_ENSURE_TRUE(mFrame, NS_ERROR_FAILURE);
|
||||
mWnd = mFrame->CreateFrameWindow(pParent, hParent, aRect,
|
||||
mWindowType, mBorderStyle);
|
||||
NS_ENSURE_TRUE(mWnd, NS_ERROR_FAILURE);
|
||||
} else {
|
||||
nsresult rv = CreateWindow(pParent, hParent, aRect, aInitData);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
// Store a pointer to this object in the window's extra bytes.
|
||||
SetNSWindowPtr(mWnd, this);
|
||||
|
||||
// Finalize the widget creation process.
|
||||
|
@ -407,7 +419,7 @@ NS_METHOD nsWindow::Create(nsIWidget* aParent,
|
|||
DispatchWindowEvent(&event);
|
||||
|
||||
mWindowState = nsWindowState_eLive;
|
||||
return rv;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -416,7 +428,7 @@ NS_METHOD nsWindow::Create(nsIWidget* aParent,
|
|||
nsresult nsWindow::CreateWindow(nsWindow* aParent,
|
||||
HWND aParentWnd,
|
||||
const nsIntRect& aRect,
|
||||
PRUint32 aStyle)
|
||||
nsWidgetInitData* aInitData)
|
||||
{
|
||||
// For pop-ups, the Desktop is the parent and aParentWnd is the owner.
|
||||
HWND hOwner = 0;
|
||||
|
@ -425,11 +437,18 @@ nsresult nsWindow::CreateWindow(nsWindow* aParent,
|
|||
aParentWnd = HWND_DESKTOP;
|
||||
}
|
||||
|
||||
// While we comply with the clipSiblings flag, we always set
|
||||
// clipChildren regardless of the flag for performance reasons.
|
||||
PRUint32 style = WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
|
||||
if (aInitData && !aInitData->clipSiblings) {
|
||||
style &= ~WS_CLIPSIBLINGS;
|
||||
}
|
||||
|
||||
// Create the window hidden; it will be resized below.
|
||||
mWnd = WinCreateWindow(aParentWnd,
|
||||
kWindowClassName,
|
||||
0,
|
||||
aStyle,
|
||||
style,
|
||||
0, 0, 0, 0,
|
||||
hOwner,
|
||||
HWND_TOP,
|
||||
|
@ -488,9 +507,7 @@ NS_METHOD nsWindow::Destroy()
|
|||
CaptureRollupEvents(nsnull, nsnull, PR_FALSE, PR_TRUE);
|
||||
}
|
||||
|
||||
// Since this may be called by the destructor, don't use
|
||||
// GetMainWindow() which is virtual (and will cause a crash).
|
||||
HWND hMain = mFrameWnd ? mFrameWnd : mWnd;
|
||||
HWND hMain = GetMainWindow();
|
||||
if (hMain) {
|
||||
DEBUGFOCUS(Destroy);
|
||||
if (hMain == WinQueryFocus(HWND_DESKTOP)) {
|
||||
|
@ -505,8 +522,19 @@ NS_METHOD nsWindow::Destroy()
|
|||
// Standard Window Operations
|
||||
//=============================================================================
|
||||
|
||||
// This can't be inlined in nsWindow.h because it doesn't know about
|
||||
// GetFrameWnd().
|
||||
|
||||
inline HWND nsWindow::GetMainWindow()
|
||||
{
|
||||
return mFrame ? mFrame->GetFrameWnd() : mWnd;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Inline this here for consistency (and a cleaner looking .h).
|
||||
|
||||
// static
|
||||
nsWindow* nsWindow::GetNSWindowPtr(HWND aWnd)
|
||||
inline nsWindow* nsWindow::GetNSWindowPtr(HWND aWnd)
|
||||
{
|
||||
return (nsWindow*)WinQueryWindowPtr(aWnd, QWL_NSWINDOWPTR);
|
||||
}
|
||||
|
@ -514,7 +542,7 @@ nsWindow* nsWindow::GetNSWindowPtr(HWND aWnd)
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
// static
|
||||
PRBool nsWindow::SetNSWindowPtr(HWND aWnd, nsWindow* aPtr)
|
||||
inline PRBool nsWindow::SetNSWindowPtr(HWND aWnd, nsWindow* aPtr)
|
||||
{
|
||||
return WinSetWindowPtr(aWnd, QWL_NSWINDOWPTR, aPtr);
|
||||
}
|
||||
|
@ -525,7 +553,7 @@ nsIWidget* nsWindow::GetParent()
|
|||
{
|
||||
// if this window isn't supposed to have a parent or it doesn't have
|
||||
// a parent, or if it or its parent is being destroyed, return null
|
||||
if (mIsTopWidgetWindow || mIsDestroying || mOnDestroyCalled ||
|
||||
if (mFrame || mIsDestroying || mOnDestroyCalled ||
|
||||
!mParent || mParent->mIsDestroying) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -555,10 +583,12 @@ NS_METHOD nsWindow::IsEnabled(PRBool* aState)
|
|||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsFrameWindow overrides this
|
||||
|
||||
NS_METHOD nsWindow::Show(PRBool aState)
|
||||
{
|
||||
if (mFrame) {
|
||||
return mFrame->Show(aState);
|
||||
}
|
||||
if (mWnd) {
|
||||
if (aState) {
|
||||
// don't try to show new windows (e.g. the Bookmark menu)
|
||||
|
@ -828,15 +858,21 @@ void nsWindow::Scroll(const nsIntPoint& aDelta,
|
|||
// Window Positioning
|
||||
//=============================================================================
|
||||
|
||||
// For toplevel windows, mBounds contains the dimensions of the client
|
||||
// window. os2FrameWindow's "override" returns the size of the frame.
|
||||
|
||||
NS_METHOD nsWindow::GetBounds(nsIntRect& aRect)
|
||||
{
|
||||
if (mFrame) {
|
||||
return mFrame->GetBounds(aRect);
|
||||
}
|
||||
aRect = mBounds;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsFrameWindow overrides this method. Since it is only invoked on toplevel
|
||||
// windows, this implementation for child windows should never get called.
|
||||
// Since mBounds contains the dimensions of the client, os2FrameWindow
|
||||
// doesn't have to provide any special handling for this method.
|
||||
|
||||
NS_METHOD nsWindow::GetClientBounds(nsIntRect& aRect)
|
||||
{
|
||||
|
@ -865,14 +901,14 @@ nsIntPoint nsWindow::WidgetToScreenOffset()
|
|||
// ptl is in this window's space
|
||||
void nsWindow::NS2PM(POINTL& ptl)
|
||||
{
|
||||
ptl.y = GetClientHeight() - ptl.y - 1;
|
||||
ptl.y = mBounds.height - ptl.y - 1;
|
||||
}
|
||||
|
||||
// rcl is in this window's space
|
||||
void nsWindow::NS2PM(RECTL& rcl)
|
||||
{
|
||||
LONG height = rcl.yTop - rcl.yBottom;
|
||||
rcl.yTop = GetClientHeight() - rcl.yBottom;
|
||||
rcl.yTop = mBounds.height - rcl.yBottom;
|
||||
rcl.yBottom = rcl.yTop - height;
|
||||
}
|
||||
|
||||
|
@ -882,7 +918,7 @@ void nsWindow::NS2PM_PARENT(POINTL& ptl)
|
|||
if (mParent) {
|
||||
mParent->NS2PM(ptl);
|
||||
} else {
|
||||
HWND hParent = WinQueryWindow(GetMainWindow(), QW_PARENT);
|
||||
HWND hParent = WinQueryWindow(mWnd, QW_PARENT);
|
||||
SWP swp;
|
||||
WinQueryWindowPos(hParent, &swp);
|
||||
ptl.y = swp.cy - ptl.y - 1;
|
||||
|
@ -893,9 +929,8 @@ void nsWindow::NS2PM_PARENT(POINTL& ptl)
|
|||
|
||||
NS_METHOD nsWindow::Move(PRInt32 aX, PRInt32 aY)
|
||||
{
|
||||
if (mWindowType == eWindowType_toplevel ||
|
||||
mWindowType == eWindowType_dialog) {
|
||||
SetSizeMode(nsSizeMode_Normal);
|
||||
if (mFrame) {
|
||||
return mFrame->Move(aX, aY);
|
||||
}
|
||||
Resize(aX, aY, mBounds.width, mBounds.height, PR_FALSE);
|
||||
return NS_OK;
|
||||
|
@ -905,6 +940,9 @@ NS_METHOD nsWindow::Move(PRInt32 aX, PRInt32 aY)
|
|||
|
||||
NS_METHOD nsWindow::Resize(PRInt32 aWidth, PRInt32 aHeight, PRBool aRepaint)
|
||||
{
|
||||
if (mFrame) {
|
||||
return mFrame->Resize(aWidth, aHeight, aRepaint);
|
||||
}
|
||||
Resize(mBounds.x, mBounds.y, aWidth, aHeight, aRepaint);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -914,6 +952,10 @@ NS_METHOD nsWindow::Resize(PRInt32 aWidth, PRInt32 aHeight, PRBool aRepaint)
|
|||
NS_METHOD nsWindow::Resize(PRInt32 aX, PRInt32 aY,
|
||||
PRInt32 aWidth, PRInt32 aHeight, PRBool aRepaint)
|
||||
{
|
||||
if (mFrame) {
|
||||
return mFrame->Resize(aX, aY, aWidth, aHeight, aRepaint);
|
||||
}
|
||||
|
||||
// For mWnd & eWindowType_child set the cached values upfront, see bug 286555.
|
||||
// For other mWnd types we defer transfer of values to mBounds to
|
||||
// WinSetWindowPos(), see bug 391421.
|
||||
|
@ -943,7 +985,7 @@ NS_METHOD nsWindow::Resize(PRInt32 aX, PRInt32 aY,
|
|||
&ptl, 1);
|
||||
}
|
||||
|
||||
if (!WinSetWindowPos(GetMainWindow(), 0, ptl.x, ptl.y, aWidth, aHeight,
|
||||
if (!WinSetWindowPos(mWnd, 0, ptl.x, ptl.y, aWidth, aHeight,
|
||||
SWP_MOVE | SWP_SIZE) && aRepaint) {
|
||||
WinInvalidateRect(mWnd, 0, FALSE);
|
||||
}
|
||||
|
@ -1183,277 +1225,57 @@ HWND nsWindow::GetPluginClipWindow(HWND aParentWnd)
|
|||
// Top-level (frame window) Operations
|
||||
//=============================================================================
|
||||
|
||||
// When a window gets the focus, call nsFrameWindow's version of this
|
||||
// When a window gets the focus, call os2FrameWindow's version of this
|
||||
// method. It will fire an NS_ACTIVATE event on the top-level widget
|
||||
// if appropriate.
|
||||
|
||||
void nsWindow::ActivateTopLevelWidget()
|
||||
{
|
||||
nsWindow* top = static_cast<nsWindow*>(GetTopLevelWidget());
|
||||
if (top) {
|
||||
top->ActivateTopLevelWidget();
|
||||
if (mFrame) {
|
||||
mFrame->ActivateTopLevelWidget();
|
||||
} else {
|
||||
nsWindow* top = static_cast<nsWindow*>(GetTopLevelWidget());
|
||||
if (top && top->mFrame) {
|
||||
top->mFrame->ActivateTopLevelWidget();
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Maximize, minimize or restore the window. When the frame has its
|
||||
// controls, this method is advisory because the min/max/restore has
|
||||
// already occurred. Only when the frame is in kiosk/fullscreen mode
|
||||
// does it perform the minimize or restore
|
||||
// All of these methods are inherently toplevel-only, and are in fact
|
||||
// only invoked on toplevel widgets. If they're invoked on a child
|
||||
// window, there's an error upstream.
|
||||
|
||||
NS_IMETHODIMP nsWindow::SetSizeMode(PRInt32 aMode)
|
||||
{
|
||||
NS_ENSURE_TRUE(mFrameWnd, NS_ERROR_UNEXPECTED);
|
||||
|
||||
PRInt32 previousMode;
|
||||
GetSizeMode(&previousMode);
|
||||
|
||||
// save the new state
|
||||
nsresult rv = nsBaseWidget::SetSizeMode(aMode);
|
||||
|
||||
// Minimized windows would get restored involuntarily if we fired an
|
||||
// NS_ACTIVATE when the user clicks on them. Instead, we defer the
|
||||
// activation event until the window has explicitly been restored.
|
||||
if (previousMode == nsSizeMode_Minimized && previousMode != aMode) {
|
||||
DEBUGFOCUS(deferred NS_ACTIVATE);
|
||||
ActivateTopLevelWidget();
|
||||
}
|
||||
|
||||
// nothing to do in these cases
|
||||
if (!NS_SUCCEEDED(rv) || !mChromeHidden || aMode == nsSizeMode_Maximized) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
ULONG ulStyle = WinQueryWindowULong(mFrameWnd, QWL_STYLE);
|
||||
|
||||
// act on the request if the frame isn't already in the requested state
|
||||
if (aMode == nsSizeMode_Minimized) {
|
||||
if (!(ulStyle & WS_MINIMIZED)) {
|
||||
WinSetWindowPos(mFrameWnd, HWND_BOTTOM, 0, 0, 0, 0,
|
||||
SWP_MINIMIZE | SWP_ZORDER | SWP_DEACTIVATE);
|
||||
}
|
||||
} else
|
||||
if (ulStyle & (WS_MAXIMIZED | WS_MINIMIZED)) {
|
||||
WinSetWindowPos(mFrameWnd, 0, 0, 0, 0, 0, SWP_RESTORE);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
NS_ENSURE_TRUE(mFrame, NS_ERROR_UNEXPECTED);
|
||||
return mFrame->SetSizeMode(aMode);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Hide or show the frame & its controls (titlebar, minmax, etc.).
|
||||
|
||||
NS_IMETHODIMP nsWindow::HideWindowChrome(PRBool aShouldHide)
|
||||
{
|
||||
NS_ENSURE_TRUE(mFrameWnd, NS_ERROR_UNEXPECTED);
|
||||
|
||||
// Putting a maximized window into fullscreen mode causes multiple
|
||||
// problems if it's later minimized & then restored. To avoid them,
|
||||
// restore maximized windows before putting them in fullscreen mode.
|
||||
if (WinQueryWindowULong(mFrameWnd, QWL_STYLE) & WS_MAXIMIZED) {
|
||||
WinSetWindowPos(mFrameWnd, 0, 0, 0, 0, 0, SWP_RESTORE | SWP_NOREDRAW);
|
||||
}
|
||||
|
||||
HWND hParent;
|
||||
if (aShouldHide) {
|
||||
hParent = HWND_OBJECT;
|
||||
mChromeHidden = PR_TRUE;
|
||||
} else {
|
||||
hParent = mFrameWnd;
|
||||
mChromeHidden = PR_FALSE;
|
||||
}
|
||||
|
||||
// Hide or show the frame controls.
|
||||
HWND hControl = (HWND)WinQueryProperty(mFrameWnd, "hwndTitleBar");
|
||||
if (hControl) {
|
||||
WinSetParent(hControl, hParent, FALSE);
|
||||
}
|
||||
hControl = (HWND)WinQueryProperty(mFrameWnd, "hwndSysMenu");
|
||||
if (hControl) {
|
||||
WinSetParent(hControl, hParent, FALSE);
|
||||
}
|
||||
hControl = (HWND)WinQueryProperty(mFrameWnd, "hwndMinMax");
|
||||
if (hControl) {
|
||||
WinSetParent(hControl, hParent, FALSE);
|
||||
}
|
||||
|
||||
// Modify the frame style, then advise it of the changes.
|
||||
if (aShouldHide) {
|
||||
ULONG ulStyle = WinQueryWindowULong(mFrameWnd, QWL_STYLE);
|
||||
WinSetProperty(mFrameWnd, "ulStyle", (PVOID)ulStyle, 0);
|
||||
WinSetWindowULong(mFrameWnd, QWL_STYLE, ulStyle & ~FS_SIZEBORDER);
|
||||
WinSendMsg(mFrameWnd, WM_UPDATEFRAME, 0, 0);
|
||||
} else {
|
||||
ULONG ulStyle = (ULONG)WinQueryProperty(mFrameWnd, "ulStyle");
|
||||
WinSetWindowULong(mFrameWnd, QWL_STYLE, ulStyle);
|
||||
WinSendMsg(mFrameWnd, WM_UPDATEFRAME,
|
||||
MPFROMLONG(FCF_TITLEBAR | FCF_SYSMENU | FCF_MINMAX), 0);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
NS_ENSURE_TRUE(mFrame, NS_ERROR_UNEXPECTED);
|
||||
return mFrame->HideWindowChrome(aShouldHide);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// On OS/2, if you pass a titlebar > 512 characters, it doesn't display at all.
|
||||
// We are going to limit our titlebars to 256 just to be on the safe side.
|
||||
|
||||
#define MAX_TITLEBAR_LENGTH 256
|
||||
|
||||
NS_METHOD nsWindow::SetTitle(const nsAString& aTitle)
|
||||
{
|
||||
NS_ENSURE_TRUE(mFrameWnd, NS_ERROR_UNEXPECTED);
|
||||
|
||||
PRUnichar* uchtemp = ToNewUnicode(aTitle);
|
||||
for (PRUint32 i = 0; i < aTitle.Length(); i++) {
|
||||
switch (uchtemp[i]) {
|
||||
case 0x2018:
|
||||
case 0x2019:
|
||||
uchtemp[i] = 0x0027;
|
||||
break;
|
||||
case 0x201C:
|
||||
case 0x201D:
|
||||
uchtemp[i] = 0x0022;
|
||||
break;
|
||||
case 0x2014:
|
||||
uchtemp[i] = 0x002D;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
nsAutoCharBuffer title;
|
||||
PRInt32 titleLength;
|
||||
WideCharToMultiByte(0, uchtemp, aTitle.Length(), title, titleLength);
|
||||
if (titleLength > MAX_TITLEBAR_LENGTH) {
|
||||
title[MAX_TITLEBAR_LENGTH] = '\0';
|
||||
}
|
||||
WinSetWindowText(mFrameWnd, title.Elements());
|
||||
|
||||
// If the chrome is hidden, set the text of the titlebar directly
|
||||
if (mChromeHidden) {
|
||||
HWND hTitleBar = (HWND)WinQueryProperty(mFrameWnd, "hwndTitleBar");
|
||||
WinSetWindowText(hTitleBar, title.Elements());
|
||||
}
|
||||
|
||||
nsMemory::Free(uchtemp);
|
||||
return NS_OK;
|
||||
NS_ENSURE_TRUE(mFrame, NS_ERROR_UNEXPECTED);
|
||||
return mFrame->SetTitle(aTitle);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// This implementation guarantees that sysmenus & minimized windows
|
||||
// will always have some icon other than the sysmenu default.
|
||||
|
||||
NS_METHOD nsWindow::SetIcon(const nsAString& aIconSpec)
|
||||
{
|
||||
NS_ENSURE_TRUE(mFrameWnd, NS_ERROR_UNEXPECTED);
|
||||
|
||||
static HPOINTER hDefaultIcon = 0;
|
||||
HPOINTER hWorkingIcon = 0;
|
||||
|
||||
// Assume the given string is a local identifier for an icon file.
|
||||
nsCOMPtr<nsILocalFile> iconFile;
|
||||
ResolveIconName(aIconSpec, NS_LITERAL_STRING(".ico"),
|
||||
getter_AddRefs(iconFile));
|
||||
|
||||
// if the file was found, try to use it
|
||||
if (iconFile) {
|
||||
nsCAutoString path;
|
||||
iconFile->GetNativePath(path);
|
||||
|
||||
if (mFrameIcon) {
|
||||
WinFreeFileIcon(mFrameIcon);
|
||||
}
|
||||
mFrameIcon = WinLoadFileIcon(path.get(), FALSE);
|
||||
hWorkingIcon = mFrameIcon;
|
||||
}
|
||||
|
||||
// if that doesn't work, use the app's icon (let's hope it can be
|
||||
// loaded because nobody should have to look at SPTR_APPICON - ugggh!)
|
||||
if (!hWorkingIcon) {
|
||||
if (!hDefaultIcon) {
|
||||
hDefaultIcon = WinLoadPointer(HWND_DESKTOP, 0, 1);
|
||||
if (!hDefaultIcon) {
|
||||
hDefaultIcon = WinQuerySysPointer(HWND_DESKTOP, SPTR_APPICON, FALSE);
|
||||
}
|
||||
}
|
||||
hWorkingIcon = hDefaultIcon;
|
||||
}
|
||||
|
||||
WinSendMsg(mFrameWnd, WM_SETICON, (MPARAM)hWorkingIcon, (MPARAM)0);
|
||||
return NS_OK;
|
||||
NS_ENSURE_TRUE(mFrame, NS_ERROR_UNEXPECTED);
|
||||
return mFrame->SetIcon(aIconSpec);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constrain a potential move to fit onscreen.
|
||||
|
||||
NS_METHOD nsWindow::ConstrainPosition(PRBool aAllowSlop,
|
||||
PRInt32* aX, PRInt32* aY)
|
||||
{
|
||||
NS_ENSURE_TRUE(mFrameWnd, NS_ERROR_UNEXPECTED);
|
||||
|
||||
// do we have enough info to do anything
|
||||
PRBool doConstrain = PR_FALSE;
|
||||
|
||||
// get our playing field. use the current screen, or failing
|
||||
// that for any reason, use device caps for the default screen.
|
||||
RECTL screenRect;
|
||||
|
||||
nsCOMPtr<nsIScreenManager> screenmgr =
|
||||
do_GetService("@mozilla.org/gfx/screenmanager;1");
|
||||
if (screenmgr) {
|
||||
nsCOMPtr<nsIScreen> screen;
|
||||
PRInt32 left, top, width, height;
|
||||
|
||||
// zero size rects confuse the screen manager
|
||||
width = mBounds.width > 0 ? mBounds.width : 1;
|
||||
height = mBounds.height > 0 ? mBounds.height : 1;
|
||||
screenmgr->ScreenForRect(*aX, *aY, width, height,
|
||||
getter_AddRefs(screen));
|
||||
if (screen) {
|
||||
screen->GetAvailRect(&left, &top, &width, &height);
|
||||
screenRect.xLeft = left;
|
||||
screenRect.xRight = left+width;
|
||||
screenRect.yTop = top;
|
||||
screenRect.yBottom = top+height;
|
||||
doConstrain = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
#define kWindowPositionSlop 100
|
||||
|
||||
if (doConstrain) {
|
||||
if (aAllowSlop) {
|
||||
if (*aX < screenRect.xLeft - mBounds.width + kWindowPositionSlop) {
|
||||
*aX = screenRect.xLeft - mBounds.width + kWindowPositionSlop;
|
||||
} else
|
||||
if (*aX >= screenRect.xRight - kWindowPositionSlop) {
|
||||
*aX = screenRect.xRight - kWindowPositionSlop;
|
||||
}
|
||||
|
||||
if (*aY < screenRect.yTop) {
|
||||
*aY = screenRect.yTop;
|
||||
} else
|
||||
if (*aY >= screenRect.yBottom - kWindowPositionSlop) {
|
||||
*aY = screenRect.yBottom - kWindowPositionSlop;
|
||||
}
|
||||
} else {
|
||||
if (*aX < screenRect.xLeft) {
|
||||
*aX = screenRect.xLeft;
|
||||
} else
|
||||
if (*aX >= screenRect.xRight - mBounds.width) {
|
||||
*aX = screenRect.xRight - mBounds.width;
|
||||
}
|
||||
|
||||
if (*aY < screenRect.yTop) {
|
||||
*aY = screenRect.yTop;
|
||||
} else
|
||||
if (*aY >= screenRect.yBottom - mBounds.height) {
|
||||
*aY = screenRect.yBottom - mBounds.height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
NS_ENSURE_TRUE(mFrame, NS_ERROR_UNEXPECTED);
|
||||
return mFrame->ConstrainPosition(aAllowSlop, aX, aY);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
@ -2143,7 +1965,7 @@ MRESULT nsWindow::ProcessMessage(ULONG msg, MPARAM mp1, MPARAM mp2)
|
|||
isDone = DispatchScrollEvent(msg, mp1, mp2);
|
||||
break;
|
||||
|
||||
// Do not act on WM_ACTIVATE - it is handled by nsFrameWindow.
|
||||
// Do not act on WM_ACTIVATE - it is handled by os2FrameWindow.
|
||||
// case WM_ACTIVATE:
|
||||
// break;
|
||||
|
||||
|
@ -2220,7 +2042,6 @@ void nsWindow::OnDestroy()
|
|||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsFrameWindow overrides this.
|
||||
|
||||
PRBool nsWindow::OnReposition(PSWP pSwp)
|
||||
{
|
||||
|
@ -2297,7 +2118,7 @@ PRBool nsWindow::OnPaint()
|
|||
// build XP rect from in-ex window rect
|
||||
nsIntRect rect;
|
||||
rect.x = rcl.xLeft;
|
||||
rect.y = GetClientHeight() - rcl.yTop;
|
||||
rect.y = mBounds.height - rcl.yTop;
|
||||
rect.width = rcl.xRight - rcl.xLeft;
|
||||
rect.height = rcl.yTop - rcl.yBottom;
|
||||
event.rect = ▭
|
||||
|
|
|
@ -46,16 +46,33 @@
|
|||
|
||||
//=============================================================================
|
||||
/*
|
||||
* nsWindow derives from nsIWidget via nsBaseWindow, and is created when
|
||||
* NS_CHILD_CID is specified. It is used for widgets that are either
|
||||
* children of other widgets or are popups (standalone windows such as
|
||||
* menus that float above other widgets).
|
||||
*
|
||||
* nsWindow derives from nsIWidget via nsBaseWindow. With the aid
|
||||
* of a helper class (os2FrameWindow) and a subclass (nsChildWindow),
|
||||
* it implements the functionality of both toplevel and child widgets.
|
||||
*
|
||||
* Top-level widgets (windows surrounded by a frame with a titlebar, etc.)
|
||||
* are implemented by nsFrameWindow which is a subclass of nsWindow. Many
|
||||
* nsWindow methods operate on both child & top-level windows. Where the
|
||||
* two categories require differing implementations, these methods rely on
|
||||
* a flag or on virtual helper methods to produce the correct result.
|
||||
* are created when NS_WINDOW_CID is used to identify the type of object
|
||||
* needed. Child widgets (windows that either are children of other windows
|
||||
* or are popups such as menus) are created when NS_CHILD_CID is specified.
|
||||
* Since Mozilla expects these to be different classes, NS_CHILD_CID is
|
||||
* mapped to a subclass (nsChildWindow) which acts solely as a wrapper for
|
||||
* nsWindow and adds no functionality.
|
||||
*
|
||||
* While most of the methods inherited from nsIWidget are generic, some
|
||||
* apply only to toplevel widgets (e.g. setting a title or icon). The
|
||||
* nature of toplevel windows on OS/2 with their separate frame & client
|
||||
* windows introduces the need for additional toplevel-specific methods,
|
||||
* as well as for special handling in otherwise generic methods.
|
||||
*
|
||||
* Rather than incorporating these toplevel functions into the body of
|
||||
* the class, nsWindow delegates them to a helper class, os2FrameWindow.
|
||||
* An instance of this class is created when nsWindow is told to create
|
||||
* a toplevel native window and is destroyed in nsWindow's destructor.
|
||||
* The class's methods operate exclusively on the frame window and never
|
||||
* deal with the frame's client other than to create it. Similarly,
|
||||
* nsWindow never operates on frame windows except for a few trivial
|
||||
* methods (e.g. Enable()). Neither class accesses the other's data
|
||||
* though, of necessity, both call the other's methods.
|
||||
*
|
||||
*/
|
||||
//=============================================================================
|
||||
|
@ -123,18 +140,12 @@ extern "C" {
|
|||
|
||||
//#define DEBUG_FOCUS
|
||||
|
||||
#ifdef DEBUG_FOCUS
|
||||
#define DEBUGFOCUS(what) fprintf(stderr, "[%8x] %8lx (%02d) "#what"\n", \
|
||||
(int)this, mWnd, mWindowIdentifier)
|
||||
#else
|
||||
#define DEBUGFOCUS(what)
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Forward declarations
|
||||
|
||||
class imgIContainer;
|
||||
class gfxOS2Surface;
|
||||
class os2FrameWindow;
|
||||
|
||||
MRESULT EXPENTRY fnwpNSWindow(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
|
||||
MRESULT EXPENTRY fnwpFrame(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
|
||||
|
@ -215,11 +226,11 @@ protected:
|
|||
|
||||
// nsWindow
|
||||
static void InitGlobals();
|
||||
virtual nsresult CreateWindow(nsWindow* aParent,
|
||||
nsresult CreateWindow(nsWindow* aParent,
|
||||
HWND aParentWnd,
|
||||
const nsIntRect& aRect,
|
||||
PRUint32 aStyle);
|
||||
virtual HWND GetMainWindow() const {return mWnd;}
|
||||
nsWidgetInitData* aInitData);
|
||||
HWND GetMainWindow();
|
||||
static nsWindow* GetNSWindowPtr(HWND aWnd);
|
||||
static PRBool SetNSWindowPtr(HWND aWnd, nsWindow* aPtr);
|
||||
void NS2PM(POINTL& ptl);
|
||||
|
@ -228,7 +239,7 @@ protected:
|
|||
void ActivatePlugin(HWND aWnd);
|
||||
void SetPluginClipRegion(const Configuration& aConfiguration);
|
||||
HWND GetPluginClipWindow(HWND aParentWnd);
|
||||
virtual void ActivateTopLevelWidget();
|
||||
void ActivateTopLevelWidget();
|
||||
HBITMAP DataToBitmap(PRUint8* aImageData, PRUint32 aWidth,
|
||||
PRUint32 aHeight, PRUint32 aDepth);
|
||||
HBITMAP CreateBitmapRGB(PRUint8* aImageData,
|
||||
|
@ -240,7 +251,7 @@ protected:
|
|||
static PRBool RollupOnButtonDown(ULONG aMsg);
|
||||
static void RollupOnFocusLost(HWND aFocus);
|
||||
MRESULT ProcessMessage(ULONG msg, MPARAM mp1, MPARAM mp2);
|
||||
virtual PRBool OnReposition(PSWP pNewSwp);
|
||||
PRBool OnReposition(PSWP pNewSwp);
|
||||
PRBool OnPaint();
|
||||
PRBool OnMouseChord(MPARAM mp1, MPARAM mp2);
|
||||
PRBool OnDragDropMsg(ULONG msg, MPARAM mp1, MPARAM mp2,
|
||||
|
@ -264,16 +275,16 @@ protected:
|
|||
PRInt16 aButton = nsMouseEvent::eLeftButton);
|
||||
PRBool DispatchActivationEvent(PRUint32 aEventType);
|
||||
PRBool DispatchScrollEvent(ULONG msg, MPARAM mp1, MPARAM mp2);
|
||||
virtual PRInt32 GetClientHeight() {return mBounds.height;}
|
||||
|
||||
friend MRESULT EXPENTRY fnwpNSWindow(HWND hwnd, ULONG msg,
|
||||
MPARAM mp1, MPARAM mp2);
|
||||
friend MRESULT EXPENTRY fnwpFrame(HWND hwnd, ULONG msg,
|
||||
MPARAM mp1, MPARAM mp2);
|
||||
friend class os2FrameWindow;
|
||||
|
||||
HWND mWnd; // window handle
|
||||
nsWindow* mParent; // parent widget
|
||||
PRBool mIsTopWidgetWindow; // is nsFrameWindow class?
|
||||
os2FrameWindow* mFrame; // ptr to os2FrameWindow helper object
|
||||
PRInt32 mWindowState; // current nsWindowState_* value
|
||||
PRBool mIsDestroying; // in destructor
|
||||
PRBool mInSetFocus; // prevent recursive calls
|
||||
|
@ -283,14 +294,24 @@ protected:
|
|||
HPOINTER mCssCursorHPtr; // created by SetCursor(imgIContainer*)
|
||||
nsCOMPtr<imgIContainer> mCssCursorImg;// saved by SetCursor(imgIContainer*)
|
||||
nsRefPtr<gfxOS2Surface> mThebesSurface;
|
||||
HWND mFrameWnd; // frame window handle
|
||||
HPOINTER mFrameIcon; // current frame icon
|
||||
PRBool mChromeHidden; // are frame controls hidden?
|
||||
#ifdef DEBUG_FOCUS
|
||||
int mWindowIdentifier; // a serial number for each new window
|
||||
#endif
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
// nsChildWindow
|
||||
//=============================================================================
|
||||
|
||||
// This only purpose of this subclass is to map NS_CHILD_CID to
|
||||
// some class other than nsWindow which is mapped to NS_WINDOW_CID.
|
||||
|
||||
class nsChildWindow : public nsWindow {
|
||||
public:
|
||||
nsChildWindow() {}
|
||||
~nsChildWindow() {}
|
||||
};
|
||||
|
||||
#endif // _nswindow_h
|
||||
|
||||
//=============================================================================
|
||||
|
|
|
@ -0,0 +1,745 @@
|
|||
/* vim: set sw=2 sts=2 et cin: */
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Mozilla OS/2 libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* John Fairhurst, <john_fairhurst@iname.com>.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Rich Walsh <dragtext@e-vertise.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK *****
|
||||
*
|
||||
* This Original Code has been modified by IBM Corporation.
|
||||
* Modifications made by IBM are
|
||||
* Copyright (c) International Business Machines Corporation, 2000
|
||||
*
|
||||
*/
|
||||
//=============================================================================
|
||||
|
||||
#include "nsWindow.h"
|
||||
#include "os2FrameWindow.h"
|
||||
#include "nsIRollupListener.h"
|
||||
#include "nsIScreenManager.h"
|
||||
#include "nsOS2Uni.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// External Variables (in nsWindow.cpp)
|
||||
|
||||
extern nsIRollupListener* gRollupListener;
|
||||
extern nsIWidget* gRollupWidget;
|
||||
extern PRBool gRollupConsumeRollupEvent;
|
||||
extern PRUint32 gOS2Flags;
|
||||
|
||||
#ifdef DEBUG_FOCUS
|
||||
extern int currentWindowIdentifier;
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Debug
|
||||
|
||||
#ifdef DEBUG_FOCUS
|
||||
#define DEBUGFOCUS(what) fprintf(stderr, "[%8x] %8lx (%02d) "#what"\n", \
|
||||
(int)this, mFrameWnd, mWindowIdentifier)
|
||||
#else
|
||||
#define DEBUGFOCUS(what)
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
// os2FrameWindow Setup
|
||||
//=============================================================================
|
||||
|
||||
os2FrameWindow::os2FrameWindow(nsWindow* aOwner)
|
||||
{
|
||||
mOwner = aOwner;
|
||||
mFrameWnd = 0;
|
||||
mTitleBar = 0;
|
||||
mSysMenu = 0;
|
||||
mMinMax = 0;
|
||||
mSavedStyle = 0;
|
||||
mFrameIcon = 0;
|
||||
mChromeHidden = PR_FALSE;
|
||||
mNeedActivation = PR_FALSE;
|
||||
mPrevFrameProc = 0;
|
||||
mFrameBounds = nsIntRect(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
os2FrameWindow::~os2FrameWindow()
|
||||
{
|
||||
if (mFrameIcon) {
|
||||
WinFreeFileIcon(mFrameIcon);
|
||||
mFrameIcon = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Create frame & client windows for an os2FrameWindow object; return the
|
||||
// handle of the client window. This is the only method that manipulates
|
||||
// the client window - all other operations on it are handled by nsWindow.
|
||||
|
||||
HWND os2FrameWindow::CreateFrameWindow(nsWindow* aParent,
|
||||
HWND aParentWnd,
|
||||
const nsIntRect& aRect,
|
||||
nsWindowType aWindowType,
|
||||
nsBorderStyle aBorderStyle)
|
||||
{
|
||||
// Create a frame window with a MozillaWindowClass window as its client.
|
||||
HWND hClient;
|
||||
PRUint32 fcfFlags = GetFCFlags(aWindowType, aBorderStyle);
|
||||
mFrameWnd = WinCreateStdWindow(HWND_DESKTOP,
|
||||
0,
|
||||
(ULONG*)&fcfFlags,
|
||||
kWindowClassName,
|
||||
"Title",
|
||||
WS_CLIPCHILDREN,
|
||||
NULLHANDLE,
|
||||
0,
|
||||
&hClient);
|
||||
if (!mFrameWnd) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Hide from the Window List until shown.
|
||||
SetWindowListVisibility(PR_FALSE);
|
||||
|
||||
// This prevents a modal dialog from being covered by its disabled parent.
|
||||
if (aParentWnd != HWND_DESKTOP) {
|
||||
WinSetOwner(mFrameWnd, aParentWnd);
|
||||
}
|
||||
|
||||
// Get the frame control HWNDs for use by fullscreen mode.
|
||||
mTitleBar = WinWindowFromID(mFrameWnd, FID_TITLEBAR);
|
||||
mSysMenu = WinWindowFromID(mFrameWnd, FID_SYSMENU);
|
||||
mMinMax = WinWindowFromID(mFrameWnd, FID_MINMAX);
|
||||
|
||||
// Calc the size of a frame needed to contain a client area of the
|
||||
// specified width & height. Without this, eWindowType_dialog windows
|
||||
// will be truncated (toplevel windows will still display correctly).
|
||||
RECTL rcl = {0, 0, aRect.width, aRect.height};
|
||||
WinCalcFrameRect(mFrameWnd, &rcl, FALSE);
|
||||
mFrameBounds = nsIntRect(aRect.x, aRect.y,
|
||||
rcl.xRight-rcl.xLeft, rcl.yTop-rcl.yBottom);
|
||||
|
||||
// Move & resize the frame.
|
||||
PRInt32 pmY = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN)
|
||||
- mFrameBounds.y - mFrameBounds.height;
|
||||
WinSetWindowPos(mFrameWnd, 0, mFrameBounds.x, pmY,
|
||||
mFrameBounds.width, mFrameBounds.height,
|
||||
SWP_SIZE | SWP_MOVE);
|
||||
|
||||
// Store the client's bounds. For windows with resizable borders,
|
||||
// the width includes the width of the frame controls (minmax, etc.).
|
||||
SWP swp;
|
||||
WinQueryWindowPos(hClient, &swp);
|
||||
mOwner->SetBounds(nsIntRect(swp.x, mFrameBounds.height - swp.y - swp.cy,
|
||||
swp.cx, swp.cy));
|
||||
|
||||
// Subclass the frame.
|
||||
mPrevFrameProc = WinSubclassWindow(mFrameWnd, fnwpFrame);
|
||||
WinSetWindowPtr(mFrameWnd, QWL_USER, this);
|
||||
|
||||
DEBUGFOCUS(Create os2FrameWindow);
|
||||
return hClient;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
PRUint32 os2FrameWindow::GetFCFlags(nsWindowType aWindowType,
|
||||
nsBorderStyle aBorderStyle)
|
||||
{
|
||||
PRUint32 style = FCF_TITLEBAR | FCF_SYSMENU | FCF_TASKLIST |
|
||||
FCF_CLOSEBUTTON | FCF_NOBYTEALIGN | FCF_AUTOICON;
|
||||
|
||||
if (aWindowType == eWindowType_dialog) {
|
||||
if (aBorderStyle == eBorderStyle_default) {
|
||||
style |= FCF_DLGBORDER;
|
||||
} else {
|
||||
style |= FCF_SIZEBORDER | FCF_MINMAX;
|
||||
}
|
||||
}
|
||||
else {
|
||||
style |= FCF_SIZEBORDER | FCF_MINMAX;
|
||||
}
|
||||
|
||||
if (gOS2Flags & kIsDBCS) {
|
||||
style |= FCF_DBE_APPSTAT;
|
||||
}
|
||||
if (aWindowType == eWindowType_invisible) {
|
||||
style &= ~FCF_TASKLIST;
|
||||
}
|
||||
|
||||
if (aBorderStyle != eBorderStyle_default &&
|
||||
aBorderStyle != eBorderStyle_all) {
|
||||
if (aBorderStyle == eBorderStyle_none ||
|
||||
!(aBorderStyle & eBorderStyle_resizeh)) {
|
||||
style &= ~FCF_SIZEBORDER;
|
||||
style |= FCF_DLGBORDER;
|
||||
}
|
||||
if (aBorderStyle == eBorderStyle_none ||
|
||||
!(aBorderStyle & eBorderStyle_border)) {
|
||||
style &= ~(FCF_DLGBORDER | FCF_SIZEBORDER);
|
||||
}
|
||||
if (aBorderStyle == eBorderStyle_none ||
|
||||
!(aBorderStyle & eBorderStyle_title)) {
|
||||
style &= ~(FCF_TITLEBAR | FCF_TASKLIST);
|
||||
}
|
||||
if (aBorderStyle == eBorderStyle_none ||
|
||||
!(aBorderStyle & eBorderStyle_close)) {
|
||||
style &= ~FCF_CLOSEBUTTON;
|
||||
}
|
||||
if (aBorderStyle == eBorderStyle_none ||
|
||||
!(aBorderStyle & (eBorderStyle_menu | eBorderStyle_close))) {
|
||||
style &= ~FCF_SYSMENU;
|
||||
}
|
||||
|
||||
// Looks like getting rid of the system menu also does away
|
||||
// with the close box. So, we only get rid of the system menu
|
||||
// if you want neither it nor the close box.
|
||||
|
||||
if (aBorderStyle == eBorderStyle_none ||
|
||||
!(aBorderStyle & eBorderStyle_minimize)) {
|
||||
style &= ~FCF_MINBUTTON;
|
||||
}
|
||||
if (aBorderStyle == eBorderStyle_none ||
|
||||
!(aBorderStyle & eBorderStyle_maximize)) {
|
||||
style &= ~FCF_MAXBUTTON;
|
||||
}
|
||||
}
|
||||
|
||||
return style;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// Window Operations
|
||||
//=============================================================================
|
||||
|
||||
// For frame windows, 'Show' is equivalent to 'Show & Activate'.
|
||||
|
||||
nsresult os2FrameWindow::Show(PRBool aState)
|
||||
{
|
||||
PRUint32 ulFlags;
|
||||
if (!aState) {
|
||||
ulFlags = SWP_HIDE | SWP_DEACTIVATE;
|
||||
} else {
|
||||
ulFlags = SWP_SHOW | SWP_ACTIVATE;
|
||||
|
||||
PRUint32 ulStyle = WinQueryWindowULong(mFrameWnd, QWL_STYLE);
|
||||
PRInt32 sizeMode;
|
||||
mOwner->GetSizeMode(&sizeMode);
|
||||
if (!(ulStyle & WS_VISIBLE)) {
|
||||
if (sizeMode == nsSizeMode_Maximized) {
|
||||
ulFlags |= SWP_MAXIMIZE;
|
||||
} else if (sizeMode == nsSizeMode_Minimized) {
|
||||
ulFlags |= SWP_MINIMIZE;
|
||||
} else {
|
||||
ulFlags |= SWP_RESTORE;
|
||||
}
|
||||
} else if (ulStyle & WS_MINIMIZED) {
|
||||
if (sizeMode == nsSizeMode_Maximized) {
|
||||
ulFlags |= SWP_MAXIMIZE;
|
||||
} else {
|
||||
ulFlags |= SWP_RESTORE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WinSetWindowPos(mFrameWnd, 0, 0, 0, 0, 0, ulFlags);
|
||||
SetWindowListVisibility(aState);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void os2FrameWindow::SetWindowListVisibility(PRBool aState)
|
||||
{
|
||||
HSWITCH hswitch = WinQuerySwitchHandle(mFrameWnd, 0);
|
||||
if (hswitch) {
|
||||
SWCNTRL swctl;
|
||||
WinQuerySwitchEntry(hswitch, &swctl);
|
||||
swctl.uchVisibility = aState ? SWL_VISIBLE : SWL_INVISIBLE;
|
||||
swctl.fbJump = aState ? SWL_JUMPABLE : SWL_NOTJUMPABLE;
|
||||
WinChangeSwitchEntry(hswitch, &swctl);
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// Window Positioning
|
||||
//=============================================================================
|
||||
|
||||
nsresult os2FrameWindow::GetBounds(nsIntRect& aRect)
|
||||
{
|
||||
aRect = mFrameBounds;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
nsresult os2FrameWindow::Move(PRInt32 aX, PRInt32 aY)
|
||||
{
|
||||
aY = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN) - mFrameBounds.height - aY;
|
||||
WinSetWindowPos(mFrameWnd, 0, aX, aY, 0, 0, SWP_MOVE);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
nsresult os2FrameWindow::Resize(PRInt32 aWidth, PRInt32 aHeight,
|
||||
PRBool aRepaint)
|
||||
{
|
||||
WinSetWindowPos(mFrameWnd, 0, 0, 0, aWidth, aHeight, SWP_SIZE);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
nsresult os2FrameWindow::Resize(PRInt32 aX, PRInt32 aY,
|
||||
PRInt32 aWidth, PRInt32 aHeight,
|
||||
PRBool aRepaint)
|
||||
{
|
||||
aY = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN) - aY - aHeight;
|
||||
WinSetWindowPos(mFrameWnd, 0, aX, aY, aWidth, aHeight, SWP_MOVE | SWP_SIZE);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// Top-level (frame window) Operations
|
||||
//=============================================================================
|
||||
|
||||
// When WM_ACTIVATE is received with the "gaining activation" flag set,
|
||||
// the frame's wndproc sets mNeedActivation. Later, when an nsWindow
|
||||
// gets a WM_FOCUSCHANGED msg with the "gaining focus" flag set, it
|
||||
// invokes this method on os2FrameWindow to fire an NS_ACTIVATE event.
|
||||
|
||||
void os2FrameWindow::ActivateTopLevelWidget()
|
||||
{
|
||||
// Don't fire event if we're minimized or else the window will
|
||||
// be restored as soon as the user clicks on it. When the user
|
||||
// explicitly restores it, SetSizeMode() will call this method.
|
||||
if (mNeedActivation) {
|
||||
PRInt32 sizeMode;
|
||||
mOwner->GetSizeMode(&sizeMode);
|
||||
if (sizeMode != nsSizeMode_Minimized) {
|
||||
mNeedActivation = PR_FALSE;
|
||||
DEBUGFOCUS(NS_ACTIVATE);
|
||||
mOwner->DispatchActivationEvent(NS_ACTIVATE);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Maximize, minimize or restore the window. When the frame has its
|
||||
// controls, this method is advisory because the min/max/restore has
|
||||
// already occurred. Only when the frame is in kiosk/fullscreen mode
|
||||
// does it perform the minimize or restore
|
||||
|
||||
nsresult os2FrameWindow::SetSizeMode(PRInt32 aMode)
|
||||
{
|
||||
PRInt32 previousMode;
|
||||
mOwner->GetSizeMode(&previousMode);
|
||||
|
||||
// save the new state
|
||||
nsresult rv = mOwner->nsBaseWidget::SetSizeMode(aMode);
|
||||
|
||||
// Minimized windows would get restored involuntarily if we fired an
|
||||
// NS_ACTIVATE when the user clicks on them. Instead, we defer the
|
||||
// activation event until the window has explicitly been restored.
|
||||
if (previousMode == nsSizeMode_Minimized && previousMode != aMode) {
|
||||
DEBUGFOCUS(deferred NS_ACTIVATE);
|
||||
ActivateTopLevelWidget();
|
||||
}
|
||||
|
||||
// nothing to do in these cases
|
||||
if (!NS_SUCCEEDED(rv) || !mChromeHidden || aMode == nsSizeMode_Maximized) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
ULONG ulStyle = WinQueryWindowULong(mFrameWnd, QWL_STYLE);
|
||||
|
||||
// act on the request if the frame isn't already in the requested state
|
||||
if (aMode == nsSizeMode_Minimized) {
|
||||
if (!(ulStyle & WS_MINIMIZED)) {
|
||||
WinSetWindowPos(mFrameWnd, HWND_BOTTOM, 0, 0, 0, 0,
|
||||
SWP_MINIMIZE | SWP_ZORDER | SWP_DEACTIVATE);
|
||||
}
|
||||
} else
|
||||
if (ulStyle & (WS_MAXIMIZED | WS_MINIMIZED)) {
|
||||
WinSetWindowPos(mFrameWnd, 0, 0, 0, 0, 0, SWP_RESTORE);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Hide or show the frame & its controls (titlebar, minmax, etc.).
|
||||
|
||||
nsresult os2FrameWindow::HideWindowChrome(PRBool aShouldHide)
|
||||
{
|
||||
// Putting a maximized window into fullscreen mode causes multiple
|
||||
// problems if it's later minimized & then restored. To avoid them,
|
||||
// restore maximized windows before putting them in fullscreen mode.
|
||||
if (WinQueryWindowULong(mFrameWnd, QWL_STYLE) & WS_MAXIMIZED) {
|
||||
WinSetWindowPos(mFrameWnd, 0, 0, 0, 0, 0, SWP_RESTORE | SWP_NOREDRAW);
|
||||
}
|
||||
|
||||
HWND hParent;
|
||||
if (aShouldHide) {
|
||||
hParent = HWND_OBJECT;
|
||||
mChromeHidden = PR_TRUE;
|
||||
} else {
|
||||
hParent = mFrameWnd;
|
||||
mChromeHidden = PR_FALSE;
|
||||
}
|
||||
|
||||
// Hide or show the frame controls.
|
||||
WinSetParent(mTitleBar, hParent, FALSE);
|
||||
WinSetParent(mSysMenu, hParent, FALSE);
|
||||
WinSetParent(mMinMax, hParent, FALSE);
|
||||
|
||||
// Modify the frame style, then advise it of the changes.
|
||||
if (aShouldHide) {
|
||||
mSavedStyle = WinQueryWindowULong(mFrameWnd, QWL_STYLE);
|
||||
WinSetWindowULong(mFrameWnd, QWL_STYLE, mSavedStyle & ~FS_SIZEBORDER);
|
||||
WinSendMsg(mFrameWnd, WM_UPDATEFRAME, 0, 0);
|
||||
} else {
|
||||
WinSetWindowULong(mFrameWnd, QWL_STYLE, mSavedStyle);
|
||||
WinSendMsg(mFrameWnd, WM_UPDATEFRAME,
|
||||
MPFROMLONG(FCF_TITLEBAR | FCF_SYSMENU | FCF_MINMAX), 0);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// On OS/2, if you pass a titlebar > 512 characters, it doesn't display at all.
|
||||
// We are going to limit our titlebars to 256 just to be on the safe side.
|
||||
|
||||
#define MAX_TITLEBAR_LENGTH 256
|
||||
|
||||
nsresult os2FrameWindow::SetTitle(const nsAString& aTitle)
|
||||
{
|
||||
PRUnichar* uchtemp = ToNewUnicode(aTitle);
|
||||
for (PRUint32 i = 0; i < aTitle.Length(); i++) {
|
||||
switch (uchtemp[i]) {
|
||||
case 0x2018:
|
||||
case 0x2019:
|
||||
uchtemp[i] = 0x0027;
|
||||
break;
|
||||
case 0x201C:
|
||||
case 0x201D:
|
||||
uchtemp[i] = 0x0022;
|
||||
break;
|
||||
case 0x2014:
|
||||
uchtemp[i] = 0x002D;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
nsAutoCharBuffer title;
|
||||
PRInt32 titleLength;
|
||||
WideCharToMultiByte(0, uchtemp, aTitle.Length(), title, titleLength);
|
||||
if (titleLength > MAX_TITLEBAR_LENGTH) {
|
||||
title[MAX_TITLEBAR_LENGTH] = '\0';
|
||||
}
|
||||
WinSetWindowText(mFrameWnd, title.Elements());
|
||||
|
||||
// If the chrome is hidden, set the text of the titlebar directly
|
||||
if (mChromeHidden) {
|
||||
WinSetWindowText(mTitleBar, title.Elements());
|
||||
}
|
||||
|
||||
nsMemory::Free(uchtemp);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// This implementation guarantees that sysmenus & minimized windows
|
||||
// will always have some icon other than the sysmenu default.
|
||||
|
||||
nsresult os2FrameWindow::SetIcon(const nsAString& aIconSpec)
|
||||
{
|
||||
static HPOINTER hDefaultIcon = 0;
|
||||
HPOINTER hWorkingIcon = 0;
|
||||
|
||||
// Assume the given string is a local identifier for an icon file.
|
||||
nsCOMPtr<nsILocalFile> iconFile;
|
||||
mOwner->ResolveIconName(aIconSpec, NS_LITERAL_STRING(".ico"),
|
||||
getter_AddRefs(iconFile));
|
||||
|
||||
// if the file was found, try to use it
|
||||
if (iconFile) {
|
||||
nsCAutoString path;
|
||||
iconFile->GetNativePath(path);
|
||||
|
||||
if (mFrameIcon) {
|
||||
WinFreeFileIcon(mFrameIcon);
|
||||
}
|
||||
mFrameIcon = WinLoadFileIcon(path.get(), FALSE);
|
||||
hWorkingIcon = mFrameIcon;
|
||||
}
|
||||
|
||||
// if that doesn't work, use the app's icon (let's hope it can be
|
||||
// loaded because nobody should have to look at SPTR_APPICON)
|
||||
if (!hWorkingIcon) {
|
||||
if (!hDefaultIcon) {
|
||||
hDefaultIcon = WinLoadPointer(HWND_DESKTOP, 0, 1);
|
||||
if (!hDefaultIcon) {
|
||||
hDefaultIcon = WinQuerySysPointer(HWND_DESKTOP, SPTR_APPICON, FALSE);
|
||||
}
|
||||
}
|
||||
hWorkingIcon = hDefaultIcon;
|
||||
}
|
||||
|
||||
WinSendMsg(mFrameWnd, WM_SETICON, (MPARAM)hWorkingIcon, (MPARAM)0);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constrain a potential move to fit onscreen.
|
||||
|
||||
nsresult os2FrameWindow::ConstrainPosition(PRBool aAllowSlop,
|
||||
PRInt32* aX, PRInt32* aY)
|
||||
{
|
||||
// do we have enough info to do anything
|
||||
PRBool doConstrain = PR_FALSE;
|
||||
|
||||
// get our playing field. use the current screen, or failing
|
||||
// that for any reason, use device caps for the default screen.
|
||||
RECTL screenRect;
|
||||
|
||||
nsCOMPtr<nsIScreenManager> screenmgr =
|
||||
do_GetService("@mozilla.org/gfx/screenmanager;1");
|
||||
if (screenmgr) {
|
||||
nsCOMPtr<nsIScreen> screen;
|
||||
PRInt32 left, top, width, height;
|
||||
|
||||
// zero size rects confuse the screen manager
|
||||
width = mFrameBounds.width > 0 ? mFrameBounds.width : 1;
|
||||
height = mFrameBounds.height > 0 ? mFrameBounds.height : 1;
|
||||
screenmgr->ScreenForRect(*aX, *aY, width, height,
|
||||
getter_AddRefs(screen));
|
||||
if (screen) {
|
||||
screen->GetAvailRect(&left, &top, &width, &height);
|
||||
screenRect.xLeft = left;
|
||||
screenRect.xRight = left+width;
|
||||
screenRect.yTop = top;
|
||||
screenRect.yBottom = top+height;
|
||||
doConstrain = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
#define kWindowPositionSlop 100
|
||||
|
||||
if (doConstrain) {
|
||||
if (aAllowSlop) {
|
||||
if (*aX < screenRect.xLeft - mFrameBounds.width + kWindowPositionSlop) {
|
||||
*aX = screenRect.xLeft - mFrameBounds.width + kWindowPositionSlop;
|
||||
} else
|
||||
if (*aX >= screenRect.xRight - kWindowPositionSlop) {
|
||||
*aX = screenRect.xRight - kWindowPositionSlop;
|
||||
}
|
||||
|
||||
if (*aY < screenRect.yTop) {
|
||||
*aY = screenRect.yTop;
|
||||
} else
|
||||
if (*aY >= screenRect.yBottom - kWindowPositionSlop) {
|
||||
*aY = screenRect.yBottom - kWindowPositionSlop;
|
||||
}
|
||||
} else {
|
||||
if (*aX < screenRect.xLeft) {
|
||||
*aX = screenRect.xLeft;
|
||||
} else
|
||||
if (*aX >= screenRect.xRight - mFrameBounds.width) {
|
||||
*aX = screenRect.xRight - mFrameBounds.width;
|
||||
}
|
||||
|
||||
if (*aY < screenRect.yTop) {
|
||||
*aY = screenRect.yTop;
|
||||
} else
|
||||
if (*aY >= screenRect.yBottom - mFrameBounds.height) {
|
||||
*aY = screenRect.yBottom - mFrameBounds.height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// os2FrameWindow's Window Procedure
|
||||
//=============================================================================
|
||||
|
||||
// Subclass for frame window
|
||||
|
||||
MRESULT EXPENTRY fnwpFrame(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
|
||||
{
|
||||
// check to see if we have a rollup listener registered
|
||||
if (gRollupListener && gRollupWidget) {
|
||||
if (msg == WM_TRACKFRAME || msg == WM_MINMAXFRAME ||
|
||||
msg == WM_BUTTON1DOWN || msg == WM_BUTTON2DOWN ||
|
||||
msg == WM_BUTTON3DOWN) {
|
||||
// Rollup if the event is outside the popup
|
||||
if (!nsWindow::EventIsInsideWindow((nsWindow*)gRollupWidget)) {
|
||||
gRollupListener->Rollup(PR_UINT32_MAX, nsnull);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
os2FrameWindow* pFrame = (os2FrameWindow*)WinQueryWindowPtr(hwnd, QWL_USER);
|
||||
return pFrame->ProcessFrameMessage(msg, mp1, mp2);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Process messages from the frame
|
||||
|
||||
MRESULT os2FrameWindow::ProcessFrameMessage(ULONG msg, MPARAM mp1, MPARAM mp2)
|
||||
{
|
||||
MRESULT mresult = 0;
|
||||
PRBool isDone = PR_FALSE;
|
||||
|
||||
switch (msg) {
|
||||
case WM_WINDOWPOSCHANGED: {
|
||||
PSWP pSwp = (PSWP)mp1;
|
||||
|
||||
if (pSwp->fl & SWP_MOVE && !(pSwp->fl & SWP_MINIMIZE)) {
|
||||
POINTL ptl = { pSwp->x, pSwp->y + pSwp->cy };
|
||||
ptl.y = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN) - ptl.y;
|
||||
mFrameBounds.x = ptl.x;
|
||||
mFrameBounds.y = ptl.y;
|
||||
mOwner->DispatchMoveEvent(ptl.x, ptl.y);
|
||||
}
|
||||
|
||||
// Save the frame's bounds, then call the default wndproc
|
||||
// so the client can handle its WM_WINDOWPOSCHANGED msg now.
|
||||
if (pSwp->fl & SWP_SIZE && !(pSwp->fl & SWP_MINIMIZE)) {
|
||||
mFrameBounds.width = pSwp->cx;
|
||||
mFrameBounds.height = pSwp->cy;
|
||||
mresult = (*mPrevFrameProc)(mFrameWnd, msg, mp1, mp2);
|
||||
isDone = PR_TRUE;
|
||||
}
|
||||
|
||||
if (pSwp->fl & (SWP_MAXIMIZE | SWP_MINIMIZE | SWP_RESTORE)) {
|
||||
nsSizeModeEvent event(PR_TRUE, NS_SIZEMODE, mOwner);
|
||||
if (pSwp->fl & SWP_MAXIMIZE) {
|
||||
event.mSizeMode = nsSizeMode_Maximized;
|
||||
} else if (pSwp->fl & SWP_MINIMIZE) {
|
||||
event.mSizeMode = nsSizeMode_Minimized;
|
||||
} else {
|
||||
event.mSizeMode = nsSizeMode_Normal;
|
||||
}
|
||||
mOwner->InitEvent(event);
|
||||
mOwner->DispatchWindowEvent(&event);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// A frame window in kiosk/fullscreen mode must have its frame
|
||||
// controls reattached before it's minimized & detached after it's
|
||||
// restored. If this doesn't happen at the correct times, clicking
|
||||
// on the icon won't restore it, the sysmenu will have the wrong
|
||||
// items, and/or the minmax button will have the wrong buttons.
|
||||
|
||||
case WM_ADJUSTWINDOWPOS:
|
||||
if (mChromeHidden && ((PSWP)mp1)->fl & SWP_MINIMIZE) {
|
||||
WinSetParent(mTitleBar, mFrameWnd, TRUE);
|
||||
WinSetParent(mSysMenu, mFrameWnd, TRUE);
|
||||
WinSetParent(mMinMax, mFrameWnd, TRUE);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_ADJUSTFRAMEPOS:
|
||||
if (mChromeHidden && ((PSWP)mp1)->fl & SWP_RESTORE) {
|
||||
WinSetParent(mTitleBar, HWND_OBJECT, TRUE);
|
||||
WinSetParent(mSysMenu, HWND_OBJECT, TRUE);
|
||||
WinSetParent(mMinMax, HWND_OBJECT, TRUE);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_DESTROY:
|
||||
DEBUGFOCUS(frame WM_DESTROY);
|
||||
WinSubclassWindow(mFrameWnd, mPrevFrameProc);
|
||||
WinSetWindowPtr(mFrameWnd, QWL_USER, 0);
|
||||
break;
|
||||
|
||||
case WM_INITMENU:
|
||||
// If we are in fullscreen/kiosk mode, disable maximize menu item.
|
||||
if (mChromeHidden &&
|
||||
SHORT1FROMMP(mp1) == SC_SYSMENU &&
|
||||
WinQueryWindowULong(mFrameWnd, QWL_STYLE) & WS_MINIMIZED) {
|
||||
MENUITEM menuitem;
|
||||
WinSendMsg(WinWindowFromID(mFrameWnd, FID_SYSMENU), MM_QUERYITEM,
|
||||
MPFROM2SHORT(SC_SYSMENU, FALSE), MPARAM(&menuitem));
|
||||
mresult = (*mPrevFrameProc)(mFrameWnd, msg, mp1, mp2);
|
||||
WinEnableMenuItem(menuitem.hwndSubMenu, SC_MAXIMIZE, FALSE);
|
||||
isDone = PR_TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_SYSCOMMAND:
|
||||
// If we are in fullscreen/kiosk mode, don't honor maximize requests.
|
||||
if (mChromeHidden &&
|
||||
SHORT1FROMMP(mp1) == SC_MAXIMIZE &&
|
||||
WinQueryWindowULong(mFrameWnd, QWL_STYLE) & WS_MINIMIZED) {
|
||||
isDone = PR_TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
// When the frame is activated, set a flag to be acted on after
|
||||
// PM has finished changing focus. When deactivated, dispatch
|
||||
// the event immediately because it doesn't affect the focus.
|
||||
case WM_ACTIVATE:
|
||||
DEBUGFOCUS(WM_ACTIVATE);
|
||||
if (mp1) {
|
||||
mNeedActivation = PR_TRUE;
|
||||
} else {
|
||||
mNeedActivation = PR_FALSE;
|
||||
DEBUGFOCUS(NS_DEACTIVATE);
|
||||
mOwner->DispatchActivationEvent(NS_DEACTIVATE);
|
||||
// Prevent the frame from automatically focusing any window
|
||||
// when it's reactivated. Let moz set the focus to avoid
|
||||
// having non-widget children of plugins focused in error.
|
||||
WinSetWindowULong(mFrameWnd, QWL_HWNDFOCUSSAVE, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!isDone) {
|
||||
mresult = (*mPrevFrameProc)(mFrameWnd, msg, mp1, mp2);
|
||||
}
|
||||
|
||||
return mresult;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
/* vim: set sw=2 sts=2 et cin: */
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Mozilla OS/2 libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* John Fairhurst, <john_fairhurst@iname.com>.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Rich Walsh <dragtext@e-vertise.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
//=============================================================================
|
||||
/*
|
||||
* os2FrameWindow is a helper class instantiated by nsWindow to handle
|
||||
* operations that are specific to OS/2 frame windows. It never references
|
||||
* the frame's client window except to create it. See nsWindow.h for details.
|
||||
* Note: nsWindow.h must be #included in *.cpp before #including this file.
|
||||
*
|
||||
*/
|
||||
//=============================================================================
|
||||
|
||||
#ifndef _os2framewindow_h
|
||||
#define _os2framewindow_h
|
||||
|
||||
//=============================================================================
|
||||
// os2FrameWindow
|
||||
//=============================================================================
|
||||
|
||||
class os2FrameWindow
|
||||
{
|
||||
public:
|
||||
os2FrameWindow(nsWindow* aOwner);
|
||||
~os2FrameWindow();
|
||||
|
||||
HWND CreateFrameWindow(nsWindow* aParent,
|
||||
HWND aParentWnd,
|
||||
const nsIntRect& aRect,
|
||||
nsWindowType aWindowType,
|
||||
nsBorderStyle aBorderStyle);
|
||||
PRUint32 GetFCFlags(nsWindowType aWindowType,
|
||||
nsBorderStyle aBorderStyle);
|
||||
nsresult Show(PRBool aState);
|
||||
void SetWindowListVisibility(PRBool aState);
|
||||
nsresult GetBounds(nsIntRect& aRect);
|
||||
nsresult Move(PRInt32 aX, PRInt32 aY);
|
||||
nsresult Resize(PRInt32 aWidth, PRInt32 aHeight,
|
||||
PRBool aRepaint);
|
||||
nsresult Resize(PRInt32 aX, PRInt32 aY, PRInt32 w, PRInt32 h,
|
||||
PRBool aRepaint);
|
||||
void ActivateTopLevelWidget();
|
||||
nsresult SetSizeMode(PRInt32 aMode);
|
||||
nsresult HideWindowChrome(PRBool aShouldHide);
|
||||
nsresult SetTitle(const nsAString& aTitle);
|
||||
nsresult SetIcon(const nsAString& aIconSpec);
|
||||
nsresult ConstrainPosition(PRBool aAllowSlop,
|
||||
PRInt32* aX, PRInt32* aY);
|
||||
MRESULT ProcessFrameMessage(ULONG msg, MPARAM mp1, MPARAM mp2);
|
||||
HWND GetFrameWnd() {return mFrameWnd;}
|
||||
|
||||
friend MRESULT EXPENTRY fnwpFrame(HWND hwnd, ULONG msg,
|
||||
MPARAM mp1, MPARAM mp2);
|
||||
|
||||
protected:
|
||||
nsWindow * mOwner; // the nsWindow that created this instance
|
||||
HWND mFrameWnd; // the frame's window handle
|
||||
HWND mTitleBar; // the frame controls that have
|
||||
HWND mSysMenu; // to be hidden or shown when
|
||||
HWND mMinMax; // HideWindowChrome() is called
|
||||
PRUint32 mSavedStyle; // frame style saved by HideWindowChrome()
|
||||
HPOINTER mFrameIcon; // current frame icon
|
||||
PRBool mChromeHidden; // are frame controls hidden?
|
||||
PRBool mNeedActivation; // triggers activation when focus changes
|
||||
PFNWP mPrevFrameProc; // the frame's original wndproc
|
||||
nsIntRect mFrameBounds; // the frame's location & dimensions
|
||||
};
|
||||
|
||||
#endif //_os2framewindow_h
|
||||
|
||||
//=============================================================================
|
||||
|
Загрузка…
Ссылка в новой задаче