Major reimplementation of nsWindow class
Full step by step porting of Gtk2 version
Fixes: some problems with widget resize...
New problems: SetCursor does not work
--- a/widget/src/qt/Makefile.in
+++ b/widget/src/qt/Makefile.in
@@ -49,24 +49,27 @@ EXPORT_LIBRARY = 1
IS_COMPONENT = 1
MODULE_NAME = nsWidgetQtModule
GRE_MODULE = 1
LIBXUL_LIBRARY = 1
REQUIRES = xpcom \
string \
gfx \
- layout \
- content \
+ pref \
dom \
- appshell \
- pref \
+ necko \
uconv \
- necko \
+ intl \
+ imglib2 \
view \
+ content \
+ layout \
+ util \
+ locale \
thebes \
cairo \
$(NULL)
# MOCSRCS><-->= \
# moc_mozqwidget.cpp \
# nsAppShell.cpp \
# $(NULL)
--- a/widget/src/qt/mozqwidget.cpp
+++ b/widget/src/qt/mozqwidget.cpp
@@ -1,13 +1,13 @@
#include "mozqwidget.h"
-#include "nsCommonWidget.h"
+#include "nsWindow.h"
#include <qevent.h>
-MozQWidget::MozQWidget(nsCommonWidget *receiver, QWidget *parent,
+MozQWidget::MozQWidget(nsWindow *receiver, QWidget *parent,
const char *name, int f)
: QWidget(parent, (Qt::WindowFlags)f),
mReceiver(receiver)
{
}
bool MozQWidget::event(QEvent *e)
{
@@ -19,47 +19,47 @@ bool MozQWidget::event(QEvent *e)
{
qDebug("accessibility event received");
}
break;
*/
case QEvent::MouseButtonPress:
{
QMouseEvent *ms = (QMouseEvent*)(e);
- ignore = mReceiver->mousePressEvent(ms);
+ ignore = mReceiver->OnButtonPressEvent(ms);
}
break;
case QEvent::MouseButtonRelease:
{
QMouseEvent *ms = (QMouseEvent*)(e);
- ignore = mReceiver->mouseReleaseEvent(ms);
+ ignore = mReceiver->OnButtonReleaseEvent(ms);
}
break;
case QEvent::MouseButtonDblClick:
{
QMouseEvent *ms = (QMouseEvent*)(e);
ignore = mReceiver->mouseDoubleClickEvent(ms);
}
break;
case QEvent::MouseMove:
{
QMouseEvent *ms = (QMouseEvent*)(e);
- ignore = mReceiver->mouseMoveEvent(ms);
+ ignore = mReceiver->OnMotionNotifyEvent(ms);
}
break;
case QEvent::KeyPress:
{
QKeyEvent *kev = (QKeyEvent*)(e);
- ignore = mReceiver->keyPressEvent(kev);
+ ignore = mReceiver->OnKeyPressEvent(kev);
}
break;
case QEvent::KeyRelease:
{
QKeyEvent *kev = (QKeyEvent*)(e);
- ignore = mReceiver->keyReleaseEvent(kev);
+ ignore = mReceiver->OnKeyReleaseEvent(kev);
}
break;
/*
case QEvent::IMStart:
{
QIMEvent *iev = (QIMEvent*)(e);
ignore = mReceiver->imStartEvent(iev);
}
@@ -75,53 +75,53 @@ bool MozQWidget::event(QEvent *e)
QIMEvent *iev = (QIMEvent*)(e);
ignore = mReceiver->imEndEvent(iev);
}
break;
*/
case QEvent::FocusIn:
{
QFocusEvent *fev = (QFocusEvent*)(e);
- mReceiver->focusInEvent(fev);
+ mReceiver->OnContainerFocusInEvent(fev);
return TRUE;
}
break;
case QEvent::FocusOut:
{
QFocusEvent *fev = (QFocusEvent*)(e);
- mReceiver->focusOutEvent(fev);
+ mReceiver->OnContainerFocusOutEvent(fev);
return TRUE;
}
break;
case QEvent::Enter:
{
- ignore = mReceiver->enterEvent(e);
+ ignore = mReceiver->OnEnterNotifyEvent(e);
}
break;
case QEvent::Leave:
{
- ignore = mReceiver->enterEvent(e);
+ ignore = mReceiver->OnLeaveNotifyEvent(e);
}
break;
case QEvent::Paint:
{
QPaintEvent *ev = (QPaintEvent*)(e);
- mReceiver->paintEvent(ev);
+ mReceiver->OnExposeEvent(ev);
}
break;
case QEvent::Move:
{
QMoveEvent *mev = (QMoveEvent*)(e);
- ignore = mReceiver->moveEvent(mev);
+ ignore = mReceiver->OnConfigureEvent(mev);
}
break;
case QEvent::Resize:
{
QResizeEvent *rev = (QResizeEvent*)(e);
- ignore = mReceiver->resizeEvent(rev);
+ ignore = mReceiver->OnSizeAllocate(rev);
}
break;
case QEvent::Show:
{
QShowEvent *sev = (QShowEvent*)(e);
mReceiver->showEvent(sev);
}
break;
@@ -129,53 +129,53 @@ bool MozQWidget::event(QEvent *e)
{
QHideEvent *hev = (QHideEvent*)(e);
ignore = mReceiver->hideEvent(hev);
}
break;
case QEvent::Close:
{
QCloseEvent *cev = (QCloseEvent*)(e);
- ignore = mReceiver->closeEvent(cev);
+ ignore = mReceiver->OnDeleteEvent(cev);
}
break;
case QEvent::Wheel:
{
QWheelEvent *wev = (QWheelEvent*)(e);
- ignore = mReceiver->wheelEvent(wev);
+ ignore = mReceiver->OnScrollEvent(wev);
}
break;
case QEvent::ContextMenu:
{
QContextMenuEvent *cev = (QContextMenuEvent*)(e);
ignore = mReceiver->contextMenuEvent(cev);
}
break;
case QEvent::DragEnter:
{
QDragEnterEvent *dev = (QDragEnterEvent*)(e);
- ignore = mReceiver->dragEnterEvent(dev);
+ ignore = mReceiver->OnDragEnter(dev);
}
break;
case QEvent::DragMove:
{
QDragMoveEvent *dev = (QDragMoveEvent*)(e);
- ignore = mReceiver->dragMoveEvent(dev);
+ ignore = mReceiver->OnDragMotionEvent(dev);
}
break;
case QEvent::DragLeave:
{
QDragLeaveEvent *dev = (QDragLeaveEvent*)(e);
- ignore = mReceiver->dragLeaveEvent(dev);
+ ignore = mReceiver->OnDragLeaveEvent(dev);
}
break;
case QEvent::Drop:
{
QDropEvent *dev = (QDropEvent*)(e);
- ignore = mReceiver->dropEvent(dev);
+ ignore = mReceiver->OnDragDropEvent(dev);
}
break;
default:
break;
}
QWidget::event(e);
--- a/widget/src/qt/mozqwidget.h
+++ b/widget/src/qt/mozqwidget.h
@@ -1,28 +1,29 @@
#ifndef MOZQWIDGET_H
#define MOZQWIDGET_H
#include <qwidget.h>
class QEvent;
-class nsCommonWidget;
+class nsWindow;
class MozQWidget : public QWidget
{
Q_OBJECT
public:
- MozQWidget(nsCommonWidget *receiver, QWidget *parent,
+ MozQWidget(nsWindow* receiver, QWidget *parent,
const char *name, int f);
/**
* Mozilla helper.
*/
void setModal(bool);
void dropReciever() { mReceiver = 0x0; };
+ nsWindow* getReciever() { return mReceiver; };
protected:
virtual bool event(QEvent *ev);
private:
- nsCommonWidget *mReceiver;
+ nsWindow *mReceiver;
};
#endif
--- a/widget/src/qt/nsAppShell.cpp
+++ b/widget/src/qt/nsAppShell.cpp
@@ -39,16 +39,23 @@
#include "nsAppShell.h"
#include <qapplication.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#define NOTIFY_TOKEN 0xFA
+#ifdef PR_LOGGING
+PRLogModuleInfo *gWidgetLog = nsnull;
+PRLogModuleInfo *gWidgetFocusLog = nsnull;
+PRLogModuleInfo *gWidgetIMLog = nsnull;
+PRLogModuleInfo *gWidgetDrawLog = nsnull;
+#endif
+
void nsAppShell::EventNativeCallback(int fd)
{
unsigned char c;
read (mPipeFDs[0], &c, sizeof(unsigned int));
NS_ASSERTION(c == (unsigned char) NOTIFY_TOKEN, "wrong token");
NativeEventCallback();
return;
@@ -62,16 +69,27 @@ nsAppShell::~nsAppShell()
close(mPipeFDs[0]);
if (mPipeFDs[1])
close(mPipeFDs[1]);
}
nsresult
nsAppShell::Init()
{
+#ifdef PR_LOGGING
+ if (!gWidgetLog)
+ gWidgetLog = PR_NewLogModule("Widget");
+ if (!gWidgetFocusLog)
+ gWidgetFocusLog = PR_NewLogModule("WidgetFocus");
+ if (!gWidgetIMLog)
+ gWidgetIMLog = PR_NewLogModule("WidgetIM");
+ if (!gWidgetDrawLog)
+ gWidgetDrawLog = PR_NewLogModule("WidgetDraw");
+#endif
+
int err = pipe(mPipeFDs);
if (err)
return NS_ERROR_OUT_OF_MEMORY;
// make the pipe nonblocking
int flags = fcntl(mPipeFDs[0], F_GETFL, 0);
if (flags == -1)
--- a/widget/src/qt/nsCommonWidget.cpp
+++ b/widget/src/qt/nsCommonWidget.cpp
@@ -1,696 +1,115 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim:expandtab:shiftwidth=4:tabstop=4:
+ */
+/* ***** 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 mozilla.org code.
*
- * The Initial Developer of the Original Code is
- * Zack Rusin <zack@kde.org>.
- * Portions created by the Initial Developer are Copyright (C) 2004
- * the Initial Developer. All Rights Reserved.
+ * The Initial Developer of the Original Code is Christopher Blizzard
+ * <blizzard@mozilla.org>. Portions created by the Initial Developer
+ * are Copyright (C) 2001 the Initial Developer. All Rights Reserved.
*
* Contributor(s):
- * Lars Knoll <knoll@kde.org>
- * Zack Rusin <zack@kde.org>
*
* 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 ***** */
+
#include "nsCommonWidget.h"
-
-#include "nsGUIEvent.h"
-//#include "nsQtEventDispatcher.h"
-#include "nsIRenderingContext.h"
-#include "nsIServiceManager.h"
-#include "nsGfxCIID.h"
-#include "nsIPrefBranch.h"
-#include "nsIPrefService.h"
-
-#include "mozqwidget.h"
-
-#include <qapplication.h>
-#include <qdesktopwidget.h>
-#include <qwidget.h>
-#include "qx11info_x11.h"
-#include <qcursor.h>
-#include <qevent.h>
-#include <qobject.h>
-#include <execinfo.h>
-#include <stdlib.h>
-
-#include <execinfo.h>
-#include <stdlib.h>
#include "nsQtKeyUtils.h"
-static const int WHEEL_DELTA = 120;
-static const int kWindowPositionSlop = 20;
-
-static void backTrace()
+nsCommonWidget::nsCommonWidget()
{
- int levels = -1;
- QString s;
- void* trace[256];
- int n = backtrace(trace, 256);
- if (!n)
- return;
- char** strings = backtrace_symbols (trace, n);
+ mIsTopLevel = PR_FALSE;
+ mIsDestroyed = PR_FALSE;
+ mNeedsResize = PR_FALSE;
+ mNeedsMove = PR_FALSE;
+ mListenForResizes = PR_FALSE;
+ mIsShown = PR_FALSE;
+ mNeedsShow = PR_FALSE;
+ mEnabled = PR_TRUE;
+ mCreated = PR_FALSE;
+ mPlaced = PR_FALSE;
- if ( levels != -1 )
- n = qMin( n, levels );
- s = "[\n";
-
- for (int i = 0; i < n; ++i)
- s += QString::number(i) +
- QString::fromLatin1(": ") +
- QString::fromLatin1(strings[i]) + QString::fromLatin1("\n");
- s += "]\n";
- if (strings)
- free (strings);
-// qDebug("stacktrace:\n%s", s.latin1());
+ mPreferredWidth = 0;
+ mPreferredHeight = 0;
}
-static PRBool
-isContextMenuKey(const nsKeyEvent &aKeyEvent)
-{
- return ((aKeyEvent.keyCode == NS_VK_F10 && aKeyEvent.isShift &&
- !aKeyEvent.isControl && !aKeyEvent.isMeta && !aKeyEvent.isAlt) ||
- (aKeyEvent.keyCode == NS_VK_CONTEXT_MENU && !aKeyEvent.isShift &&
- !aKeyEvent.isControl && !aKeyEvent.isMeta && !aKeyEvent.isAlt));
-}
-
-static void
-keyEventToContextMenuEvent(const nsKeyEvent* aKeyEvent,
- nsMouseEvent* aCMEvent)
-{
- memcpy(aCMEvent, aKeyEvent, sizeof(nsInputEvent));
-// aCMEvent->message = NS_CONTEXTMENU_KEY;
- aCMEvent->isShift = aCMEvent->isControl = PR_FALSE;
- aCMEvent->isControl = PR_FALSE;
- aCMEvent->isAlt = aCMEvent->isMeta = PR_FALSE;
- aCMEvent->isMeta = PR_FALSE;
- aCMEvent->clickCount = 0;
- aCMEvent->acceptActivation = PR_FALSE;
-}
-
-nsCommonWidget::nsCommonWidget()
- : mContainer(0),
- mWidget(0),
- mListenForResizes(PR_FALSE),
- mNeedsResize(PR_FALSE),
- mNeedsShow(PR_FALSE),
- mIsShown(PR_FALSE)
+nsCommonWidget::~nsCommonWidget()
{
}
-NS_IMPL_ISUPPORTS_INHERITED0(nsCommonWidget,nsBaseWidget)
-nsCommonWidget::~nsCommonWidget()
+nsIWidget *
+nsCommonWidget::GetParent(void)
{
- MozQWidget *mozWidget = static_cast<MozQWidget*>(mWidget);
- if (mozWidget)
- mozWidget->dropReciever();
- mWidget->deleteLater();
- mWidget = 0;
+ return mParent;
}
void
-nsCommonWidget::Initialize(QWidget *widget)
-{
- Q_ASSERT(widget);
-
- mWidget = widget;
- mWidget->setMouseTracking(PR_TRUE);
- mWidget->setFocusPolicy(Qt::WheelFocus);
-}
-
-NS_IMETHODIMP
-nsCommonWidget::Show(PRBool aState)
-{
- mIsShown = aState;
-
- // Ok, someone called show on a window that isn't sized to a sane
- // value. Mark this window as needing to have Show() called on it
- // and return.
- if ((aState && !AreBoundsSane()) || !mWidget) {
-#ifdef DEBUG_WIDGETS
- qWarning("XX Bounds are insane or window hasn't been created yet");
-#endif
- mNeedsShow = PR_TRUE;
- return NS_OK;
- }
-
- // If someone is hiding this widget, clear any needing show flag.
- if (!aState)
- mNeedsShow = PR_FALSE;
-
- // If someone is showing this window and it needs a resize then
- // resize the widget.
- if (aState && mNeedsResize) {
-#ifdef DEBUG_WIDGETS
- qDebug("\tresizing [%d, %d, %d, %d]", mBounds.x, mBounds.y,
- mBounds.width, mBounds.height);
-#endif
- NativeResize(mBounds.x, mBounds.y, mBounds.width, mBounds.height,
- PR_FALSE);
- }
-
- NativeShow(aState);
-
- return NS_OK;
-}
-
-NS_IMETHODIMP
-nsCommonWidget::IsVisible(PRBool &visible)
-{
- if (mWidget)
- visible = mWidget->isVisible();
- else
- visible = PR_FALSE;
- return NS_OK;
-}
-
-NS_IMETHODIMP
-nsCommonWidget::ConstrainPosition(PRBool aAllowSlop, PRInt32 *aX, PRInt32 *aY)
-{
- if (mContainer) {
- PRInt32 screenWidth = QApplication::desktop()->width();
- PRInt32 screenHeight = QApplication::desktop()->height();
- if (aAllowSlop) {
- if (*aX < (kWindowPositionSlop - mBounds.width))
- *aX = kWindowPositionSlop - mBounds.width;
- if (*aX > (screenWidth - kWindowPositionSlop))
- *aX = screenWidth - kWindowPositionSlop;
- if (*aY < (kWindowPositionSlop - mBounds.height))
- *aY = kWindowPositionSlop - mBounds.height;
- if (*aY > (screenHeight - kWindowPositionSlop))
- *aY = screenHeight - kWindowPositionSlop;
- } else {
- if (*aX < 0)
- *aX = 0;
- if (*aX > (screenWidth - mBounds.width))
- *aX = screenWidth - mBounds.width;
- if (*aY < 0)
- *aY = 0;
- if (*aY > (screenHeight - mBounds.height))
- *aY = screenHeight - mBounds.height;
- }
- }
- return NS_OK;
-}
-
-NS_IMETHODIMP
-nsCommonWidget::Move(PRInt32 x, PRInt32 y)
-{
- bool popup = mWidget ? mWidget->windowType() == Qt::Popup : false;
-
- if (!mWidget || (x == mBounds.x && y == mBounds.y &&
- !popup))
- return NS_OK;
-
-#ifdef DEBUG_WIDGETS
- qDebug("Move [%d,%d] (%s)", x, y, popup?"popup":"widget");
-#endif
-
- if (!mWidget)
- return NS_OK;
-
- QPoint pos(x, y);
- if (mContainer) {
- if (mParent && mWidget->windowType() == Qt::Popup) {
- nsRect oldrect, newrect;
- oldrect.x = x;
- oldrect.y = y;
-
- mParent->WidgetToScreen(oldrect, newrect);
-
- pos = QPoint(newrect.x, newrect.y);
-#ifdef DEBUG_WIDGETS
- qDebug("pos is [%d,%d]", pos.x(), pos.y());
-#endif
- } else {
- qDebug("Widget within another? (%p)", (void*)mWidget);
- }
- }
-
- mBounds.x = pos.x();
- mBounds.y = pos.y();
-
- mWidget->move(pos);
-
- return NS_OK;
-}
-
-NS_IMETHODIMP
-nsCommonWidget::Resize(PRInt32 aWidth,
- PRInt32 aHeight,
- PRBool aRepaint)
+nsCommonWidget::CommonCreate(nsIWidget *aParent, PRBool aListenForResizes)
{
- mBounds.width = aWidth;
- mBounds.height = aHeight;
-
- if (!mWidget || (mWidget->width() == aWidth &&
- mWidget->height() == aHeight))
- return NS_OK;
-
- // There are several cases here that we need to handle, based on a
- // matrix of the visibility of the widget, the sanity of this resize
- // and whether or not the widget was previously sane.
-
- // Has this widget been set to visible?
- if (mIsShown) {
- // Are the bounds sane?
- if (AreBoundsSane()) {
- // Yep? Resize the window
- //Maybe, the toplevel has moved
- if (mContainer || mNeedsShow)
- NativeResize(mBounds.x, mBounds.y,
- mBounds.width, mBounds.height, aRepaint);
- else
- NativeResize(mBounds.width, mBounds.height, aRepaint);
-
- // Does it need to be shown because it was previously insane?
- if (mNeedsShow)
- NativeShow(PR_TRUE);
- }
- else {
- // If someone has set this so that the needs show flag is false
- // and it needs to be hidden, update the flag and hide the
- // window. This flag will be cleared the next time someone
- // hides the window or shows it. It also prevents us from
- // calling NativeShow(PR_FALSE) excessively on the window which
- // causes unneeded X traffic.
- if (!mNeedsShow) {
- mNeedsShow = PR_TRUE;
- NativeShow(PR_FALSE);
- }
- }
- }
- // If the widget hasn't been shown, mark the widget as needing to be
- // resized before it is shown.
- else {
- if (AreBoundsSane() && mListenForResizes) {
- // For widgets that we listen for resizes for (widgets created
- // with native parents) we apparently _always_ have to resize. I
- // dunno why, but apparently we're lame like that.
- NativeResize(aWidth, aHeight, aRepaint);
- }
- else {
- mNeedsResize = PR_TRUE;
- }
- }
-
- // synthesize a resize event if this isn't a toplevel
- if (mContainer || mListenForResizes) {
- nsRect rect(mBounds.x, mBounds.y, aWidth, aHeight);
- nsEventStatus status;
- DispatchResizeEvent(rect, status);
- }
-
- return NS_OK;
-}
-
-/*
- * XXXX: This sucks because it basically hardcore duplicates the
- * code from the above function.
- */
-NS_IMETHODIMP
-nsCommonWidget::Resize(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight,
- PRBool aRepaint)
-{
-#ifdef DEBUG_WIDGETS
- qDebug("Resize : [%d,%d,%d,%d]", aX, aY, aWidth, aHeight);
-#endif
- if (!mWidget || (mWidget->x() == aX &&
- mWidget->y() == aY &&
- mWidget->height() == aHeight &&
- mWidget->width() == aWidth))
- return NS_OK;
-
- mBounds.x = aX;
- mBounds.y = aY;
- mBounds.width = aWidth;
- mBounds.height = aHeight;
-
- // There are several cases here that we need to handle, based on a
- // matrix of the visibility of the widget, the sanity of this resize
- // and whether or not the widget was previously sane.
-
- // Has this widget been set to visible?
- if (mIsShown) {
- // Are the bounds sane?
- if (AreBoundsSane()) {
- // Yep? Resize the window
- NativeResize(aX, aY, aWidth, aHeight, aRepaint);
-
- // Does it need to be shown because it was previously insane?
- if (mNeedsShow)
- NativeShow(PR_TRUE);
- }
- else {
- // If someone has set this so that the needs show flag is false
- // and it needs to be hidden, update the flag and hide the
- // window. This flag will be cleared the next time someone
- // hides the window or shows it. It also prevents us from
- // calling NativeShow(PR_FALSE) excessively on the window which
- // causes unneeded X traffic.
- if (!mNeedsShow) {
- mNeedsShow = PR_TRUE;
- NativeShow(PR_FALSE);
- }
- }
- }
- // If the widget hasn't been shown, mark the widget as needing to be
- // resized before it is shown
- else {
- if (AreBoundsSane() && mListenForResizes){
- // For widgets that we listen for resizes for (widgets created
- // with native parents) we apparently _always_ have to resize. I
- // dunno why, but apparently we're lame like that.
- NativeResize(aX, aY, aWidth, aHeight, aRepaint);
- }
- else {
- mNeedsResize = PR_TRUE;
- }
- }
-
- // synthesize a resize event if this isn't a toplevel
- if (mContainer || mListenForResizes) {
- nsRect rect(mBounds.x, mBounds.y, mBounds.width, mBounds.height);
- nsEventStatus status;
- DispatchResizeEvent(rect, status);
- }
-
- return NS_OK;
+ mParent = aParent;
+ mListenForResizes = aListenForResizes;
+ mCreated = PR_TRUE;
}
-NS_IMETHODIMP
-nsCommonWidget::Enable(PRBool aState)
+void
+nsCommonWidget::InitKeyEvent(nsKeyEvent &aEvent, QKeyEvent *aQEvent)
{
- if (mWidget)
- mWidget->setEnabled(aState);
-
- return NS_OK;
-}
-
-NS_IMETHODIMP
-nsCommonWidget::IsEnabled(PRBool *aState)
-{
- if (mWidget)
- *aState = mWidget->isEnabled();
+ aEvent.isShift = aQEvent->modifiers() & Qt::ShiftModifier;
+ aEvent.isControl = aQEvent->modifiers() & Qt::ControlModifier;
+ aEvent.isAlt = aQEvent->modifiers() & Qt::AltModifier;
+ aEvent.isMeta = aQEvent->modifiers() & Qt::MetaModifier;
+ aEvent.time = 0;
- return NS_OK;
-}
+ // The transformations above and in gdk for the keyval are not invertible
+ // so link to the GdkEvent (which will vanish soon after return from the
+ // event callback) to give plugins access to hardware_keycode and state.
+ // (An XEvent would be nice but the GdkEvent is good enough.)
+ aEvent.nativeMsg = (void *)aQEvent;
-NS_IMETHODIMP
-nsCommonWidget::SetFocus(PRBool aRaise)
-{
-#ifdef DEBUG_WIDGETS
- qDebug("SetFocus mWidget=%p, mContainer=%p, focuswidget=%p (%d)",
- (void*)mWidget, (void*)mContainer, (void*)mWidget->focusWidget());
-#endif
- if (mWidget) {
- if (aRaise)
- mWidget->raise();
- mWidget->setFocus();
-
- DispatchGotFocusEvent();
+// aEvent.time = aGdkEvent->time;
+/*
+ if (qEvent->text().length() && qEvent->text()[0].isPrint()) {
+ nsEvent->charCode = (PRInt32)qEvent->text()[0].unicode();
+ }
+ else {
+ nsEvent->charCode = 0;
}
- return NS_OK;
-}
-
-nsIFontMetrics*
-nsCommonWidget::GetFont()
-{
-#ifdef DEBUG_WIDGETS
- qWarning("nsCommonWidget.cpp: GetFont not implemented");
-#endif
- return nsnull;
-}
-
-NS_IMETHODIMP
-nsCommonWidget::SetFont(const nsFont&)
-{
- return NS_OK;
-}
-
-NS_IMETHODIMP
-nsCommonWidget::Invalidate(PRBool aIsSynchronous)
-{
-#ifdef DEBUG_WIDGETS
- qDebug("nsCommonWidget::Invalidate1 container=%p widget=%p", (void*)mContainer, (void*)mWidget);
-#endif
- if (!mWidget)
- return NS_OK;
-
- if (aIsSynchronous)
- mWidget->repaint();
- else
- mWidget->update();
-
- return NS_OK;
-}
-
-NS_IMETHODIMP
-nsCommonWidget::Invalidate(const nsRect & aRect, PRBool aIsSynchronous)
-{
-#ifdef DEBUG_WIDGETS
- qDebug("nsCommonWidget::Invalidate2 container=%p widget=%p", (void*)mContainer, (void*)mWidget);
-#endif
- if (!mWidget)
- return NS_OK;
-
- if (aIsSynchronous)
- mWidget->repaint(aRect.x, aRect.y, aRect.width, aRect.height);
- else
- mWidget->update(aRect.x, aRect.y, aRect.width, aRect.height);
-
- return NS_OK;
-}
-
-NS_IMETHODIMP
-nsCommonWidget::Update()
-{
-#ifdef DEBUG_WIDGETS
- qDebug("nsCommonWidget::Update container=%p widget=%p", (void*)mContainer, (void*)mWidget);
-#endif
- if (!mWidget)
- return NS_OK;
- mWidget->update();
-
- return NS_OK;
-}
-
-NS_IMETHODIMP
-nsCommonWidget::SetColorMap(nsColorMap*)
-{
- return NS_OK;
-}
-
-NS_IMETHODIMP
-nsCommonWidget::Scroll(int aDx, int aDy, nsRect *aClipRect)
-{
- if (mWidget)
- mWidget->scroll(aDx, aDy);
-
- // Update bounds on our child windows
- for (nsIWidget* kid = mFirstChild; kid; kid = kid->GetNextSibling()) {
- nsRect bounds;
- kid->GetBounds(bounds);
- bounds.x += aDx;
- bounds.y += aDy;
- static_cast<nsBaseWidget*>(kid)->SetBounds(bounds);
- }
- return NS_OK;
-}
-
-NS_IMETHODIMP
-nsCommonWidget::ScrollWidgets(PRInt32 aDx,
- PRInt32 aDy)
-{
- if (mWidget)
- mWidget->scroll(aDx, aDy);
-
- return NS_OK;
-}
-
-void*
-nsCommonWidget::GetNativeData(PRUint32 aDataType)
-{
- switch(aDataType) {
- case NS_NATIVE_WINDOW:
- return mWidget;
- break;
-
- case NS_NATIVE_DISPLAY:
- if (mWidget)
- return mWidget->x11Info().display();
- break;
-
- case NS_NATIVE_WIDGET:
- return mWidget;
- break;
-
- case NS_NATIVE_PLUGIN_PORT:
- if (mWidget)
- return (void*)mWidget->winId();
- break;
-
- default:
- break;
+ if (nsEvent->charCode) {
+ nsEvent->keyCode = 0;
}
-
- return nsnull;
-}
-
-NS_IMETHODIMP
-nsCommonWidget::SetTitle(const nsAString &str)
-{
- nsAString::const_iterator it;
- QString qStr((QChar*)str.BeginReading(it).get(), -1);
-
- if (mContainer)
- mContainer->setWindowTitle(qStr);
-
- return NS_OK;
-}
-
-NS_IMETHODIMP
-nsCommonWidget::SetMenuBar(nsIMenuBar*)
-{
- qWarning("XXXXX SetMenuBar");
- return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-NS_IMETHODIMP
-nsCommonWidget::ShowMenuBar(int)
-{
-
- qWarning("XXXXX ShowMenuBar");
- return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-NS_IMETHODIMP
-nsCommonWidget::WidgetToScreen(const nsRect &aOldRect, nsRect &aNewRect)
-{
- aNewRect.width = aOldRect.width;
- aNewRect.height = aOldRect.height;
-
- if (mWidget) {
- PRInt32 x,y;
-
- QPoint offset(0,0);
- offset = mWidget->mapToGlobal(offset);
- x = offset.x();
- y = offset.y();
-
- aNewRect.x = aOldRect.x + x;
- aNewRect.y = aOldRect.y + y;
+ else {
+ nsEvent->keyCode = QtKeyCodeToDOMKeyCode(qEvent->key());
}
-
- return NS_OK;
-}
-
-NS_IMETHODIMP
-nsCommonWidget::ScreenToWidget(const nsRect &aOldRect, nsRect &aNewRect)
-{
- if (mWidget) {
- PRInt32 X,Y;
-
- QPoint offset(0,0);
- offset = mWidget->mapFromGlobal(offset);
- X = offset.x();
- Y = offset.y();
-
- aNewRect.x = aOldRect.x + X;
- aNewRect.y = aOldRect.y + Y;
- }
- return NS_OK;
-}
-
-NS_IMETHODIMP
-nsCommonWidget::BeginResizingChildren()
-{
- qWarning("XXXXXX BeginResizingChildren");
- return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-NS_IMETHODIMP
-nsCommonWidget::EndResizingChildren()
-{
- qWarning("XXXXXXX EndResizingChildren");
- return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-NS_IMETHODIMP
-nsCommonWidget::GetPreferredSize(PRInt32 &aWidth, PRInt32 &aHeight)
-{
- if (!mWidget)
- return NS_ERROR_FAILURE;
-
- QSize sh = mWidget->sizeHint();
- aWidth = qMax(0, sh.width());
- aHeight = qMax(0, sh.height());
- return NS_OK;
-}
-
-NS_IMETHODIMP
-nsCommonWidget::SetPreferredSize(int w, int h)
-{
- qWarning("XXX SetPreferredSize %d %d", w, h);
- return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-NS_IMETHODIMP
-nsCommonWidget::DispatchEvent(nsGUIEvent *aEvent, nsEventStatus &aStatus)
-{
- aStatus = nsEventStatus_eIgnore;
-
- // hold a widget reference while we dispatch this event
- nsIWidget* widget = aEvent->widget;
- NS_ADDREF(widget);
-
- if (mEventCallback)
- aStatus = (*mEventCallback)(aEvent);
-
- // dispatch to event listener if event was not consumed
- if ((aStatus != nsEventStatus_eIgnore) && mEventListener)
- aStatus = mEventListener->ProcessEvent(*aEvent);
-
- NS_IF_RELEASE(widget);
-
- return NS_OK;
-}
-
-NS_IMETHODIMP
-nsCommonWidget::CaptureRollupEvents(nsIRollupListener*, PRBool, PRBool)
-{
- return NS_OK;
+*/
}
void
nsCommonWidget::DispatchGotFocusEvent(void)
{
nsGUIEvent event(PR_TRUE, NS_GOTFOCUS, this);
nsEventStatus status;
DispatchEvent(&event, status);
@@ -726,734 +145,272 @@ nsCommonWidget::DispatchResizeEvent(nsRe
nsSizeEvent event(PR_TRUE, NS_SIZE, this);
event.windowSize = &aRect;
event.refPoint.x = aRect.x;
event.refPoint.y = aRect.y;
event.mWinWidth = aRect.width;
event.mWinHeight = aRect.height;
- DispatchEvent(&event, aStatus);
+ nsEventStatus status;
+ DispatchEvent(&event, status);
}
-bool
-nsCommonWidget::mousePressEvent(QMouseEvent *e)
+NS_IMETHODIMP
+nsCommonWidget::DispatchEvent(nsGUIEvent *aEvent,
+ nsEventStatus &aStatus)
{
- //qDebug("mousePressEvent mWidget=%p", (void*)mWidget);
-// backTrace();
- PRUint32 eventType;
-
- switch (e->button()) {
- case Qt::MidButton:
- eventType = nsMouseEvent::eMiddleButton;
- break;
- case Qt::RightButton:
- eventType = nsMouseEvent::eRightButton;
- break;
- default:
- eventType = nsMouseEvent::eLeftButton;
- break;
- }
-
- nsMouseEvent event(PR_TRUE, NS_MOUSE_BUTTON_DOWN, this, nsMouseEvent::eReal);
- event.button = eventType;
-
- InitMouseEvent(&event, e, 1);
-
- nsEventStatus status;
- DispatchEvent(&event, status);
+#ifdef DEBUG
+ debug_DumpEvent(stdout, aEvent->widget, aEvent,
+ nsCAutoString("something"), 0);
+#endif
- // right menu click on linux should also pop up a context menu
- if (eventType == nsMouseEvent::eRightButton) {
- nsMouseEvent contextMenuEvent(PR_TRUE, NS_CONTEXTMENU, this,
- nsMouseEvent::eReal);
- InitMouseEvent(&contextMenuEvent, e, 1);
- DispatchEvent(&contextMenuEvent, status);
- }
+ aStatus = nsEventStatus_eIgnore;
- return ignoreEvent(status);
-}
-
-bool
-nsCommonWidget::mouseReleaseEvent(QMouseEvent *e)
-{
- //qDebug("mouseReleaseEvent mWidget=%p", (void*)mWidget);
- PRUint32 eventType;
+ // send it to the standard callback
+ if (mEventCallback)
+ aStatus = (* mEventCallback)(aEvent);
- switch (e->button()) {
- case Qt::MidButton:
- eventType = nsMouseEvent::eMiddleButton;
- break;
- case Qt::RightButton:
- eventType = nsMouseEvent::eRightButton;
- break;
- default:
- eventType = nsMouseEvent::eLeftButton;
- break;
- }
+ // dispatch to event listener if event was not consumed
+ if ((aStatus != nsEventStatus_eIgnore) && mEventListener)
+ aStatus = mEventListener->ProcessEvent(*aEvent);
- nsMouseEvent event(PR_TRUE, NS_MOUSE_BUTTON_UP, this, nsMouseEvent::eReal);
- event.button = eventType;
-
- InitMouseEvent(&event, e, 1);
-
- //not pressed
- nsEventStatus status;
- DispatchEvent(&event, status);
- return ignoreEvent(status);
+ return NS_OK;
}
-bool
-nsCommonWidget::mouseDoubleClickEvent(QMouseEvent *e)
+NS_IMETHODIMP
+nsCommonWidget::Show(PRBool aState)
{
- PRUint32 eventType;
+ mIsShown = aState;
+
+ LOG(("nsCommonWidget::Show [%p] state %d\n", (void *)this, aState));
- switch (e->button()) {
- case Qt::MidButton:
- eventType = nsMouseEvent::eMiddleButton;
- break;
- case Qt::RightButton:
- eventType = nsMouseEvent::eRightButton;
- break;
- default:
- eventType = nsMouseEvent::eLeftButton;
- break;
+ // Ok, someone called show on a window that isn't sized to a sane
+ // value. Mark this window as needing to have Show() called on it
+ // and return.
+ if ((aState && !AreBoundsSane()) || !mCreated) {
+ LOG(("\tbounds are insane or window hasn't been created yet\n"));
+ mNeedsShow = PR_TRUE;
+ return NS_OK;
}
- nsMouseEvent event(PR_TRUE, NS_MOUSE_DOUBLECLICK, this, nsMouseEvent::eReal);
- event.button = eventType;
-
- InitMouseEvent(&event, e, 2);
- //pressed
- nsEventStatus status;
- DispatchEvent(&event, status);
- return ignoreEvent(status);
-}
+ // If someone is hiding this widget, clear any needing show flag.
+ if (!aState)
+ mNeedsShow = PR_FALSE;
-bool
-nsCommonWidget::mouseMoveEvent(QMouseEvent *e)
-{
- nsMouseEvent event(PR_TRUE, NS_MOUSE_MOVE, this, nsMouseEvent::eReal);
+ // If someone is showing this window and it needs a resize then
+ // resize the widget.
+ if (aState) {
+ if (mNeedsMove) {
+ LOG(("\tresizing\n"));
+ NativeResize(mBounds.x, mBounds.y, mBounds.width, mBounds.height,
+ PR_FALSE);
+ } else if (mNeedsResize) {
+ NativeResize(mBounds.width, mBounds.height, PR_FALSE);
+ }
+ }
- InitMouseEvent(&event, e, 0);
- nsEventStatus status;
- DispatchEvent(&event, status);
- return ignoreEvent(status);
+ NativeShow(aState);
+
+ return NS_OK;
}
-bool
-nsCommonWidget::wheelEvent(QWheelEvent *e)
+NS_IMETHODIMP
+nsCommonWidget::Resize(PRInt32 aWidth, PRInt32 aHeight, PRBool aRepaint)
{
- nsMouseScrollEvent nsEvent(PR_TRUE, NS_MOUSE_SCROLL, this);
+ mBounds.width = aWidth;
+ mBounds.height = aHeight;
- InitMouseWheelEvent(&nsEvent, e);
+ if (!mCreated)
+ return NS_OK;
- nsEventStatus status;
- DispatchEvent(&nsEvent, status);
- return ignoreEvent(status);
-}
+ // There are several cases here that we need to handle, based on a
+ // matrix of the visibility of the widget, the sanity of this resize
+ // and whether or not the widget was previously sane.
-bool
-nsCommonWidget::keyPressEvent(QKeyEvent *e)
-{
- //qDebug("keyPressEvent");
-
- nsEventStatus status;
+ // Has this widget been set to visible?
+ if (mIsShown) {
+ // Are the bounds sane?
+ if (AreBoundsSane()) {
+ // Yep? Resize the window
+ //Maybe, the toplevel has moved
- // If the key repeat flag isn't set then set it so we don't send
- // another key down event on the next key press -- DOM events are
- // key down, key press and key up. X only has key press and key
- // release. gtk2 already filters the extra key release events for
- // us.
+ // Note that if the widget needs to be shown because it
+ // was previously insane in Resize(x,y,w,h), then we need
+ // to set the x and y here too, because the widget wasn't
+ // moved back then
+ if (mIsTopLevel || mNeedsShow)
+ NativeResize(mBounds.x, mBounds.y,
+ mBounds.width, mBounds.height, aRepaint);
+ else
+ NativeResize(mBounds.width, mBounds.height, aRepaint);
- nsKeyEvent pressEvent(PR_TRUE, NS_KEY_PRESS, this);
- InitKeyEvent(&pressEvent, e);
- pressEvent.charCode = (PRInt32)e->text()[0].unicode();
-
- if (!e->isAutoRepeat()) {
-
- // send the key down event
- nsKeyEvent downEvent(PR_TRUE, NS_KEY_DOWN, this);
- InitKeyEvent(&downEvent, e);
- DispatchEvent(&downEvent, status);
- if (ignoreEvent(status)) { // If prevent default on keydown, do same for keypress
- pressEvent.flags |= NS_EVENT_FLAG_NO_DEFAULT;
+ // Does it need to be shown because it was previously insane?
+ if (mNeedsShow)
+ NativeShow(PR_TRUE);
+ }
+ else {
+ // If someone has set this so that the needs show flag is false
+ // and it needs to be hidden, update the flag and hide the
+ // window. This flag will be cleared the next time someone
+ // hides the window or shows it. It also prevents us from
+ // calling NativeShow(PR_FALSE) excessively on the window which
+ // causes unneeded X traffic.
+ if (!mNeedsShow) {
+ mNeedsShow = PR_TRUE;
+ NativeShow(PR_FALSE);
+ }
+ }
+ }
+ // If the widget hasn't been shown, mark the widget as needing to be
+ // resized before it is shown.
+ else {
+ if (AreBoundsSane() && mListenForResizes) {
+ // For widgets that we listen for resizes for (widgets created
+ // with native parents) we apparently _always_ have to resize. I
+ // dunno why, but apparently we're lame like that.
+ NativeResize(aWidth, aHeight, aRepaint);
+ }
+ else {
+ mNeedsResize = PR_TRUE;
}
}
- // before we dispatch a key, check if it's the context menu key.
- // If so, send a context menu key event instead.
- if (isContextMenuKey(pressEvent)) {
- nsMouseEvent contextMenuEvent(PR_TRUE, 0, nsnull, nsMouseEvent::eReal);
- keyEventToContextMenuEvent(&pressEvent, &contextMenuEvent);
- DispatchEvent(&contextMenuEvent, status);
- }
- else {
- // send the key press event
- DispatchEvent(&pressEvent, status);
+ // synthesize a resize event if this isn't a toplevel
+ if (mIsTopLevel || mListenForResizes) {
+ nsRect rect(mBounds.x, mBounds.y, aWidth, aHeight);
+ nsEventStatus status;
+ DispatchResizeEvent(rect, status);
}
- return ignoreEvent(status);
-}
-
-bool
-nsCommonWidget::keyReleaseEvent(QKeyEvent *e)
-{
- nsKeyEvent event(PR_TRUE, NS_KEY_UP, this);
-
- InitKeyEvent(&event, e);
-
- nsEventStatus status;
- DispatchEvent(&event, status);
- return ignoreEvent(status);
-}
-
-bool
-nsCommonWidget::focusInEvent(QFocusEvent *)
-{
- if (!mWidget)
- return FALSE;
-
-#ifdef DEBUG_WIDGETS
- qDebug("focusInEvent mWidget=%p, mContainer=%p", (void*)mWidget, (void*)mContainer);
-#endif
-
- DispatchGotFocusEvent();
-
- DispatchActivateEvent();
-
- return FALSE;
-}
-
-bool
-nsCommonWidget::focusOutEvent(QFocusEvent *)
-{
-#ifdef DEBUG_WIDGETS
- qDebug("focusOutEvent mWidget=%p,mContainer = %p", (void*)mWidget, (void*)mContainer);
-#endif
-
- DispatchLostFocusEvent();
- if (mContainer)
- DispatchDeactivateEvent();
-
- return FALSE;
-}
-
-bool
-nsCommonWidget::enterEvent(QEvent *)
-{
- nsMouseEvent event(PR_TRUE, NS_MOUSE_ENTER, this, nsMouseEvent::eReal);
-
- QPoint pt = QCursor::pos();
-
- event.refPoint.x = nscoord(pt.x());
- event.refPoint.y = nscoord(pt.y());
-
- nsEventStatus status;
- DispatchEvent(&event, status);
- return FALSE;
-}
-
-bool
-nsCommonWidget::leaveEvent(QEvent *aEvent)
-{
- nsMouseEvent event(PR_TRUE, NS_MOUSE_EXIT, this, nsMouseEvent::eReal);
-
- QPoint pt = QCursor::pos();
-
- event.refPoint.x = nscoord(pt.x());
- event.refPoint.y = nscoord(pt.y());
-
- nsEventStatus status;
- DispatchEvent(&event, status);
- return FALSE;
-}
-
-bool
-nsCommonWidget::paintEvent(QPaintEvent *e)
-{
- //qDebug("paintEvent: mWidget=%p x = %d, y = %d, width = %d, height = %d", (void*)mWidget,
- //e->rect().x(), e->rect().y(), e->rect().width(), e->rect().height());
-// qDebug("paintEvent: Widgetrect %d %d %d %d", mWidget->x(), mWidget->y(),
-// mWidget->width(), mWidget->height());
-
- QRect r = e->rect();
- if (!r.isValid())
- r = mWidget->rect();
- nsRect rect(r.x(), r.y(), r.width(), r.height());
-
- nsCOMPtr<nsIRenderingContext> rc = getter_AddRefs(GetRenderingContext());
-
- // Generate XPFE paint event
- nsPaintEvent event(PR_TRUE, NS_PAINT, this);
- event.refPoint.x = 0;
- event.refPoint.y = 0;
- event.rect = ▭
- // XXX fix this!
- event.region = nsnull;
- // XXX fix this!
- event.renderingContext = rc;
-
- nsEventStatus status;
- DispatchEvent(&event, status);
- return ignoreEvent(status);
+ return NS_OK;
}
-bool
-nsCommonWidget::moveEvent(QMoveEvent *e)
+NS_IMETHODIMP
+nsCommonWidget::Resize(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight,
+ PRBool aRepaint)
{
- // can we shortcut?
- if (!mWidget || (mBounds.x == e->pos().x() &&
- mBounds.y == e->pos().y()))
- return FALSE;
+ mBounds.x = aX;
+ mBounds.y = aY;
+ mBounds.width = aWidth;
+ mBounds.height = aHeight;
+
+ mPlaced = PR_TRUE;
-#ifdef DEBUG_WIDGETS
- bool shown = mWidget ? !mWidget->isHidden() : false;
- bool popup = mWidget ? mWidget->windowType() == Qt::Popup : false;
+ if (!mCreated)
+ return NS_OK;
+
+ // There are several cases here that we need to handle, based on a
+ // matrix of the visibility of the widget, the sanity of this resize
+ // and whether or not the widget was previously sane.
- qDebug("moveEvent mWidget=%p %d %d (%s, %s)", (void*)mWidget, e->pos().x(), e->pos().y(),
- shown? "shown": "hidden", popup ? "popup": "widget");
-#endif
-
- // Toplevel windows need to have their bounds set so that we can
- // keep track of our location. It's not often that the x,y is set
- // by the layout engine. Width and height are set elsewhere.
- QPoint pos = e->pos();
-
- if (mContainer) {
- // Need to translate this into the right coordinates
- nsRect oldrect, newrect;
- WidgetToScreen(oldrect, newrect);
- mBounds.x = newrect.x;
- mBounds.y = newrect.y;
-#ifdef DEBUG_WIDGETS
- qDebug("BOUNDS are [%d, %d]", mBounds.x, mBounds.y);
-#endif
+ // Has this widget been set to visible?
+ if (mIsShown) {
+ // Are the bounds sane?
+ if (AreBoundsSane()) {
+ // Yep? Resize the window
+ NativeResize(aX, aY, aWidth, aHeight, aRepaint);
+ // Does it need to be shown because it was previously insane?
+ if (mNeedsShow)
+ NativeShow(PR_TRUE);
+ }
+ else {
+ // If someone has set this so that the needs show flag is false
+ // and it needs to be hidden, update the flag and hide the
+ // window. This flag will be cleared the next time someone
+ // hides the window or shows it. It also prevents us from
+ // calling NativeShow(PR_FALSE) excessively on the window which
+ // causes unneeded X traffic.
+ if (!mNeedsShow) {
+ mNeedsShow = PR_TRUE;
+ NativeShow(PR_FALSE);
+ }
+ }
+ }
+ // If the widget hasn't been shown, mark the widget as needing to be
+ // resized before it is shown
+ else {
+ if (AreBoundsSane() && mListenForResizes){
+ // For widgets that we listen for resizes for (widgets created
+ // with native parents) we apparently _always_ have to resize. I
+ // dunno why, but apparently we're lame like that.
+ NativeResize(aX, aY, aWidth, aHeight, aRepaint);
+ }
+ else {
+ mNeedsResize = PR_TRUE;
+ mNeedsMove = PR_TRUE;
+ }
}
- nsGUIEvent event(PR_TRUE, NS_MOVE, this);
- event.refPoint.x = pos.x();
- event.refPoint.y = pos.y();
-
- // XXX mozilla will invalidate the entire window after this move
- // complete. wtf?
- nsEventStatus status;
- DispatchEvent(&event, status);
- return ignoreEvent(status);
-}
-
-bool
-nsCommonWidget::resizeEvent(QResizeEvent *e)
-{
- nsRect rect;
-
- // Generate XPFE resize event
- GetBounds(rect);
- rect.width = e->size().width();
- rect.height = e->size().height();
+ if (mIsTopLevel || mListenForResizes) {
+ // synthesize a resize event
+ nsRect rect(aX, aY, aWidth, aHeight);
+ nsEventStatus status;
+ DispatchResizeEvent(rect, status);
+ }
- mBounds.width = rect.width;
- mBounds.height = rect.height;
-
-#ifdef DEBUG_WIDGETS
- qDebug("resizeEvent: mWidget=%p, aWidth=%d, aHeight=%d, aX = %d, aY = %d", (void*)mWidget,
- rect.width, rect.height, rect.x, rect.y);
-#endif
-
- nsEventStatus status;
- DispatchResizeEvent(rect, status);
- return ignoreEvent(status);
-}
-
-bool
-nsCommonWidget::closeEvent(QCloseEvent *)
-{
- nsGUIEvent event(PR_TRUE, NS_XUL_CLOSE, this);
-
- event.refPoint.x = 0;
- event.refPoint.y = 0;
-
- nsEventStatus status;
- DispatchEvent(&event, status);
-
- return ignoreEvent(status);
+ return NS_OK;
}
-bool
-nsCommonWidget::contextMenuEvent(QContextMenuEvent *)
-{
- //qDebug("context menu");
- return false;
-}
-
-bool
-nsCommonWidget::imStartEvent(QEvent *)
-{
- qWarning("XXX imStartEvent");
- return false;
-}
-
-bool
-nsCommonWidget::imComposeEvent(QEvent *)
+NS_IMETHODIMP
+nsCommonWidget::GetPreferredSize(PRInt32 &aWidth,
+ PRInt32 &aHeight)
{
- qWarning("XXX imComposeEvent");
- return false;
-}
-
-bool
-nsCommonWidget::imEndEvent(QEvent * )
-{
- qWarning("XXX imComposeEvent");
- return false;
-}
-
-bool
-nsCommonWidget::dragEnterEvent(QDragEnterEvent *)
-{
- qDebug("XXX dragEnterEvent");
- return false;
-}
-
-bool
-nsCommonWidget::dragMoveEvent(QDragMoveEvent *)
-{
- qDebug("XXX dragMoveEvent");
- return false;
+ aWidth = mPreferredWidth;
+ aHeight = mPreferredHeight;
+ return (mPreferredWidth != 0 && mPreferredHeight != 0) ?
+ NS_OK : NS_ERROR_FAILURE;
}
-bool
-nsCommonWidget::dragLeaveEvent(QDragLeaveEvent *)
+NS_IMETHODIMP
+nsCommonWidget::SetPreferredSize(PRInt32 aWidth,
+ PRInt32 aHeight)
{
- qDebug("XXX dragLeaveEvent");
- return false;
-}
-
-bool
-nsCommonWidget::dropEvent(QDropEvent *)
-{
- qDebug("XXX dropEvent");
- return false;
+ mPreferredWidth = aWidth;
+ mPreferredHeight = aHeight;
+ return NS_OK;
}
-bool
-nsCommonWidget::showEvent(QShowEvent *)
+NS_IMETHODIMP
+nsCommonWidget::Enable(PRBool aState)
{
-#ifdef DEBUG_WIDGETS
- qDebug("showEvent mWidget=%p", (void*)mWidget);
-#endif
-
- QRect r = mWidget->rect();
- nsRect rect(r.x(), r.y(), r.width(), r.height());
+ mEnabled = aState;
- nsCOMPtr<nsIRenderingContext> rc = getter_AddRefs(GetRenderingContext());
- // Generate XPFE paint event
- nsPaintEvent event(PR_TRUE, NS_PAINT, this);
- event.refPoint.x = 0;
- event.refPoint.y = 0;
- event.rect = ▭
- // XXX fix this!
- event.region = nsnull;
- // XXX fix this!
- event.renderingContext = rc;
-
- nsEventStatus status;
- DispatchEvent(&event, status);
-
- return false;
+ return NS_OK;
}
-bool
-nsCommonWidget::hideEvent(QHideEvent *)
+NS_IMETHODIMP
+nsCommonWidget::IsEnabled(PRBool *aState)
{
-#ifdef DEBUG_WIDGETS
- qDebug("hideEvent mWidget=%p", (void*)mWidget);
-#endif
- return false;
+ *aState = mEnabled;
+
+ return NS_OK;
}
void
-nsCommonWidget::InitKeyEvent(nsKeyEvent *nsEvent, QKeyEvent *qEvent)
+nsCommonWidget::OnDestroy(void)
{
- nsEvent->isShift = qEvent->modifiers() & Qt::ShiftModifier;
- nsEvent->isControl = qEvent->modifiers() & Qt::ControlModifier;
- nsEvent->isAlt = qEvent->modifiers() & Qt::AltModifier;
- nsEvent->isMeta = qEvent->modifiers() & Qt::MetaModifier;
- nsEvent->time = 0;
+ if (mOnDestroyCalled)
+ return;
- if (qEvent->text().length() && qEvent->text()[0].isPrint()) {
- nsEvent->charCode = (PRInt32)qEvent->text()[0].unicode();
- }
- else {
- nsEvent->charCode = 0;
- }
-
- if (nsEvent->charCode) {
- nsEvent->keyCode = 0;
- }
- else {
- nsEvent->keyCode = QtKeyCodeToDOMKeyCode(qEvent->key());
- }
-}
-
-void
-nsCommonWidget::InitMouseEvent(nsMouseEvent *nsEvent, QMouseEvent *qEvent, int aClickCount)
-{
- nsEvent->refPoint.x = nscoord(qEvent->x());
- nsEvent->refPoint.y = nscoord(qEvent->y());
+ mOnDestroyCalled = PR_TRUE;
- nsEvent->isShift = qEvent->modifiers() & Qt::ShiftModifier;
- nsEvent->isControl = qEvent->modifiers() & Qt::ControlModifier;
- nsEvent->isAlt = qEvent->modifiers() & Qt::AltModifier;
- nsEvent->isMeta = qEvent->modifiers() & Qt::MetaModifier;
- nsEvent->clickCount = aClickCount;
-}
+ // release references to children, device context, toolkit + app shell
+ nsBaseWidget::OnDestroy();
+
+ // let go of our parent
+ mParent = nsnull;
-void
-nsCommonWidget::InitMouseWheelEvent(nsMouseScrollEvent *aEvent,
- QWheelEvent *qEvent)
-{
- switch (qEvent->orientation()) {
- case Qt::Vertical:
- aEvent->scrollFlags = nsMouseScrollEvent::kIsVertical;
- break;
- case Qt::Horizontal:
- aEvent->scrollFlags = nsMouseScrollEvent::kIsHorizontal;
- break;
- default:
- Q_ASSERT(0);
- break;
- }
- aEvent->delta = (int)((qEvent->delta() / WHEEL_DELTA) * -3);
+ nsCOMPtr<nsIWidget> kungFuDeathGrip = this;
- aEvent->refPoint.x = nscoord(qEvent->x());
- aEvent->refPoint.y = nscoord(qEvent->y());
-
- aEvent->isShift = qEvent->modifiers() & Qt::ShiftModifier;
- aEvent->isControl = qEvent->modifiers() & Qt::ControlModifier;
- aEvent->isAlt = qEvent->modifiers() & Qt::AltModifier;
- aEvent->isMeta = qEvent->modifiers() & Qt::MetaModifier;
- aEvent->time = 0;
-}
-
-void
-nsCommonWidget::CommonCreate(nsIWidget *aParent, PRBool aListenForResizes)
-{
- mParent = aParent;
- mListenForResizes = aListenForResizes;
+ nsGUIEvent event(PR_TRUE, NS_DESTROY, this);
+ nsEventStatus status;
+ DispatchEvent(&event, status);
}
PRBool
-nsCommonWidget::AreBoundsSane() const
+nsCommonWidget::AreBoundsSane(void)
{
if (mBounds.width > 0 && mBounds.height > 0)
return PR_TRUE;
return PR_FALSE;
}
-
-NS_IMETHODIMP
-nsCommonWidget::Create(nsIWidget *aParent, const nsRect &aRect, EVENT_CALLBACK aHandleEventFunction,
- nsIDeviceContext *aContext, nsIAppShell *aAppShell, nsIToolkit *aToolkit,
- nsWidgetInitData *aInitData)
-{
- return NativeCreate(aParent, nsnull, aRect, aHandleEventFunction, aContext, aAppShell,
- aToolkit, aInitData);
-}
-
-NS_IMETHODIMP
-nsCommonWidget::Create(nsNativeWidget aParent, const nsRect &aRect, EVENT_CALLBACK aHandleEventFunction,
- nsIDeviceContext *aContext, nsIAppShell *aAppShell, nsIToolkit *aToolkit,
- nsWidgetInitData *aInitData)
-{
- return NativeCreate(nsnull, (QWidget*)aParent, aRect, aHandleEventFunction, aContext, aAppShell,
- aToolkit, aInitData);
-}
-
-nsresult
-nsCommonWidget::NativeCreate(nsIWidget *aParent,
- QWidget *aNativeParent,
- const nsRect &aRect,
- EVENT_CALLBACK aHandleEventFunction,
- nsIDeviceContext *aContext,
- nsIAppShell *aAppShell,
- nsIToolkit *aToolkit,
- nsWidgetInitData *aInitData)
-{
- // only set the base parent if we're going to be a dialog or a
- // toplevel
- nsIWidget *baseParent = aInitData &&
- (aInitData->mWindowType == eWindowType_dialog ||
- aInitData->mWindowType == eWindowType_toplevel ||
- aInitData->mWindowType == eWindowType_invisible) ?
- nsnull : aParent;
-
- // initialize all the common bits of this class
- BaseCreate(baseParent, aRect, aHandleEventFunction, aContext,
- aAppShell, aToolkit, aInitData);
-
- // Do we need to listen for resizes?
- PRBool listenForResizes = PR_FALSE;;
- if (aNativeParent || (aInitData && aInitData->mListenForResizes))
- listenForResizes = PR_TRUE;
-
- // and do our common creation
- CommonCreate(aParent, listenForResizes);
-
- // save our bounds
- mBounds = aRect;
-
- QWidget *parent = 0;
- if (aParent != nsnull)
- parent = (QWidget*)aParent->GetNativeData(NS_NATIVE_WIDGET);
- else
- parent = aNativeParent;
-
- mWidget = createQWidget(parent, aInitData);
-
- Initialize(mWidget);
-
- Resize(mBounds.width, mBounds.height, PR_FALSE);
-
- return NS_OK;
-}
-
-nsCursor nsCommonWidget::GetCursor()
-{
- return mCursor;
-}
-
-NS_METHOD nsCommonWidget::SetCursor(nsCursor aCursor)
-{
- mCursor = aCursor;
- Qt::CursorShape cursor = Qt::ArrowCursor;
- switch(mCursor) {
- case eCursor_standard:
- cursor = Qt::ArrowCursor;
- break;
- case eCursor_wait:
- cursor = Qt::WaitCursor;
- break;
- case eCursor_select:
- cursor = Qt::IBeamCursor;
- break;
- case eCursor_hyperlink:
- cursor = Qt::PointingHandCursor;
- break;
- case eCursor_ew_resize:
- cursor = Qt::SplitHCursor;
- break;
- case eCursor_ns_resize:
- cursor = Qt::SplitVCursor;
- break;
- case eCursor_nw_resize:
- case eCursor_se_resize:
- cursor = Qt::SizeBDiagCursor;
- break;
- case eCursor_ne_resize:
- case eCursor_sw_resize:
- cursor = Qt::SizeFDiagCursor;
- break;
- case eCursor_crosshair:
- case eCursor_move:
- cursor = Qt::SizeAllCursor;
- break;
- case eCursor_help:
- cursor = Qt::WhatsThisCursor;
- break;
- case eCursor_copy:
- case eCursor_alias:
- break;
- case eCursor_context_menu:
- case eCursor_cell:
- case eCursor_grab:
- case eCursor_grabbing:
- case eCursor_spinning:
- case eCursor_zoom_in:
- case eCursor_zoom_out:
-
- default:
- break;
- }
- mWidget->setCursor(cursor);
- return NS_OK;
-}
-
-NS_METHOD nsCommonWidget::SetModal(PRBool aModal)
-{
-#ifdef DEBUG_WIDGETS
- qDebug("------------> SetModal mWidget=%p",(void*) mWidget);
-#endif
-
- MozQWidget *mozWidget = static_cast<MozQWidget*>(mWidget);
- if (mozWidget)
- mozWidget->setModal(aModal);
-
- return NS_OK;
-}
-
-NS_IMETHODIMP nsCommonWidget::GetScreenBounds(nsRect &aRect)
-{
- nsRect origin(0,0,mBounds.width,mBounds.height);
- WidgetToScreen(origin, aRect);
- return NS_OK;
-}
-
-void
-nsCommonWidget::NativeShow(PRBool aState)
-{
- mNeedsShow = PR_FALSE;
-
- if (!mWidget) {
- //XXX: apperently can be null during the printing, check whether
- // that's true
- qDebug("nsCommon::Show : widget empty");
- return;
- }
- mWidget->setShown(aState);
-}
-
-void
-nsCommonWidget::NativeResize(PRInt32 aWidth, PRInt32 aHeight, PRBool aRepaint)
-{
- mNeedsResize = PR_FALSE;
-
- mWidget->resize( aWidth, aHeight);
-
- if (aRepaint) {
- if (mWidget->isVisible())
- mWidget->repaint();
- }
-}
-
-void
-nsCommonWidget::NativeResize(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight,
- PRBool aRepaint)
-{
- mNeedsResize = PR_FALSE;
-
- QPoint pos(aX, aY);
- if (mContainer)
- {
- if (mParent && mWidget->windowType() == Qt::Popup) {
- nsRect oldrect, newrect;
- oldrect.x = aX;
- oldrect.y = aY;
-
- mParent->WidgetToScreen(oldrect, newrect);
-
- pos = QPoint(newrect.x, newrect.y);
-#ifdef DEBUG_WIDGETS
- qDebug("pos is [%d,%d]", pos.x(), pos.y());
-#endif
- } else {
-#ifdef DEBUG_WIDGETS
- qDebug("Widget with original position? (%p)", mWidget);
-#endif
- }
- }
-
- mWidget->setGeometry(pos.x(), pos.y(), aWidth, aHeight);
-
- if (aRepaint) {
- if (mWidget->isVisible())
- mWidget->repaint();
- }
-}
--- a/widget/src/qt/nsCommonWidget.h
+++ b/widget/src/qt/nsCommonWidget.h
@@ -1,215 +1,160 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim:expandtab:shiftwidth=4:tabstop=4:
+ */
+/* ***** 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 mozilla.org code.
*
- * The Initial Developer of the Original Code is
- * Zack Rusin <zack@kde.org>.
- * Portions created by the Initial Developer are Copyright (C) 2004
- * the Initial Developer. All Rights Reserved.
+ * The Initial Developer of the Original Code is Christopher Blizzard
+ * <blizzard@mozilla.org>. Portions created by the Initial Developer
+ * are Copyright (C) 2001 the Initial Developer. All Rights Reserved.
*
* Contributor(s):
- * Lars Knoll <knoll@kde.org>
- * Zack Rusin <zack@kde.org>
*
* 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 ***** */
-#ifndef NSCOMMONWIDGET_H
-#define NSCOMMONWIDGET_H
+
+#ifndef __nsCommonWidget_h__
+#define __nsCommonWidget_h__
#include "nsBaseWidget.h"
+#include "nsGUIEvent.h"
+#include <QKeyEvent>
-#include "nsEvent.h"
+//#ifdef MOZ_LOGGING
+#if 0
+
+// make sure that logging is enabled before including prlog.h
+#define FORCE_PR_LOG
-#include <qevent.h> //XXX switch for forward-decl
+#include "prlog.h"
+
+extern PRLogModuleInfo *gWidgetLog;
+extern PRLogModuleInfo *gWidgetFocusLog;
+extern PRLogModuleInfo *gWidgetIMLog;
+extern PRLogModuleInfo *gWidgetDrawLog;
-class nsIToolkit;
-class nsWidgetInitData;
-class nsIDeviceContext;
-class nsIAppShell;
-class nsIFontMetrics;
-class nsColorMap;
-class nsFont;
-class nsRect;
-class nsAString;
-class nsIMenuBar;
-class nsGUIEvent;
-class nsIRollupListener;
-class QWidget;
-class nsQtEventDispatcher;
+#define LOG(args) PR_LOG(gWidgetLog, 4, args)
+#define LOGFOCUS(args) PR_LOG(gWidgetFocusLog, 4, args)
+#define LOGIM(args) PR_LOG(gWidgetIMLog, 4, args)
+#define LOGDRAW(args) PR_LOG(gWidgetDrawLog, 4, args)
+
+#else
-class nsCommonWidget : public nsBaseWidget
-{
+#define LOG(args)
+#define LOGFOCUS(args)
+#define LOGIM(args)
+#define LOGDRAW(args)
+
+#endif /* MOZ_LOGGING */
+
+class nsCommonWidget : public nsBaseWidget {
public:
nsCommonWidget();
- ~nsCommonWidget();
-
- NS_DECL_ISUPPORTS_INHERITED
-
- NS_IMETHOD Show(PRBool);
- NS_IMETHOD IsVisible(PRBool&);
-
- NS_IMETHOD ConstrainPosition(PRBool, PRInt32*, PRInt32*);
- NS_IMETHOD Move(PRInt32, PRInt32);
- NS_IMETHOD Resize(PRInt32, PRInt32, PRBool);
- NS_IMETHOD Resize(PRInt32, PRInt32, PRInt32, PRInt32, PRBool);
- NS_IMETHOD Enable(PRBool);
- NS_IMETHOD IsEnabled(PRBool*);
- NS_IMETHOD SetFocus(PRBool araise = PR_FALSE);
-
- virtual nsIFontMetrics* GetFont();
+ virtual ~nsCommonWidget();
- NS_IMETHOD SetFont(const nsFont&);
- NS_IMETHOD Invalidate(PRBool);
- NS_IMETHOD Invalidate(const nsRect&, int);
- NS_IMETHOD Update();
- NS_IMETHOD SetColorMap(nsColorMap*);
- NS_IMETHOD Scroll(PRInt32, PRInt32, nsRect*);
- NS_IMETHOD ScrollWidgets(PRInt32 aDx, PRInt32 aDy);
-
- NS_IMETHOD SetModal(PRBool aModal);
-
- virtual void* GetNativeData(PRUint32);
-
- NS_IMETHOD SetTitle(const nsAString&);
- NS_IMETHOD SetMenuBar(nsIMenuBar*);
- NS_IMETHOD ShowMenuBar(PRBool);
- NS_IMETHOD GetScreenBounds(nsRect &aRect);
- NS_IMETHOD WidgetToScreen(const nsRect&, nsRect&);
- NS_IMETHOD ScreenToWidget(const nsRect&, nsRect&);
- NS_IMETHOD BeginResizingChildren();
- NS_IMETHOD EndResizingChildren();
- NS_IMETHOD GetPreferredSize(PRInt32&, PRInt32&);
- NS_IMETHOD SetPreferredSize(PRInt32, PRInt32);
- NS_IMETHOD DispatchEvent(nsGUIEvent*, nsEventStatus&);
- NS_IMETHOD CaptureRollupEvents(nsIRollupListener*, PRBool, PRBool);
+ virtual nsIWidget *GetParent(void);
- // nsIWidget
- NS_IMETHOD Create(nsIWidget *aParent,
- const nsRect &aRect,
- EVENT_CALLBACK aHandleEventFunction,
- nsIDeviceContext *aContext,
- nsIAppShell *aAppShell,
- nsIToolkit *aToolkit,
- nsWidgetInitData *aInitData);
- NS_IMETHOD Create(nsNativeWidget aParent,
- const nsRect &aRect,
- EVENT_CALLBACK aHandleEventFunction,
- nsIDeviceContext *aContext,
- nsIAppShell *aAppShell,
- nsIToolkit *aToolkit,
- nsWidgetInitData *aInitData);
-
- nsCursor GetCursor();
- NS_METHOD SetCursor(nsCursor aCursor);
-
-protected:
- /**
- * Event handlers (proxied from the actual qwidget).
- * They follow normal Qt widget semantics.
- */
- friend class nsQtEventDispatcher;
- friend class InterceptContainer;
- friend class MozQWidget;
+ void CommonCreate(nsIWidget *aParent, PRBool aListenForResizes);
- virtual bool mousePressEvent(QMouseEvent *);
- virtual bool mouseReleaseEvent(QMouseEvent *);
- virtual bool mouseDoubleClickEvent(QMouseEvent *);
- virtual bool mouseMoveEvent(QMouseEvent *);
- virtual bool wheelEvent(QWheelEvent *);
- virtual bool keyPressEvent(QKeyEvent *);
- virtual bool keyReleaseEvent(QKeyEvent *);
- virtual bool focusInEvent(QFocusEvent *);
- virtual bool focusOutEvent(QFocusEvent *);
- virtual bool enterEvent(QEvent *);
- virtual bool leaveEvent(QEvent *);
- virtual bool paintEvent(QPaintEvent *);
- virtual bool moveEvent(QMoveEvent *);
- virtual bool resizeEvent(QResizeEvent *);
- virtual bool closeEvent(QCloseEvent *);
- virtual bool contextMenuEvent(QContextMenuEvent *);
- virtual bool imStartEvent(QEvent *);
- virtual bool imComposeEvent(QEvent *);
- virtual bool imEndEvent(QEvent *);
- virtual bool dragEnterEvent(QDragEnterEvent *);
- virtual bool dragMoveEvent(QDragMoveEvent *);
- virtual bool dragLeaveEvent(QDragLeaveEvent *);
- virtual bool dropEvent(QDropEvent *);
- virtual bool showEvent(QShowEvent *);
- virtual bool hideEvent(QHideEvent *);
-
-protected:
- virtual QWidget *createQWidget(QWidget *parent, nsWidgetInitData *aInitData) = 0;
- virtual void NativeResize(PRInt32, PRInt32, PRInt32, PRInt32, PRBool);
- virtual void NativeResize(PRInt32, PRInt32, PRBool);
- virtual void NativeShow(PRBool);
-
- static bool ignoreEvent(nsEventStatus aStatus)
- { return aStatus == nsEventStatus_eConsumeNoDefault; }
-
- /**
- * Has to be called in subclasses after they created
- * the actual QWidget if they overwrite the Create
- * calls from the nsCommonWidget class.
- */
- void Initialize(QWidget *widget);
+ // event handling code
+ void InitKeyEvent(nsKeyEvent &aEvent, QKeyEvent *aGdkEvent);
void DispatchGotFocusEvent(void);
void DispatchLostFocusEvent(void);
void DispatchActivateEvent(void);
void DispatchDeactivateEvent(void);
void DispatchResizeEvent(nsRect &aRect, nsEventStatus &aStatus);
- void InitKeyEvent(nsKeyEvent *nsEvent, QKeyEvent *qEvent);
- void InitMouseEvent(nsMouseEvent *nsEvent, QMouseEvent *qEvent, int aClickCount);
- void InitMouseWheelEvent(nsMouseScrollEvent *aEvent, QWheelEvent *qEvent);
+ NS_IMETHOD DispatchEvent(nsGUIEvent *aEvent, nsEventStatus &aStatus);
+
+ // virtual interfaces for some nsIWidget methods
+ virtual void NativeResize(PRInt32 aWidth,
+ PRInt32 aHeight,
+ PRBool aRepaint) = 0;
+
+ virtual void NativeResize(PRInt32 aX,
+ PRInt32 aY,
+ PRInt32 aWidth,
+ PRInt32 aHeight,
+ PRBool aRepaint) = 0;
+
+ virtual void NativeShow (PRBool aAction) = 0;
- void CommonCreate(nsIWidget *aParent, PRBool aListenForResizes);
+ // Some of the nsIWidget methods
+ NS_IMETHOD Show (PRBool aState);
+ NS_IMETHOD Resize (PRInt32 aWidth,
+ PRInt32 aHeight,
+ PRBool aRepaint);
+ NS_IMETHOD Resize (PRInt32 aX,
+ PRInt32 aY,
+ PRInt32 aWidth,
+ PRInt32 aHeight,
+ PRBool aRepaint);
+ NS_IMETHOD GetPreferredSize (PRInt32 &aWidth,
+ PRInt32 &aHeight);
+ NS_IMETHOD SetPreferredSize (PRInt32 aWidth,
+ PRInt32 aHeight);
+ NS_IMETHOD Enable (PRBool aState);
+ NS_IMETHOD IsEnabled (PRBool *aState);
- PRBool AreBoundsSane() const;
+ // called when we are destroyed
+ void OnDestroy(void);
+
+ // called to check and see if a widget's dimensions are sane
+ PRBool AreBoundsSane(void);
protected:
- QWidget *mContainer;
- QWidget *mWidget;
- PRPackedBool mListenForResizes;
- PRPackedBool mNeedsResize;
- PRPackedBool mNeedsShow;
- PRPackedBool mIsShown;
nsCOMPtr<nsIWidget> mParent;
+ // Is this a toplevel window?
+ PRPackedBool mIsTopLevel;
+ // Has this widget been destroyed yet?
+ PRPackedBool mIsDestroyed;
-private:
- nsresult NativeCreate(nsIWidget *aParent,
- QWidget *aNativeParent,
- const nsRect &aRect,
- EVENT_CALLBACK aHandleEventFunction,
- nsIDeviceContext *aContext,
- nsIAppShell *aAppShell,
- nsIToolkit *aToolkit,
- nsWidgetInitData *aInitData);
+ // This is a flag that tracks if we need to resize a widget or
+ // window when we show it.
+ PRPackedBool mNeedsResize;
+ // This is a flag that tracks if we need to move a widget or
+ // window when we show it.
+ PRPackedBool mNeedsMove;
+ // Should we send resize events on all resizes?
+ PRPackedBool mListenForResizes;
+ // This flag tracks if we're hidden or shown.
+ PRPackedBool mIsShown;
+ PRPackedBool mNeedsShow;
+ // is this widget enabled?
+ PRBool mEnabled;
+ // has the native window for this been created yet?
+ PRBool mCreated;
+ // Has anyone set an x/y location for this widget yet? Toplevels
+ // shouldn't be automatically set to 0,0 for first show.
+ PRBool mPlaced;
+ // Preferred sizes
+ PRUint32 mPreferredWidth;
+ PRUint32 mPreferredHeight;
};
-#endif
+#endif /* __nsCommonWidget_h__ */
--- a/widget/src/qt/nsToolkit.cpp
+++ b/widget/src/qt/nsToolkit.cpp
@@ -112,8 +112,23 @@ NS_METHOD NS_GetCurrentToolkit(nsIToolki
}
else {
NS_ADDREF(toolkit);
}
*aResult = toolkit;
}
return rv;
}
+
+void nsToolkit::CreateSharedGC(void)
+{
+ if (mSharedGC)
+ return;
+
+ mSharedGC = new QPixmap();
+}
+
+Qt::HANDLE
+nsToolkit::GetSharedGC(void)
+{
+ // FIXME Not sure
+ return mSharedGC->handle();
+}
--- a/widget/src/qt/nsToolkit.h
+++ b/widget/src/qt/nsToolkit.h
@@ -34,25 +34,50 @@
* 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 ***** */
#ifndef nsToolkit_h__
#define nsToolkit_h__
#include "nsIToolkit.h"
+#include "nsString.h"
+#include <QPixmap>
/**
* Wrapper around the thread running the message pump.
* The toolkit abstraction is necessary because the message pump must
* execute within the same thread that created the widget under Win32.
*/
class nsToolkit : public nsIToolkit
{
public:
nsToolkit();
virtual ~nsToolkit();
-
+
+ void CreateSharedGC(void);
+ Qt::HANDLE GetSharedGC(void);
+
+ /**
+ * Get/set our value of DESKTOP_STARTUP_ID. When non-empty, this is applied
+ * to the next toplevel window to be shown or focused (and then immediately
+ * cleared).
+ */
+ void SetDesktopStartupID(const nsACString& aID) { mDesktopStartupID = aID; }
+ void GetDesktopStartupID(nsACString* aID) { *aID = mDesktopStartupID; }
+
+ /**
+ * Get/set the timestamp value to be used, if non-zero, to focus the
+ * next top-level window to be shown or focused (upon which it is cleared).
+ */
+ void SetFocusTimestamp(PRUint32 aTimestamp) { mFocusTimestamp = aTimestamp; }
+ PRUint32 GetFocusTimestamp() { return mFocusTimestamp; }
+
NS_DECL_ISUPPORTS
NS_IMETHOD Init(PRThread *aThread);
+
+private:
+ nsCString mDesktopStartupID;
+ PRUint32 mFocusTimestamp;
+ QPixmap *mSharedGC;
};
#endif // nsToolkit_h__
--- a/widget/src/qt/nsWidgetFactory.cpp
+++ b/widget/src/qt/nsWidgetFactory.cpp
@@ -73,18 +73,18 @@
// #include "nsGfxCIID.h"
// #include "nsIPrefBranch.h"
// #include "nsIPrefService.h"
//
// #include "nsBidiKeyboard.h"
// #include "nsNativeThemeQt.h"
NS_GENERIC_FACTORY_CONSTRUCTOR(nsWindow)
-NS_GENERIC_FACTORY_CONSTRUCTOR(ChildWindow)
-NS_GENERIC_FACTORY_CONSTRUCTOR(PopupWindow)
+NS_GENERIC_FACTORY_CONSTRUCTOR(nsChildWindow)
+NS_GENERIC_FACTORY_CONSTRUCTOR(nsPopupWindow)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsToolkit)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsHTMLFormatConverter)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsTransferable)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsLookAndFeel)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsScreenManagerQt)
/*
static NS_DEFINE_CID(kNativeScrollCID, NS_NATIVESCROLLBAR_CID);
@@ -106,29 +106,29 @@ static const nsModuleComponentInfo compo
{
{ "Qt nsWindow",
NS_WINDOW_CID,
"@mozilla.org/widgets/window/qt;1",
nsWindowConstructor },
{ "Qt Child nsWindow",
NS_CHILD_CID,
"@mozilla.org/widgets/child_window/qt;1",
- ChildWindowConstructor },
+ nsChildWindowConstructor },
{ "Qt AppShell",
NS_APPSHELL_CID,
"@mozilla.org/widget/appshell/qt;1",
nsAppShellConstructor },
{ "Qt Look And Feel",
NS_LOOKANDFEEL_CID,
"@mozilla.org/widget/lookandfeel/qt;1",
nsLookAndFeelConstructor },
{ "Qt Popup nsWindow",
NS_POPUP_CID,
"@mozilla.org/widgets/popup_window/qt;1",
- PopupWindowConstructor },
+ nsPopupWindowConstructor },
{ "HTML Format Converter",
NS_HTMLFORMATCONVERTER_CID,
"@mozilla.org/widget/htmlformatconverter/qt;1",
nsHTMLFormatConverterConstructor },
{ "Qt Toolkit",
NS_TOOLKIT_CID,
"@mozilla.org/widget/toolkit/qt;1",
nsToolkitConstructor },
--- a/widget/src/qt/nsWindow.cpp
+++ b/widget/src/qt/nsWindow.cpp
@@ -1,180 +1,2956 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim:expandtab:shiftwidth=4:tabstop=4:
+ */
+/* ***** 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 mozilla.org code.
*
- * The Initial Developer of the Original Code is
- * Zack Rusin <zack@kde.org>.
- * Portions created by the Initial Developer are Copyright (C) 2004
- * the Initial Developer. All Rights Reserved.
+ * The Initial Developer of the Original Code is Christopher Blizzard
+ * <blizzard@mozilla.org>. Portions created by the Initial Developer
+ * are Copyright (C) 2001 the Initial Developer. All Rights Reserved.
*
* Contributor(s):
- * Lars Knoll <knoll@kde.org>
- * Zack Rusin <zack@kde.org>
+ * Mats Palmgren <mats.palmgren@bredband.net>
+ * Masayuki Nakano <masayuki@d-toybox.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 ***** */
+
+#include "prlink.h"
+
+#include <QtGui>
+#include <qcursor.h>
+
#include "nsWindow.h"
+#include "nsToolkit.h"
+#include "nsIDeviceContext.h"
+#include "nsIRenderingContext.h"
+#include "nsIRegion.h"
+#include "nsIRollupListener.h"
+#include "nsIMenuRollup.h"
+#include "nsIDOMNode.h"
+
+#include "nsWidgetsCID.h"
+#include "nsIDragService.h"
+
+#include "nsQtKeyUtils.h"
+
+#include <X11/XF86keysym.h>
+
+#include "nsWidgetAtoms.h"
+
+#ifdef MOZ_ENABLE_STARTUP_NOTIFICATION
+#define SN_API_NOT_YET_FROZEN
+#include <startup-notification-1.0/libsn/sn.h>
+#endif
+
+#include "nsIPrefService.h"
+#include "nsIPrefBranch.h"
+#include "nsIServiceManager.h"
+#include "nsIStringBundle.h"
+#include "nsGfxCIID.h"
+
+/* For SetIcon */
+#include "nsAppDirectoryServiceDefs.h"
+#include "nsXPIDLString.h"
+#include "nsIFile.h"
+#include "nsILocalFile.h"
+
+/* SetCursor(imgIContainer*) */
+#include "imgIContainer.h"
+#include "gfxIImageFrame.h"
+#include "nsGfxCIID.h"
+#include "nsIImage.h"
+#include "nsIInterfaceRequestorUtils.h"
+#include "nsAutoPtr.h"
+
+#include "gfxPlatformQt.h"
+#include "gfxXlibSurface.h"
+#include "gfxContext.h"
+#include "gfxImageSurface.h"
+
+#ifdef MOZ_ENABLE_GLITZ
+#include "gfxGlitzSurface.h"
+#include "glitz-glx.h"
+#endif
#include "mozqwidget.h"
-#include "gfxPlatform.h"
-#include "gfxXlibSurface.h"
-
-#include <qwidget.h>
-#include <qlayout.h>
-#include <QX11Info>
-
-NS_IMPL_ISUPPORTS_INHERITED1(nsWindow, nsCommonWidget,
- nsISupportsWeakReference)
+/* For PrepareNativeWidget */
+static NS_DEFINE_IID(kDeviceContextCID, NS_DEVICE_CONTEXT_CID);
+
+/* utility functions */
+static PRBool is_mouse_in_window(QWidget* aWindow,
+ double aMouseX, double aMouseY);
+
+// initialization static functions
+static nsresult initialize_prefs (void);
+
+static NS_DEFINE_IID(kCDragServiceCID, NS_DRAGSERVICE_CID);
+
+#define NS_WINDOW_TITLE_MAX_LENGTH 4095
+
+#define kWindowPositionSlop 20
+
+// QT
+static const int WHEEL_DELTA = 120;
+static PRBool gGlobalsInitialized = PR_FALSE;
+static nsWindow * get_window_for_qt_widget(QWidget *widget);
+static bool ignoreEvent(nsEventStatus aStatus)
+{
+ return aStatus == nsEventStatus_eConsumeNoDefault;
+}
+
+static PRBool
+isContextMenuKey(const nsKeyEvent &aKeyEvent)
+{
+ return ((aKeyEvent.keyCode == NS_VK_F10 && aKeyEvent.isShift &&
+ !aKeyEvent.isControl && !aKeyEvent.isMeta && !aKeyEvent.isAlt) ||
+ (aKeyEvent.keyCode == NS_VK_CONTEXT_MENU && !aKeyEvent.isShift &&
+ !aKeyEvent.isControl && !aKeyEvent.isMeta && !aKeyEvent.isAlt));
+}
+
+static void
+keyEventToContextMenuEvent(const nsKeyEvent* aKeyEvent,
+ nsMouseEvent* aCMEvent)
+{
+ memcpy(aCMEvent, aKeyEvent, sizeof(nsInputEvent));
+// aCMEvent->message = NS_CONTEXTMENU_KEY;
+ aCMEvent->isShift = aCMEvent->isControl = PR_FALSE;
+ aCMEvent->isControl = PR_FALSE;
+ aCMEvent->isAlt = aCMEvent->isMeta = PR_FALSE;
+ aCMEvent->isMeta = PR_FALSE;
+ aCMEvent->clickCount = 0;
+ aCMEvent->acceptActivation = PR_FALSE;
+}
nsWindow::nsWindow()
{
+ mDrawingarea = nsnull;
+ mIsVisible = PR_FALSE;
+ mRetryPointerGrab = PR_FALSE;
+ mRetryKeyboardGrab = PR_FALSE;
+ mActivatePending = PR_FALSE;
+ mWindowType = eWindowType_child;
+ mSizeState = nsSizeMode_Normal;
+ mPluginType = PluginType_NONE;
+ mQCursor = Qt::ArrowCursor;
+
+ if (!gGlobalsInitialized) {
+ gGlobalsInitialized = PR_TRUE;
+
+ // It's OK if either of these fail, but it may not be one day.
+ initialize_prefs();
+ }
+
+ memset(mKeyDownFlags, 0, sizeof(mKeyDownFlags));
+
+ mIsTransparent = PR_FALSE;
+ mTransparencyBitmap = nsnull;
+
+ mTransparencyBitmapWidth = 0;
+ mTransparencyBitmapHeight = 0;
+ mCursor = eCursor_standard;
}
nsWindow::~nsWindow()
{
+ LOG(("nsWindow::~nsWindow() [%p]\n", (void *)this));
+
+ delete[] mTransparencyBitmap;
+ mTransparencyBitmap = nsnull;
+
+ Destroy();
}
-QWidget*
-nsWindow::createQWidget(QWidget *parent, nsWidgetInitData *aInitData)
+void
+nsWindow::Initialize(QWidget *widget)
+{
+ Q_ASSERT(widget);
+
+ mDrawingarea = widget;
+ mDrawingarea->setMouseTracking(PR_TRUE);
+ mDrawingarea->setFocusPolicy(Qt::WheelFocus);
+}
+
+/* static */ void
+nsWindow::ReleaseGlobals()
+{
+}
+
+NS_IMPL_ISUPPORTS_INHERITED1(nsWindow, nsCommonWidget,
+ nsISupportsWeakReference)
+
+NS_IMETHODIMP
+nsWindow::Create(nsIWidget *aParent,
+ const nsRect &aRect,
+ EVENT_CALLBACK aHandleEventFunction,
+ nsIDeviceContext *aContext,
+ nsIAppShell *aAppShell,
+ nsIToolkit *aToolkit,
+ nsWidgetInitData *aInitData)
+{
+ nsresult rv = NativeCreate(aParent, nsnull, aRect, aHandleEventFunction,
+ aContext, aAppShell, aToolkit, aInitData);
+ return rv;
+}
+
+NS_IMETHODIMP
+nsWindow::Create(nsNativeWidget aParent,
+ const nsRect &aRect,
+ EVENT_CALLBACK aHandleEventFunction,
+ nsIDeviceContext *aContext,
+ nsIAppShell *aAppShell,
+ nsIToolkit *aToolkit,
+ nsWidgetInitData *aInitData)
+{
+ nsresult rv = NativeCreate(nsnull, aParent, aRect, aHandleEventFunction,
+ aContext, aAppShell, aToolkit, aInitData);
+ return rv;
+}
+
+NS_IMETHODIMP
+nsWindow::Destroy(void)
+{
+ if (mIsDestroyed || !mCreated)
+ return NS_OK;
+
+ LOG(("nsWindow::Destroy [%p]\n", (void *)this));
+ mIsDestroyed = PR_TRUE;
+ mCreated = PR_FALSE;
+
+ NativeShow(PR_FALSE);
+
+ // walk the list of children and call destroy on them. Have to be
+ // careful, though -- calling destroy on a kid may actually remove
+ // it from our child list, losing its sibling links.
+ for (nsIWidget* kid = mFirstChild; kid; ) {
+ nsIWidget* next = kid->GetNextSibling();
+ kid->Destroy();
+ kid = next;
+ }
+
+ // Destroy thebes surface now. Badness can happen if we destroy
+ // the surface after its X Window.
+ mThebesSurface = nsnull;
+
+ if (mDrawingarea) {
+ delete mDrawingarea;
+ mDrawingarea = nsnull;
+ }
+
+ OnDestroy();
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWindow::SetParent(nsIWidget *aNewParent)
{
- Qt::WFlags flags = Qt::Widget;
- Qt::WA_StaticContents;
+ NS_ENSURE_ARG_POINTER(aNewParent);
+
+ QWidget* newParentWindow =
+ static_cast<QWidget*>(aNewParent->GetNativeData(NS_NATIVE_WINDOW));
+ NS_ASSERTION(newParentWindow, "Parent widget has a null native window handle");
+
+ if (mDrawingarea) {
+ qDebug("FIXME:>>>>>>Func:%s::%d\n", __PRETTY_FUNCTION__, __LINE__);
+ // moz_drawingarea_reparent(mDrawingarea, newParentWindow);
+ } else {
+ NS_NOTREACHED("nsWindow::SetParent - reparenting a non-child window");
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWindow::SetModal(PRBool aModal)
+{
+ LOG(("nsWindow::SetModal [%p] %d, widget[%p]\n", (void *)this, aModal, mDrawingarea));
+
+ MozQWidget *mozWidget = static_cast<MozQWidget*>(mDrawingarea);
+ if (mozWidget)
+ mozWidget->setModal(aModal);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWindow::IsVisible(PRBool & aState)
+{
+ aState = mDrawingarea?mDrawingarea->isVisible():PR_FALSE;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWindow::ConstrainPosition(PRBool aAllowSlop, PRInt32 *aX, PRInt32 *aY)
+{
+ if (mDrawingarea) {
+ PRInt32 screenWidth = QApplication::desktop()->width();
+ PRInt32 screenHeight = QApplication::desktop()->height();
+ if (aAllowSlop) {
+ if (*aX < (kWindowPositionSlop - mBounds.width))
+ *aX = kWindowPositionSlop - mBounds.width;
+ if (*aX > (screenWidth - kWindowPositionSlop))
+ *aX = screenWidth - kWindowPositionSlop;
+ if (*aY < (kWindowPositionSlop - mBounds.height))
+ *aY = kWindowPositionSlop - mBounds.height;
+ if (*aY > (screenHeight - kWindowPositionSlop))
+ *aY = screenHeight - kWindowPositionSlop;
+ } else {
+ if (*aX < 0)
+ *aX = 0;
+ if (*aX > (screenWidth - mBounds.width))
+ *aX = screenWidth - mBounds.width;
+ if (*aY < 0)
+ *aY = 0;
+ if (*aY > (screenHeight - mBounds.height))
+ *aY = screenHeight - mBounds.height;
+ }
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWindow::Move(PRInt32 aX, PRInt32 aY)
+{
+ LOG(("nsWindow::Move [%p] %d %d\n", (void *)this,
+ aX, aY));
+
+ mPlaced = PR_TRUE;
+
+ // Since a popup window's x/y coordinates are in relation to to
+ // the parent, the parent might have moved so we always move a
+ // popup window.
+ //bool popup = mDrawingarea ? mDrawingarea->windowType() == Qt::Popup : false;
+ if (aX == mBounds.x && aY == mBounds.y &&
+ mWindowType != eWindowType_popup)
+ return NS_OK;
+
+ // XXX Should we do some AreBoundsSane check here?
+
+
+ if (!mDrawingarea)
+ return NS_OK;
+
+ QPoint pos(aX, aY);
+ if (mDrawingarea) {
+ if (mParent && mDrawingarea->windowType() == Qt::Popup) {
+ nsRect oldrect, newrect;
+ oldrect.x = aX;
+ oldrect.y = aY;
+
+ mParent->WidgetToScreen(oldrect, newrect);
+
+ pos = QPoint(newrect.x, newrect.y);
#ifdef DEBUG_WIDGETS
- qDebug("NEW WIDGET\n\tparent is %p (%s)", (void*)parent,
- parent ? qPrintable(parent->objectName()) : "null");
+ qDebug("pos is [%d,%d]", pos.x(), pos.y());
#endif
- // ok, create our windows
- switch (mWindowType) {
- case eWindowType_dialog:
- case eWindowType_popup:
- case eWindowType_toplevel:
- case eWindowType_invisible: {
- if (mWindowType == eWindowType_dialog) {
- flags |= Qt::Dialog;
- mContainer = new MozQWidget(this, parent, "topLevelDialog", flags);
- qDebug("\t\t#### dialog (%p)", (void*)mContainer);
- //SetDefaultIcon();
+ } else {
+ qDebug("Widget within another? (%p)", (void*)mDrawingarea);
+ }
+ }
+
+ mBounds.x = pos.x();
+ mBounds.y = pos.y();
+
+ if (!mCreated)
+ return NS_OK;
+
+ if (mIsTopLevel) {
+ mDrawingarea->move(pos);
+ }
+ else if (mDrawingarea) {
+ mDrawingarea->move(pos);
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWindow::PlaceBehind(nsTopLevelWidgetZPlacement aPlacement,
+ nsIWidget *aWidget,
+ PRBool aActivate)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsWindow::SetZIndex(PRInt32 aZIndex)
+{
+ nsIWidget* oldPrev = GetPrevSibling();
+
+ nsBaseWidget::SetZIndex(aZIndex);
+
+ if (GetPrevSibling() == oldPrev) {
+ return NS_OK;
+ }
+
+ NS_ASSERTION(!mDrawingarea, "Expected Mozilla child widget");
+
+ // We skip the nsWindows that don't have mDrawingareas.
+ // These are probably in the process of being destroyed.
+
+ if (!GetNextSibling()) {
+ // We're to be on top.
+ if (mDrawingarea) {
+ qDebug("FIXME:>>>>>>Func:%s::%d\n", __PRETTY_FUNCTION__, __LINE__);
+ // gdk_window_raise(mDrawingarea->clip_window);
+ }
+ } else {
+ // All the siblings before us need to be below our widget.
+ for (nsWindow* w = this; w;
+ w = static_cast<nsWindow*>(w->GetPrevSibling())) {
+ if (w->mDrawingarea) {
+ qDebug("FIXME:>>>>>>Func:%s::%d\n", __PRETTY_FUNCTION__, __LINE__);
+ // gdk_window_lower(w->mDrawingarea->clip_window);
+ }
}
- else if (mWindowType == eWindowType_popup) {
- flags |= Qt::Popup;
- mContainer = new MozQWidget(this, parent, "topLevelPopup", flags);
- qDebug("\t\t#### popup (%p)", (void*)mContainer);
- mContainer->setFocusPolicy(Qt::WheelFocus);
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWindow::SetSizeMode(PRInt32 aMode)
+{
+ nsresult rv;
+
+ LOG(("nsWindow::SetSizeMode [%p] %d\n", (void *)this, aMode));
+
+ // Save the requested state.
+ rv = nsBaseWidget::SetSizeMode(aMode);
+
+ // return if there's no shell or our current state is the same as
+ // the mode we were just set to.
+ if (!mDrawingarea || mSizeState == mSizeMode) {
+ return rv;
+ }
+
+ switch (aMode) {
+ case nsSizeMode_Maximized:
+ mDrawingarea->showMaximized();
+ break;
+ case nsSizeMode_Minimized:
+ mDrawingarea->showMinimized();
+ break;
+ default:
+ // nsSizeMode_Normal, really.
+ mDrawingarea->showNormal ();
+ // KILLME
+ //if (mSizeState == nsSizeMode_Minimized)
+ // gtk_window_deiconify(GTK_WINDOW(mDrawingarea));
+ //else if (mSizeState == nsSizeMode_Maximized)
+ // gtk_window_unmaximize(GTK_WINDOW(mDrawingarea));
+ break;
+ }
+
+ mSizeState = mSizeMode;
+
+ return rv;
+}
+
+NS_IMETHODIMP
+nsWindow::Enable(PRBool aState)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+typedef void (* SetUserTimeFunc)(QWidget* aWindow, quint32 aTimestamp);
+
+// This will become obsolete when new GTK APIs are widely supported,
+// as described here: http://bugzilla.gnome.org/show_bug.cgi?id=347375
+static void
+SetUserTimeAndStartupIDForActivatedWindow(QWidget* aWindow)
+{
+ nsCOMPtr<nsIToolkit> toolkit;
+ NS_GetCurrentToolkit(getter_AddRefs(toolkit));
+ if (!toolkit)
+ return;
+
+ nsToolkit* QTToolkit = static_cast<nsToolkit*>
+ (static_cast<nsIToolkit*>(toolkit));
+ nsCAutoString desktopStartupID;
+ QTToolkit->GetDesktopStartupID(&desktopStartupID);
+ if (desktopStartupID.IsEmpty()) {
+ // We don't have the data we need. Fall back to an
+ // approximation ... using the timestamp of the remote command
+ // being received as a guess for the timestamp of the user event
+ // that triggered it.
+ PRUint32 timestamp = QTToolkit->GetFocusTimestamp();
+ if (timestamp) {
+ aWindow->focusWidget ();
+ // gdk_window_focus(aWindow->window, timestamp);
+ QTToolkit->SetFocusTimestamp(0);
}
- else { // must be eWindowType_toplevel
- flags |= Qt::Window;
- mContainer = new MozQWidget(this, parent, "topLevelWindow", flags);
- qDebug("\t\t#### toplevel (%p)", (void*)mContainer);
- //SetDefaultIcon();
- }
- mWidget = mContainer;
+ return;
}
+
+ QTToolkit->SetDesktopStartupID(EmptyCString());
+}
+
+NS_IMETHODIMP
+nsWindow::SetFocus(PRBool aRaise)
+{
+ // Make sure that our owning widget has focus. If it doesn't try to
+ // grab it. Note that we don't set our focus flag in this case.
+
+ LOGFOCUS((" SetFocus [%p]\n", (void *)this));
+
+ if (!mDrawingarea)
+ return NS_ERROR_FAILURE;
+
+ if (aRaise)
+ mDrawingarea->raise();
+ mDrawingarea->setFocus();
+
+ // If there is already a focused child window, dispatch a LOSTFOCUS
+ // event from that widget and unset its got focus flag.
+
+ LOGFOCUS((" widget now has focus - dispatching events [%p]\n",
+ (void *)this));
+
+ DispatchGotFocusEvent();
+
+ LOGFOCUS((" done dispatching events in SetFocus() [%p]\n",
+ (void *)this));
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWindow::GetScreenBounds(nsRect &aRect)
+{
+ nsRect origin(0, 0, mBounds.width, mBounds.height);
+ WidgetToScreen(origin, aRect);
+ LOG(("GetScreenBounds %d %d | %d %d | %d %d\n",
+ aRect.x, aRect.y,
+ mBounds.width, mBounds.height,
+ aRect.width, aRect.height));
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWindow::SetForegroundColor(const nscolor &aColor)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsWindow::SetBackgroundColor(const nscolor &aColor)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsWindow::SetCursor(nsCursor aCursor)
+{
+ mCursor = aCursor;
+ switch(mCursor) {
+ case eCursor_standard:
+ mQCursor = Qt::ArrowCursor;
break;
- case eWindowType_child: {
- mWidget = new MozQWidget(this, parent, "paintArea", 0);
- qDebug("\t\t#### child (%p)", (void*)mWidget);
- }
+ case eCursor_wait:
+ mQCursor = Qt::WaitCursor;
+ break;
+ case eCursor_select:
+ mQCursor = Qt::IBeamCursor;
+ break;
+ case eCursor_hyperlink:
+ mQCursor = Qt::PointingHandCursor;
+ break;
+ case eCursor_ew_resize:
+ mQCursor = Qt::SplitHCursor;
+ break;
+ case eCursor_ns_resize:
+ mQCursor = Qt::SplitVCursor;
+ break;
+ case eCursor_nw_resize:
+ case eCursor_se_resize:
+ mQCursor = Qt::SizeBDiagCursor;
break;
+ case eCursor_ne_resize:
+ case eCursor_sw_resize:
+ mQCursor = Qt::SizeFDiagCursor;
+ break;
+ case eCursor_crosshair:
+ case eCursor_move:
+ mQCursor = Qt::SizeAllCursor;
+ break;
+ case eCursor_help:
+ mQCursor = Qt::WhatsThisCursor;
+ break;
+ case eCursor_copy:
+ case eCursor_alias:
+ break;
+ case eCursor_context_menu:
+ case eCursor_cell:
+ case eCursor_grab:
+ case eCursor_grabbing:
+ case eCursor_spinning:
+ case eCursor_zoom_in:
+ case eCursor_zoom_out:
+
default:
break;
}
-
- mWidget->setAttribute(Qt::WA_StaticContents);
- mWidget->setAttribute(Qt::WA_OpaquePaintEvent); // Transparent Widget Background
-
- //mWidget->setBackgroundMode(Qt::NoBackground);
- //setAutoFillBackground(false)
-
- return mWidget;
+ return NS_OK;
+ // FIXME after reimplementation of whole nsWindow SetCursor cause lot of errors
+ if (mDrawingarea)
+ mDrawingarea->setCursor(mQCursor);
+
+ return NS_OK;
+}
+
+
+static
+PRUint8* Data32BitTo1Bit(PRUint8* aImageData,
+ PRUint32 aImageBytesPerRow,
+ PRUint32 aWidth, PRUint32 aHeight)
+{
+ PRUint32 outBpr = (aWidth + 7) / 8;
+
+ PRUint8* outData = new PRUint8[outBpr * aHeight];
+ if (!outData)
+ return NULL;
+
+ PRUint8 *outRow = outData,
+ *imageRow = aImageData;
+
+ for (PRUint32 curRow = 0; curRow < aHeight; curRow++) {
+ PRUint8 *irow = imageRow;
+ PRUint8 *orow = outRow;
+ PRUint8 imagePixels = 0;
+ PRUint8 offset = 0;
+
+ for (PRUint32 curCol = 0; curCol < aWidth; curCol++) {
+ PRUint8 r = *imageRow++,
+ g = *imageRow++,
+ b = *imageRow++;
+ /* a = * */imageRow++;
+
+ if ((r + b + g) < 3 * 128)
+ imagePixels |= (1 << offset);
+
+ if (offset == 7) {
+ *outRow++ = imagePixels;
+ offset = 0;
+ imagePixels = 0;
+ } else {
+ offset++;
+ }
+ }
+ if (offset != 0)
+ *outRow++ = imagePixels;
+
+ imageRow = irow + aImageBytesPerRow;
+ outRow = orow + outBpr;
+ }
+
+ return outData;
+}
+
+
+
+NS_IMETHODIMP
+nsWindow::SetCursor(imgIContainer* aCursor,
+ PRUint32 aHotspotX, PRUint32 aHotspotY)
+{
+ nsresult rv = NS_ERROR_OUT_OF_MEMORY;
+ qDebug("FIXME:>>>>>>Func:%s::%d\n", __PRETTY_FUNCTION__, __LINE__);
+ return rv;
+}
+
+
+NS_IMETHODIMP
+nsWindow::Validate()
+{
+ // Get the update for this window and, well, just drop it on the
+ // floor.
+ if (!mDrawingarea)
+ return NS_OK;
+
+ qDebug("FIXME:>>>>>>Func:%s::%d\n", __PRETTY_FUNCTION__, __LINE__);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWindow::Invalidate(PRBool aIsSynchronous)
+{
+ LOGDRAW(("Invalidate (all) [%p]: \n", (void *)this));
+
+ if (!mDrawingarea)
+ return NS_OK;
+
+ if (aIsSynchronous)
+ mDrawingarea->repaint();
+ else
+ mDrawingarea->update();
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWindow::Invalidate(const nsRect &aRect,
+ PRBool aIsSynchronous)
+{
+ LOGDRAW(("Invalidate (rect) [%p]: %d %d %d %d (sync: %d)\n", (void *)this,
+ aRect.x, aRect.y, aRect.width, aRect.height, aIsSynchronous));
+
+ if (!mDrawingarea)
+ return NS_OK;
+
+ if (aIsSynchronous)
+ mDrawingarea->repaint(aRect.x, aRect.y, aRect.width, aRect.height);
+ else
+ mDrawingarea->update(aRect.x, aRect.y, aRect.width, aRect.height);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWindow::InvalidateRegion(const nsIRegion* aRegion,
+ PRBool aIsSynchronous)
+{
+
+ QRegion *region = nsnull;
+ aRegion->GetNativeRegion((void *&)region);
+
+ if (region && mDrawingarea) {
+ QRect rect = region->boundingRect();
+
+// LOGDRAW(("Invalidate (region) [%p]: %d %d %d %d (sync: %d)\n",
+// (void *)this,
+// rect.x, rect.y, rect.width, rect.height, aIsSynchronous));
+
+ if (aIsSynchronous)
+ mDrawingarea->repaint(*region);
+ else
+ mDrawingarea->update(*region);
+ }
+ else {
+ qDebug("FIXME:>>>>>>Func:%s::%d\n", __PRETTY_FUNCTION__, __LINE__);
+ LOGDRAW(("Invalidate (region) [%p] with empty region\n",
+ (void *)this));
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWindow::Update()
+{
+ if (!mDrawingarea)
+ return NS_OK;
+
+ mDrawingarea->update();
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWindow::SetColorMap(nsColorMap *aColorMap)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsWindow::Scroll(PRInt32 aDx,
+ PRInt32 aDy,
+ nsRect *aClipRect)
+{
+ if (!mDrawingarea)
+ return NS_OK;
+
+ mDrawingarea->scroll(aDx, aDy);
+
+ // Update bounds on our child windows
+ for (nsIWidget* kid = mFirstChild; kid; kid = kid->GetNextSibling()) {
+ nsRect bounds;
+ kid->GetBounds(bounds);
+ bounds.x += aDx;
+ bounds.y += aDy;
+ static_cast<nsBaseWidget*>(kid)->SetBounds(bounds);
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWindow::ScrollWidgets(PRInt32 aDx,
+ PRInt32 aDy)
+{
+ if (!mDrawingarea)
+ return NS_OK;
+
+ mDrawingarea->scroll(aDx, aDy);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWindow::ScrollRect(nsRect &aSrcRect,
+ PRInt32 aDx,
+ PRInt32 aDy)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+void*
+nsWindow::GetNativeData(PRUint32 aDataType)
+{
+ switch (aDataType) {
+ case NS_NATIVE_WINDOW:
+ case NS_NATIVE_WIDGET: {
+ if (!mDrawingarea)
+ return nsnull;
+
+ return mDrawingarea;
+ break;
+ }
+
+ case NS_NATIVE_PLUGIN_PORT:
+ return SetupPluginPort();
+ break;
+
+ case NS_NATIVE_DISPLAY:
+ return mDrawingarea->x11Info().display();
+ break;
+
+ case NS_NATIVE_GRAPHIC: {
+ NS_ASSERTION(nsnull != mToolkit, "NULL toolkit, unable to get a GC");
+ return (void *)static_cast<nsToolkit *>(mToolkit)->GetSharedGC();
+ break;
+ }
+
+ case NS_NATIVE_SHELLWIDGET:
+ return (void *) mDrawingarea;
+
+ default:
+ NS_WARNING("nsWindow::GetNativeData called with bad value");
+ return nsnull;
+ }
+}
+
+NS_IMETHODIMP
+nsWindow::SetBorderStyle(nsBorderStyle aBorderStyle)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsWindow::SetTitle(const nsAString& aTitle)
+{
+ if (!mDrawingarea)
+ return NS_OK;
+
+ nsAString::const_iterator it;
+ QString qStr((QChar*)aTitle.BeginReading(it).get(), -1);
+
+ if (mDrawingarea)
+ mDrawingarea->setWindowTitle(qStr);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWindow::SetIcon(const nsAString& aIconSpec)
+{
+ if (!mDrawingarea)
+ return NS_OK;
+
+ nsCOMPtr<nsILocalFile> iconFile;
+ nsCAutoString path;
+ nsCStringArray iconList;
+
+ // Look for icons with the following suffixes appended to the base name.
+ // The last two entries (for the old XPM format) will be ignored unless
+ // no icons are found using the other suffixes. XPM icons are depricated.
+
+ const char extensions[6][7] = { ".png", "16.png", "32.png", "48.png",
+ ".xpm", "16.xpm" };
+
+ for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(extensions); i++) {
+ // Don't bother looking for XPM versions if we found a PNG.
+ if (i == NS_ARRAY_LENGTH(extensions) - 2 && iconList.Count())
+ break;
+
+ nsAutoString extension;
+ extension.AppendASCII(extensions[i]);
+
+ ResolveIconName(aIconSpec, extension, getter_AddRefs(iconFile));
+ if (iconFile) {
+ iconFile->GetNativePath(path);
+ iconList.AppendCString(path);
+ }
+ }
+
+ // leave the default icon intact if no matching icons were found
+ if (iconList.Count() == 0)
+ return NS_OK;
+
+ return SetWindowIconList(iconList);
+}
+
+NS_IMETHODIMP
+nsWindow::SetMenuBar(nsIMenuBar * aMenuBar)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsWindow::ShowMenuBar(PRBool aShow)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsWindow::WidgetToScreen(const nsRect& aOldRect, nsRect& aNewRect)
+{
+ NS_ENSURE_TRUE(mDrawingarea, NS_OK);
+
+ PRInt32 X,Y;
+
+ QPoint offset(0,0);
+ offset = mDrawingarea->mapFromGlobal(offset);
+ X = offset.x();
+ Y = offset.y();
+ LOG(("WidgetToScreen (container) %d %d\n", X, Y));
+
+ aNewRect.x = aOldRect.x + X;
+ aNewRect.y = aOldRect.y + Y;
+ aNewRect.width = aOldRect.width;
+ aNewRect.height = aOldRect.height;
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWindow::ScreenToWidget(const nsRect& aOldRect, nsRect& aNewRect)
+{
+ NS_ENSURE_TRUE(mDrawingarea, NS_OK);
+
+ PRInt32 X,Y;
+
+ QPoint offset(0,0);
+ offset = mDrawingarea->mapFromGlobal(offset);
+ X = offset.x();
+ Y = offset.y();
+ LOG(("WidgetToScreen (container) %d %d\n", X, Y));
+
+ aNewRect.x = aOldRect.x - X;
+ aNewRect.y = aOldRect.y - Y;
+ aNewRect.width = aOldRect.width;
+ aNewRect.height = aOldRect.height;
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWindow::BeginResizingChildren(void)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsWindow::EndResizingChildren(void)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsWindow::EnableDragDrop(PRBool aEnable)
+{
+ return NS_OK;
+}
+
+void
+nsWindow::ConvertToDeviceCoordinates(nscoord &aX,
+ nscoord &aY)
+{
}
NS_IMETHODIMP
nsWindow::PreCreateWidget(nsWidgetInitData *aWidgetInitData)
{
if (nsnull != aWidgetInitData) {
mWindowType = aWidgetInitData->mWindowType;
mBorderStyle = aWidgetInitData->mBorderStyle;
return NS_OK;
}
return NS_ERROR_FAILURE;
}
+NS_IMETHODIMP
+nsWindow::CaptureMouse(PRBool aCapture)
+{
+ LOG(("CaptureMouse %p\n", (void *)this));
+
+ if (!mDrawingarea)
+ return NS_OK;
+
+/*
+ if (aCapture) {
+ GrabPointer();
+ }
+ else {
+ ReleaseGrabs();
+ }
+*/
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWindow::CaptureRollupEvents(nsIRollupListener *aListener,
+ PRBool aDoCapture,
+ PRBool aConsumeRollupEvent)
+{
+ if (!mDrawingarea)
+ return NS_OK;
+
+ LOG(("CaptureRollupEvents %p\n", (void *)this));
+/*
+ if (aDoCapture) {
+ GrabPointer();
+ GrabKeyboard();
+ }
+ else {
+ ReleaseGrabs();
+ }
+*/
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWindow::GetAttention(PRInt32 aCycleCount)
+{
+ LOG(("nsWindow::GetAttention [%p]\n", (void *)this));
+
+ SetUrgencyHint(mDrawingarea, PR_TRUE);
+
+ return NS_OK;
+}
+
+void
+nsWindow::LoseFocus(void)
+{
+ // make sure that we reset our key down counter so the next keypress
+ // for this widget will get the down event
+ memset(mKeyDownFlags, 0, sizeof(mKeyDownFlags));
+
+ // Dispatch a lostfocus event
+ DispatchLostFocusEvent();
+
+ LOGFOCUS((" widget lost focus [%p]\n", (void *)this));
+}
+
+bool
+nsWindow::OnExposeEvent(QPaintEvent *aEvent)
+{
+ if (mIsDestroyed) {
+ LOG(("Expose event on destroyed window [%p] window %p\n",
+ (void *)this, mDrawingarea));
+ return FALSE;
+ }
+
+ if (!mDrawingarea)
+ return FALSE;
+
+ static NS_DEFINE_CID(kRegionCID, NS_REGION_CID);
+
+ nsCOMPtr<nsIRegion> updateRegion = do_CreateInstance(kRegionCID);
+ if (!updateRegion)
+ return FALSE;
+
+ updateRegion->Init();
+
+ QVector<QRect> rects = aEvent->region().rects();
+
+ LOGDRAW(("sending expose event [%p] %p 0x%lx (rects follow):\n",
+ (void *)this, (void *)aEvent, 0));
+
+ for (int i = 0; i < rects.size(); ++i) {
+ QRect r = rects.at(i);
+ updateRegion->Union(r.x(), r.y(), r.width(), r.height());
+ LOGDRAW(("\t%d %d %d %d\n", r.x(), r.y(), r.width(), r.height()));
+ }
+
+ nsCOMPtr<nsIRenderingContext> rc = getter_AddRefs(GetRenderingContext());
+ if (NS_UNLIKELY(!rc)) {
+ return FALSE;
+ }
+
+ PRBool translucent;
+ GetHasTransparentBackground(translucent);
+ nsIntRect boundsRect;
+ QPixmap* bufferPixmap = nsnull;
+ nsRefPtr<gfxXlibSurface> bufferPixmapSurface;
+
+ updateRegion->GetBoundingBox(&boundsRect.x, &boundsRect.y,
+ &boundsRect.width, &boundsRect.height);
+
+ // do double-buffering and clipping here
+ nsRefPtr<gfxContext> ctx = rc->ThebesContext();
+ ctx->Save();
+ ctx->NewPath();
+ if (translucent) {
+ // Collapse update area to the bounding box. This is so we only have to
+ // call UpdateTranslucentWindowAlpha once. After we have dropped
+ // support for non-Thebes graphics, UpdateTranslucentWindowAlpha will be
+ // our private interface so we can rework things to avoid this.
+ ctx->Rectangle(gfxRect(boundsRect.x, boundsRect.y,
+ boundsRect.width, boundsRect.height));
+ } else {
+ for (int i = 0; i < rects.size(); ++i) {
+ QRect r = rects.at(i);
+ ctx->Rectangle(gfxRect(r.x(), r.y(), r.width(), r.height()));
+ }
+ }
+ ctx->Clip();
+
+ // double buffer
+ if (translucent) {
+ ctx->PushGroup(gfxASurface::CONTENT_COLOR_ALPHA);
+ } else {
+#ifdef MOZ_ENABLE_GLITZ
+ ctx->PushGroup(gfxASurface::CONTENT_COLOR);
+#else // MOZ_ENABLE_GLITZ
+ // Instead of just doing PushGroup we're going to do a little dance
+ // to ensure that GDK creates the pixmap, so it doesn't go all
+ // XGetGeometry on us in gdk_pixmap_foreign_new_for_display when we
+ // paint native themes
+ // GdkDrawable* d = Qt::Key_DRAWABLE(mDrawingarea->inner_window);
+ // qint32 depth = gdk_drawable_get_depth(d);
+ // bufferPixmap = new QPixmap(d, boundsRect.width, boundsRect.height);
+
+ if (bufferPixmap) {
+#if 0
+ GdkVisual* visual = gdk_drawable_get_visual(Qt::Key_DRAWABLE(bufferPixmap));
+ Visual* XVisual = gdk_x11_visual_get_xvisual(visual);
+ Display* display = gdk_x11_drawable_get_xdisplay(Qt::Key_DRAWABLE(bufferPixmap));
+ Drawable drawable = gdk_x11_drawable_get_xid(Qt::Key_DRAWABLE(bufferPixmap));
+ bufferPixmapSurface =
+ new gfxXlibSurface(display, drawable, XVisual,
+ gfxIntSize(boundsRect.width, boundsRect.height));
+ if (bufferPixmapSurface) {
+ bufferPixmapSurface->SetDeviceOffset(gfxPoint(-boundsRect.x, -boundsRect.y));
+ nsCOMPtr<nsIRenderingContext> newRC;
+ nsresult rv = GetDeviceContext()->
+ CreateRenderingContextInstance(*getter_AddRefs(newRC));
+ if (NS_FAILED(rv)) {
+ bufferPixmapSurface = nsnull;
+ } else {
+ rv = newRC->Init(GetDeviceContext(), bufferPixmapSurface);
+ if (NS_FAILED(rv)) {
+ bufferPixmapSurface = nsnull;
+ } else {
+ rc = newRC;
+ }
+ }
+ }
+#endif
+ }
+#endif // MOZ_ENABLE_GLITZ
+ }
+
+#if 0
+ // NOTE: Paint flashing region would be wrong for cairo, since
+ // cairo inflates the update region, etc. So don't paint flash
+ // for cairo.
+#ifdef DEBUG
+ if (WANT_PAINT_FLASHING && aEvent->window)
+ gdk_window_flash(aEvent->window, 1, 100, aEvent->region);
+#endif
+#endif
+
+ nsPaintEvent event(PR_TRUE, NS_PAINT, this);
+ QRect r = aEvent->rect();
+ if (!r.isValid())
+ r = mDrawingarea->rect();
+ nsRect rect(r.x(), r.y(), r.width(), r.height());
+ event.refPoint.x = aEvent->rect().x();
+ event.refPoint.y = aEvent->rect().y();
+ event.rect = ▭ // was null FIXME
+ event.region = updateRegion;
+ event.renderingContext = rc;
+
+ nsEventStatus status;
+ DispatchEvent(&event, status);
+
+ // DispatchEvent can Destroy us (bug 378273), avoid doing any paint
+ // operations below if that happened - it will lead to XError and exit().
+ if (NS_LIKELY(!mIsDestroyed)) {
+ if (status != nsEventStatus_eIgnore) {
+ if (translucent) {
+ nsRefPtr<gfxPattern> pattern = ctx->PopGroup();
+ ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
+ ctx->SetPattern(pattern);
+ ctx->Paint();
+
+ nsRefPtr<gfxImageSurface> img =
+ new gfxImageSurface(gfxIntSize(boundsRect.width, boundsRect.height),
+ gfxImageSurface::ImageFormatA8);
+ if (img && !img->CairoStatus()) {
+ img->SetDeviceOffset(gfxPoint(-boundsRect.x, -boundsRect.y));
+
+ nsRefPtr<gfxContext> imgCtx = new gfxContext(img);
+ if (imgCtx) {
+ imgCtx->SetPattern(pattern);
+ imgCtx->SetOperator(gfxContext::OPERATOR_SOURCE);
+ imgCtx->Paint();
+ }
+
+ UpdateTranslucentWindowAlphaInternal(nsRect(boundsRect.x, boundsRect.y,
+ boundsRect.width, boundsRect.height),
+ img->Data(), img->Stride());
+ }
+ } else {
+#ifdef MOZ_ENABLE_GLITZ
+ ctx->PopGroupToSource();
+ ctx->Paint();
+#else // MOZ_ENABLE_GLITZ
+ if (bufferPixmapSurface) {
+ ctx->SetSource(bufferPixmapSurface);
+ ctx->Paint();
+ }
+#endif // MOZ_ENABLE_GLITZ
+ }
+ } else {
+ // ignore
+ if (translucent) {
+ ctx->PopGroup();
+ } else {
+#ifdef MOZ_ENABLE_GLITZ
+ ctx->PopGroup();
+#endif // MOZ_ENABLE_GLITZ
+ }
+ }
+
+ if (bufferPixmap) {
+ delete bufferPixmap;
+ }
+
+ ctx->Restore();
+ }
+
+ // check the return value!
+ return ignoreEvent(status);
+}
+
+bool
+nsWindow::OnConfigureEvent(QMoveEvent *aEvent)
+{
+ LOG(("configure event [%p] %d %d\n", (void *)this,
+ aEvent->pos().x(), aEvent->pos().y()));
+
+ // can we shortcut?
+ if (!mDrawingarea
+ || (mBounds.x == aEvent->pos().x()
+ && mBounds.y == aEvent->pos().y()))
+ return FALSE;
+
+ // Toplevel windows need to have their bounds set so that we can
+ // keep track of our location. It's not often that the x,y is set
+ // by the layout engine. Width and height are set elsewhere.
+ QPoint pos = aEvent->pos();
+ if (mIsTopLevel) {
+ mPlaced = PR_TRUE;
+ // Need to translate this into the right coordinates
+ nsRect oldrect, newrect;
+ WidgetToScreen(oldrect, newrect);
+ mBounds.x = newrect.x;
+ mBounds.y = newrect.y;
+ }
+
+ nsGUIEvent event(PR_TRUE, NS_MOVE, this);
+
+ event.refPoint.x = pos.x();
+ event.refPoint.y = pos.y();
+
+ // XXX mozilla will invalidate the entire window after this move
+ // complete. wtf?
+ nsEventStatus status;
+ DispatchEvent(&event, status);
+
+ return ignoreEvent(status);
+}
+
+bool
+nsWindow::OnSizeAllocate(QResizeEvent *e)
+{
+ nsRect rect;
+
+ // Generate XPFE resize event
+ GetBounds(rect);
+
+ rect.width = e->size().width();
+ rect.height = e->size().height();
+
+ LOG(("size_allocate [%p] %d %d\n",
+ (void *)this, rect.width, rect.height));
+
+ ResizeTransparencyBitmap(rect.width, rect.height);
+
+ mBounds.width = rect.width;
+ mBounds.height = rect.height;
+
+#ifdef DEBUG_WIDGETS
+ qDebug("resizeEvent: mDrawingarea=%p, aWidth=%d, aHeight=%d, aX = %d, aY = %d", (void*)mDrawingarea,
+ rect.width, rect.height, rect.x, rect.y);
+#endif
+
+ if (mTransparencyBitmap) {
+ ApplyTransparencyBitmap();
+ }
+
+ if (mDrawingarea)
+ mDrawingarea->resize(rect.width, rect.height);
+
+ nsEventStatus status;
+ DispatchResizeEvent(rect, status);
+ return ignoreEvent(status);
+}
+
+bool
+nsWindow::OnDeleteEvent(QCloseEvent *aEvent)
+{
+ nsGUIEvent event(PR_TRUE, NS_XUL_CLOSE, this);
+
+ event.refPoint.x = 0;
+ event.refPoint.y = 0;
+
+ nsEventStatus status;
+ DispatchEvent(&event, status);
+ return ignoreEvent(status);
+}
+
+bool
+nsWindow::OnEnterNotifyEvent(QEvent *aEvent)
+{
+ nsMouseEvent event(PR_TRUE, NS_MOUSE_ENTER, this, nsMouseEvent::eReal);
+
+ QPoint pt = QCursor::pos();
+
+ event.refPoint.x = nscoord(pt.x());
+ event.refPoint.y = nscoord(pt.y());
+
+ LOG(("OnEnterNotify: %p\n", (void *)this));
+
+ nsEventStatus status;
+ DispatchEvent(&event, status);
+ return FALSE;
+}
+
+bool
+nsWindow::OnLeaveNotifyEvent(QEvent *aEvent)
+{
+ nsMouseEvent event(PR_TRUE, NS_MOUSE_EXIT, this, nsMouseEvent::eReal);
+
+ QPoint pt = QCursor::pos();
+
+ event.refPoint.x = nscoord(pt.x());
+ event.refPoint.y = nscoord(pt.y());
+
+ LOG(("OnLeaveNotify: %p\n", (void *)this));
+
+ nsEventStatus status;
+ DispatchEvent(&event, status);
+ return FALSE;
+}
+
+bool
+nsWindow::OnMotionNotifyEvent(QMouseEvent *aEvent)
+{
+ // when we receive this, it must be that the gtk dragging is over,
+ // it is dropped either in or out of mozilla, clear the flag
+ //mDrawingarea->setCursor(mQCursor);
+
+ nsMouseEvent event(PR_TRUE, NS_MOUSE_MOVE, this, nsMouseEvent::eReal);
+
+
+ event.refPoint.x = nscoord(aEvent->x());
+ event.refPoint.y = nscoord(aEvent->y());
+
+ event.isShift = aEvent->modifiers() & Qt::ShiftModifier;
+ event.isControl = aEvent->modifiers() & Qt::ControlModifier;
+ event.isAlt = aEvent->modifiers() & Qt::AltModifier;
+ event.isMeta = aEvent->modifiers() & Qt::MetaModifier;
+ event.clickCount = 0;
+
+ nsEventStatus status;
+ DispatchEvent(&event, status);
+ return ignoreEvent(status);
+}
+
+void
+nsWindow::InitButtonEvent(nsMouseEvent &event,
+ QMouseEvent *aEvent, int aClickCount)
+{
+ event.refPoint.x = nscoord(aEvent->x());
+ event.refPoint.y = nscoord(aEvent->y());
+
+ event.isShift = aEvent->modifiers() & Qt::ShiftModifier;
+ event.isControl = aEvent->modifiers() & Qt::ControlModifier;
+ event.isAlt = aEvent->modifiers() & Qt::AltModifier;
+ event.isMeta = aEvent->modifiers() & Qt::MetaModifier;
+ event.clickCount = aClickCount;
+}
+
+bool
+nsWindow::OnButtonPressEvent(QMouseEvent *aEvent)
+{
+ mDrawingarea->setCursor(mQCursor);
+ PRUint16 domButton;
+ switch (aEvent->button()) {
+ case Qt::MidButton:
+ domButton = nsMouseEvent::eMiddleButton;
+ break;
+ case Qt::RightButton:
+ domButton = nsMouseEvent::eRightButton;
+ break;
+ default:
+ domButton = nsMouseEvent::eLeftButton;
+ break;
+ }
+
+ nsMouseEvent event(PR_TRUE, NS_MOUSE_BUTTON_DOWN, this, nsMouseEvent::eReal);
+ event.button = domButton;
+ InitButtonEvent(event, aEvent, 1);
+
+ nsEventStatus status;
+ DispatchEvent(&event, status);
+
+ // right menu click on linux should also pop up a context menu
+ if (domButton == nsMouseEvent::eRightButton &&
+ NS_LIKELY(!mIsDestroyed)) {
+ nsMouseEvent contextMenuEvent(PR_TRUE, NS_CONTEXTMENU, this,
+ nsMouseEvent::eReal);
+ InitButtonEvent(contextMenuEvent, aEvent);
+ DispatchEvent(&contextMenuEvent, status);
+ }
+
+ return ignoreEvent(status);
+}
+
+bool
+nsWindow::OnButtonReleaseEvent(QMouseEvent *aEvent)
+{
+ PRUint16 domButton;
+// mLastButtonReleaseTime = aEvent->time;
+
+ switch (aEvent->button()) {
+ case Qt::MidButton:
+ domButton = nsMouseEvent::eMiddleButton;
+ break;
+ case Qt::RightButton:
+ domButton = nsMouseEvent::eRightButton;
+ break;
+ default:
+ domButton = nsMouseEvent::eLeftButton;
+ break;
+ }
+
+ nsMouseEvent event(PR_TRUE, NS_MOUSE_BUTTON_UP, this, nsMouseEvent::eReal);
+ event.button = domButton;
+ InitButtonEvent(event, aEvent);
+
+ nsEventStatus status;
+ DispatchEvent(&event, status);
+ return ignoreEvent(status);
+}
+
+bool
+nsWindow::mouseDoubleClickEvent(QMouseEvent *e)
+{
+ PRUint32 eventType;
+
+ switch (e->button()) {
+ case Qt::MidButton:
+ eventType = nsMouseEvent::eMiddleButton;
+ break;
+ case Qt::RightButton:
+ eventType = nsMouseEvent::eRightButton;
+ break;
+ default:
+ eventType = nsMouseEvent::eLeftButton;
+ break;
+ }
+
+ nsMouseEvent event(PR_TRUE, NS_MOUSE_DOUBLECLICK, this, nsMouseEvent::eReal);
+ event.button = eventType;
+
+ InitButtonEvent(event, e, 2);
+ //pressed
+ nsEventStatus status;
+ DispatchEvent(&event, status);
+ return ignoreEvent(status);
+}
+
+bool
+nsWindow::OnContainerFocusInEvent(QFocusEvent *aEvent)
+{
+ LOGFOCUS(("OnContainerFocusInEvent [%p]\n", (void *)this));
+ // Return if someone has blocked events for this widget. This will
+ // happen if someone has called gtk_widget_grab_focus() from
+ // nsWindow::SetFocus() and will prevent recursion.
+
+ if (mIsTopLevel)
+ mActivatePending = PR_TRUE;
+
+ // Unset the urgency hint, if possible
+// SetUrgencyHint(top_window, PR_FALSE);
+
+ // dispatch a got focus event
+ DispatchGotFocusEvent();
+
+ // send the activate event if it wasn't already sent via any
+ // SetFocus() calls that were the result of the GOTFOCUS event
+ // above.
+ if (mActivatePending) {
+ mActivatePending = PR_FALSE;
+ DispatchActivateEvent();
+ }
+
+ LOGFOCUS(("Events sent from focus in event [%p]\n", (void *)this));
+ return FALSE;
+}
+
+bool
+nsWindow::OnContainerFocusOutEvent(QFocusEvent *aEvent)
+{
+ LOGFOCUS(("OnContainerFocusOutEvent [%p]\n", (void *)this));
+
+ DispatchLostFocusEvent();
+ if (mDrawingarea)
+ DispatchDeactivateEvent();
+
+ mActivatePending = PR_FALSE;
+
+ LOGFOCUS(("Done with container focus out [%p]\n", (void *)this));
+ return FALSE;
+}
+
+inline PRBool
+is_latin_shortcut_key(quint32 aKeyval)
+{
+ return ((Qt::Key_0 <= aKeyval && aKeyval <= Qt::Key_9) ||
+ (Qt::Key_A <= aKeyval && aKeyval <= Qt::Key_Z));
+}
+
+PRBool
+nsWindow::DispatchCommandEvent(nsIAtom* aCommand)
+{
+ nsEventStatus status;
+ nsCommandEvent event(PR_TRUE, nsWidgetAtoms::onAppCommand, aCommand, this);
+ DispatchEvent(&event, status);
+ return TRUE;
+}
+
+bool
+nsWindow::OnKeyPressEvent(QKeyEvent *aEvent)
+{
+ LOGFOCUS(("OnKeyPressEvent [%p]\n", (void *)this));
+
+#ifdef USE_XIM
+ // if we are in the middle of composing text, XIM gets to see it
+ // before mozilla does.
+ LOGIM(("key press [%p]: composing %d val %d\n",
+ (void *)this, IMEComposingWindow() != nsnull, aEvent->key()));
+ if (IMEFilterEvent(aEvent))
+ return TRUE;
+ LOGIM(("sending as regular key press event\n"));
+#endif
+
+ nsEventStatus status;
+
+ nsCOMPtr<nsIWidget> kungFuDeathGrip = this;
+
+ // If the key down flag isn't set then set it so we don't send
+ // another key down event on the next key press -- DOM events are
+ // key down, key press and key up. X only has key press and key
+ // release. gtk2 already filters the extra key release events for
+ // us.
+
+ PRBool isKeyDownCancelled = PR_FALSE;
+ PRUint32 domVirtualKeyCode = QtKeyCodeToDOMKeyCode(aEvent->key());
+
+ if (!IsKeyDown(domVirtualKeyCode)) {
+ SetKeyDownFlag(domVirtualKeyCode);
+
+ // send the key down event
+ nsKeyEvent downEvent(PR_TRUE, NS_KEY_DOWN, this);
+ InitKeyEvent(downEvent, aEvent);
+ DispatchEvent(&downEvent, status);
+ if (NS_UNLIKELY(mIsDestroyed))
+ return PR_TRUE;
+ isKeyDownCancelled = (status == nsEventStatus_eConsumeNoDefault);
+ }
+
+ // Don't pass modifiers as NS_KEY_PRESS events.
+ // TODO: Instead of selectively excluding some keys from NS_KEY_PRESS events,
+ // we should instead selectively include (as per MSDN spec; no official
+ // spec covers KeyPress events).
+ /*
+ if (aEvent->key() == Qt::Key_Shift_L
+ || aEvent->key() == Qt::Key_Shift_R
+ || aEvent->key() == Qt::Key_Control_L
+ || aEvent->key() == Qt::Key_Control_R
+ || aEvent->key() == Qt::Key_Alt_L
+ || aEvent->key() == Qt::Key_Alt_R
+ || aEvent->key() == Qt::Key_Meta_L
+ || aEvent->key() == Qt::Key_Meta_R) {
+ return TRUE;
+ }
+ */
+
+ // Look for specialized app-command keys
+ switch (aEvent->key()) {
+ case XF86XK_Back:
+ return DispatchCommandEvent(nsWidgetAtoms::Back);
+ case XF86XK_Forward:
+ return DispatchCommandEvent(nsWidgetAtoms::Forward);
+ case XF86XK_Refresh:
+ return DispatchCommandEvent(nsWidgetAtoms::Reload);
+ case XF86XK_Stop:
+ return DispatchCommandEvent(nsWidgetAtoms::Stop);
+ case XF86XK_Search:
+ return DispatchCommandEvent(nsWidgetAtoms::Search);
+ case XF86XK_Favorites:
+ return DispatchCommandEvent(nsWidgetAtoms::Bookmarks);
+ case XF86XK_HomePage:
+ return DispatchCommandEvent(nsWidgetAtoms::Home);
+ }
+
+ nsKeyEvent event(PR_TRUE, NS_KEY_PRESS, this);
+ InitKeyEvent(event, aEvent);
+ if (isKeyDownCancelled) {
+ // If prevent default set for onkeydown, do the same for onkeypress
+ event.flags |= NS_EVENT_FLAG_NO_DEFAULT;
+ }
+ event.charCode = nsConvertCharCodeToUnicode(aEvent);
+ if (event.charCode) {
+ event.keyCode = 0;
+ // if the control, meta, or alt key is down, then we should leave
+ // the isShift flag alone (probably not a printable character)
+ // if none of the other modifier keys are pressed then we need to
+ // clear isShift so the character can be inserted in the editor
+
+ if (event.isControl || event.isAlt || event.isMeta) {
+ QKeyEvent tmpEvent = *aEvent;
+
+ // Fix for bug 69230:
+ // if modifier key is pressed and key pressed is not latin character,
+ // we should try other keyboard layouts to find out correct latin
+ // character corresponding to pressed key;
+ // that way shortcuts like Ctrl+C will work no matter what
+ // keyboard layout is selected
+ // We don't try to fix up punctuation accelerators here,
+ // because their location differs between latin layouts
+ /*
+ if (!is_latin_shortcut_key(event.charCode)) {
+ // We have a non-latin char, try other keyboard groups
+ GdkKeymapKey *keys;
+ quint32 *keyvals;
+ qint32 n_entries;
+ PRUint32 latinCharCode;
+ qint32 level;
+
+ if (gdk_keymap_translate_keyboard_state(NULL,
+ tmpEvent.hardware_keycode,
+ (GdkModifierType)tmpEvent.state,
+ tmpEvent.group,
+ NULL, NULL, &level, NULL)
+ && gdk_keymap_get_entries_for_keycode(NULL,
+ tmpEvent.hardware_keycode,
+ &keys, &keyvals,
+ &n_entries)) {
+ qint32 n;
+ for (n=0; n<n_entries; n++) {
+ if (keys[n].group == tmpEvent.group) {
+ // Skip keys from the same group
+ continue;
+ }
+ if (keys[n].level != level) {
+ // Allow only same level keys
+ continue;
+ }
+ if (is_latin_shortcut_key(keyvals[n])) {
+ // Latin character found
+ if (event.isShift)
+ tmpEvent.keyval = gdk_keyval_to_upper(keyvals[n]);
+ else
+ tmpEvent.keyval = gdk_keyval_to_lower(keyvals[n]);
+ tmpEvent.group = keys[n].group;
+ latinCharCode = nsConvertCharCodeToUnicode(&tmpEvent);
+ if (latinCharCode) {
+ event.charCode = latinCharCode;
+ break;
+ }
+ }
+ }
+ g_free(keys);
+ g_free(keyvals);
+ }
+ }
+ */
+
+ // make Ctrl+uppercase functional as same as Ctrl+lowercase
+ // when Ctrl+uppercase(eg.Ctrl+C) is pressed,convert the charCode
+ // from uppercase to lowercase(eg.Ctrl+c),so do Alt and Meta Key
+ // It is hack code for bug 61355, there is same code snip for
+ // Windows platform in widget/src/windows/nsWindow.cpp: See bug 16486
+ // Note: if Shift is pressed at the same time, do not to_lower()
+ // Because Ctrl+Shift has different function with Ctrl
+/*
+ if (!event.isShift &&
+ event.charCode >= Qt::Key_A &&
+ event.charCode <= Qt::Key_Z)
+ event.charCode = gdk_keyval_to_lower(event.charCode);
+*/
+
+ // Keep the characters unshifted for shortcuts and accesskeys and
+ // make sure that numbers are always passed as such (among others:
+ // bugs 50255 and 351310)
+/*
+ if (!event.isControl && event.isShift &&
+ (event.charCode < Qt::Key_0 || event.charCode > Qt::Key_9)) {
+ GdkKeymapKey k = { tmpEvent.hardware_keycode, tmpEvent.group, 0 };
+ tmpEvent.keyval = gdk_keymap_lookup_key(gdk_keymap_get_default(), &k);
+ PRUint32 unshiftedCharCode = nsConvertCharCodeToUnicode(&tmpEvent);
+ if (unshiftedCharCode)
+ event.charCode = unshiftedCharCode;
+ } */
+ }
+ }
+
+ // before we dispatch a key, check if it's the context menu key.
+ // If so, send a context menu key event instead.
+ if (isContextMenuKey(event)) {
+ nsMouseEvent contextMenuEvent(PR_TRUE, NS_CONTEXTMENU, this,
+ nsMouseEvent::eReal,
+ nsMouseEvent::eContextMenuKey);
+ keyEventToContextMenuEvent(&event, &contextMenuEvent);
+ DispatchEvent(&contextMenuEvent, status);
+ }
+ else {
+ // send the key press event
+ DispatchEvent(&event, status);
+ }
+
+
+ // If the event was consumed, return.
+ LOGIM(("status %d\n", status));
+ if (status == nsEventStatus_eConsumeNoDefault) {
+ LOGIM(("key press consumed\n"));
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+bool
+nsWindow::OnKeyReleaseEvent(QKeyEvent *aEvent)
+{
+ LOGFOCUS(("OnKeyReleaseEvent [%p]\n", (void *)this));
+
+#ifdef USE_XIM
+ if (IMEFilterEvent(aEvent))
+ return TRUE;
+#endif
+
+ // send the key event as a key up event
+ nsKeyEvent event(PR_TRUE, NS_KEY_UP, this);
+ InitKeyEvent(event, aEvent);
+
+ // unset the key down flag
+ ClearKeyDownFlag(event.keyCode);
+
+ nsEventStatus status;
+ DispatchEvent(&event, status);
+
+ // If the event was consumed, return.
+ if (status == nsEventStatus_eConsumeNoDefault) {
+ LOGIM(("key release consumed\n"));
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+bool
+nsWindow::OnScrollEvent(QWheelEvent *aEvent)
+{
+ // check to see if we should rollup
+ nsMouseScrollEvent event(PR_TRUE, NS_MOUSE_SCROLL, this);
+
+ switch (aEvent->orientation()) {
+ case Qt::Vertical:
+ event.scrollFlags = nsMouseScrollEvent::kIsVertical;
+ break;
+ case Qt::Horizontal:
+ event.scrollFlags = nsMouseScrollEvent::kIsHorizontal;
+ break;
+ default:
+ Q_ASSERT(0);
+ break;
+ }
+ event.delta = (int)((aEvent->delta() / WHEEL_DELTA) * -3);
+
+ event.refPoint.x = nscoord(aEvent->x());
+ event.refPoint.y = nscoord(aEvent->y());
+
+ event.isShift = aEvent->modifiers() & Qt::ShiftModifier;
+ event.isControl = aEvent->modifiers() & Qt::ControlModifier;
+ event.isAlt = aEvent->modifiers() & Qt::AltModifier;
+ event.isMeta = aEvent->modifiers() & Qt::MetaModifier;
+ event.time = 0;
+
+ nsEventStatus status;
+ DispatchEvent(&event, status);
+ return ignoreEvent(status);
+}
+
+
+bool
+nsWindow::showEvent(QShowEvent *)
+{
+ LOG(("%s [%p]\n", __PRETTY_FUNCTION__,(void *)this));
+ qDebug("FIXME:>>>>>>Func:%s::%d\n", __PRETTY_FUNCTION__, __LINE__);
+/*
+ QRect r = mDrawingarea->rect();
+ nsRect rect(r.x(), r.y(), r.width(), r.height());
+
+ nsCOMPtr<nsIRenderingContext> rc = getter_AddRefs(GetRenderingContext());
+ // Generate XPFE paint event
+ nsPaintEvent event(PR_TRUE, NS_PAINT, this);
+ event.refPoint.x = 0;
+ event.refPoint.y = 0;
+ event.rect = ▭
+ // XXX fix this!
+ event.region = nsnull;
+ // XXX fix this!
+ event.renderingContext = rc;
+
+ nsEventStatus status;
+ DispatchEvent(&event, status);
+*/
+ mIsVisible = PR_TRUE;
+ return false;
+}
+
+bool
+nsWindow::hideEvent(QHideEvent *)
+{
+ LOG(("%s [%p]\n", __PRETTY_FUNCTION__,(void *)this));
+ mIsVisible = PR_FALSE;
+ return false;
+}
+
+bool
+nsWindow::OnWindowStateEvent(QEvent *aEvent)
+{
+ qDebug("FIXME:>>>>>>Func:%s::%d\n", __PRETTY_FUNCTION__, __LINE__);
+ nsSizeModeEvent event(PR_TRUE, NS_SIZEMODE, this);
+ nsEventStatus status;
+ DispatchEvent(&event, status);
+ return ignoreEvent(status);
+}
+
+void
+nsWindow::ThemeChanged()
+{
+ nsGUIEvent event(PR_TRUE, NS_THEMECHANGED, this);
+ nsEventStatus status = nsEventStatus_eIgnore;
+ DispatchEvent(&event, status);
+
+ if (!mDrawingarea || NS_UNLIKELY(mIsDestroyed))
+ return;
+ qDebug("FIXME:>>>>>>Func:%s::%d\n", __PRETTY_FUNCTION__, __LINE__);
+ return;
+}
+
+bool
+nsWindow::OnDragMotionEvent(QDragMoveEvent *e)
+{
+ LOG(("nsWindow::OnDragMotionSignal\n"));
+
+ nsMouseEvent event(PR_TRUE, NS_DRAGDROP_OVER, 0,
+ nsMouseEvent::eReal);
+ return TRUE;
+}
+
+bool
+nsWindow::OnDragLeaveEvent(QDragLeaveEvent *e)
+{
+ // XXX Do we want to pass this on only if the event's subwindow is null?
+ LOG(("nsWindow::OnDragLeaveSignal(%p)\n", this));
+ nsMouseEvent event(PR_TRUE, NS_DRAGDROP_EXIT, this, nsMouseEvent::eReal);
+
+ nsEventStatus status;
+ DispatchEvent(&event, status);
+ return ignoreEvent(status);
+}
+
+bool
+nsWindow::OnDragDropEvent(QDropEvent *e)
+{
+ LOG(("nsWindow::OnDragDropSignal\n"));
+ nsMouseEvent event(PR_TRUE, NS_DRAGDROP_OVER, 0,
+ nsMouseEvent::eReal);
+ return TRUE;
+}
+
+bool
+nsWindow::OnDragEnter(QDragEnterEvent *)
+{
+ // XXX Do we want to pass this on only if the event's subwindow is null?
+
+ LOG(("nsWindow::OnDragEnter(%p)\n", this));
+
+ nsMouseEvent event(PR_TRUE, NS_DRAGDROP_ENTER, this, nsMouseEvent::eReal);
+ nsEventStatus status;
+ DispatchEvent(&event, status);
+ return ignoreEvent(status);
+}
+
+static void
+GetBrandName(nsXPIDLString& brandName)
+{
+ nsCOMPtr<nsIStringBundleService> bundleService =
+ do_GetService(NS_STRINGBUNDLE_CONTRACTID);
+
+ nsCOMPtr<nsIStringBundle> bundle;
+ if (bundleService)
+ bundleService->CreateBundle(
+ "chrome://branding/locale/brand.properties",
+ getter_AddRefs(bundle));
+
+ if (bundle)
+ bundle->GetStringFromName(
+ NS_LITERAL_STRING("brandShortName").get(),
+ getter_Copies(brandName));
+
+ if (brandName.IsEmpty())
+ brandName.Assign(NS_LITERAL_STRING("Mozilla"));
+}
+
+
+nsresult
+nsWindow::NativeCreate(nsIWidget *aParent,
+ nsNativeWidget aNativeParent,
+ const nsRect &aRect,
+ EVENT_CALLBACK aHandleEventFunction,
+ nsIDeviceContext *aContext,
+ nsIAppShell *aAppShell,
+ nsIToolkit *aToolkit,
+ nsWidgetInitData *aInitData)
+{
+ // only set the base parent if we're going to be a dialog or a
+ // toplevel
+ nsIWidget *baseParent = aInitData &&
+ (aInitData->mWindowType == eWindowType_dialog ||
+ aInitData->mWindowType == eWindowType_toplevel ||
+ aInitData->mWindowType == eWindowType_invisible) ?
+ nsnull : aParent;
+
+ // initialize all the common bits of this class
+ BaseCreate(baseParent, aRect, aHandleEventFunction, aContext,
+ aAppShell, aToolkit, aInitData);
+
+ // Do we need to listen for resizes?
+ PRBool listenForResizes = PR_FALSE;;
+ if (aNativeParent || (aInitData && aInitData->mListenForResizes))
+ listenForResizes = PR_TRUE;
+
+ // and do our common creation
+ CommonCreate(aParent, listenForResizes);
+
+ // save our bounds
+ mBounds = aRect;
+ if (mWindowType != eWindowType_child) {
+ // The window manager might place us. Indicate that if we're
+ // shown, we want to go through
+ // nsWindow::NativeResize(x,y,w,h) to maybe set our own
+ // position.
+ mNeedsMove = PR_TRUE;
+ }
+
+ // figure out our parent window
+ QWidget *parent = nsnull;
+ if (aParent != nsnull)
+ parent = (QWidget*)aParent->GetNativeData(NS_NATIVE_WIDGET);
+ else
+ parent = (QWidget*)aNativeParent;
+
+#ifdef MOZ_ENABLE_GLITZ
+ GdkVisual* visual = nsnull;
+ if (gfxPlatform::UseGlitz()) {
+ nsCOMPtr<nsIDeviceContext> dc = aContext;
+ if (!dc) {
+ nsCOMPtr<nsIDeviceContext> dc = do_CreateInstance(kDeviceContextCID);
+ // no parent widget to initialize with
+ dc->Init(nsnull);
+ }
+
+ Display* dpy = ;
+ int defaultScreen = gdk_x11_get_default_screen();
+ glitz_drawable_format_t* format = glitz_glx_find_window_format (dpy, defaultScreen,
+ 0, NULL, 0);
+ if (format) {
+ XVisualInfo* vinfo = glitz_glx_get_visual_info_from_format(dpy, defaultScreen, format);
+ GdkScreen* screen = gdk_display_get_screen(gdk_x11_lookup_xdisplay(dpy), defaultScreen);
+ visual = gdk_x11_screen_lookup_visual(screen, vinfo->visualid);
+ } else {
+ // couldn't find a GLX visual; force Glitz off
+ gfxPlatform::SetUseGlitz(PR_FALSE);
+ }
+ }
+#endif
+
+ // ok, create our windows
+ mDrawingarea = createQWidget(parent, aInitData);
+
+ Initialize(mDrawingarea);
+
+ LOG(("nsWindow [%p]\n", (void *)this));
+ if (mDrawingarea) {
+ LOG(("\tmDrawingarea %p %p %p %lx %lx\n", (void *)mDrawingarea));
+ }
+
+ // resize so that everything is set to the right dimensions
+ if (!mIsTopLevel)
+ Resize(mBounds.x, mBounds.y, mBounds.width, mBounds.height, PR_FALSE);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWindow::SetWindowClass(const nsAString &xulWinType)
+{
+ if (!mDrawingarea)
+ return NS_ERROR_FAILURE;
+
+ nsXPIDLString brandName;
+ GetBrandName(brandName);
+
+ XClassHint *class_hint = XAllocClassHint();
+ if (!class_hint)
+ return NS_ERROR_OUT_OF_MEMORY;
+ const char *role = NULL;
+ class_hint->res_name = ToNewCString(xulWinType);
+ if (!class_hint->res_name) {
+ XFree(class_hint);
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ class_hint->res_class = ToNewCString(brandName);
+ if (!class_hint->res_class) {
+ nsMemory::Free(class_hint->res_name);
+ XFree(class_hint);
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ // Parse res_name into a name and role. Characters other than
+ // [A-Za-z0-9_-] are converted to '_'. Anything after the first
+ // colon is assigned to role; if there's no colon, assign the
+ // whole thing to both role and res_name.
+ for (char *c = class_hint->res_name; *c; c++) {
+ if (':' == *c) {
+ *c = 0;
+ role = c + 1;
+ }
+ else if (!isascii(*c) || (!isalnum(*c) && ('_' != *c) && ('-' != *c)))
+ *c = '_';
+ }
+ class_hint->res_name[0] = toupper(class_hint->res_name[0]);
+ if (!role) role = class_hint->res_name;
+
+ // gdk_window_set_role(GTK_WIDGET(mDrawingarea)->window, role);
+ qDebug("FIXME:>>>>>>Func:%s::%d\n", __PRETTY_FUNCTION__, __LINE__);
+ // Can't use gtk_window_set_wmclass() for this; it prints
+ // a warning & refuses to make the change.
+ XSetClassHint(mDrawingarea->x11Info().display(),
+ mDrawingarea->handle(),
+ class_hint);
+ nsMemory::Free(class_hint->res_class);
+ nsMemory::Free(class_hint->res_name);
+ XFree(class_hint);
+ return NS_OK;
+}
+
+void
+nsWindow::NativeResize(PRInt32 aWidth, PRInt32 aHeight, PRBool aRepaint)
+{
+ LOG(("nsWindow::NativeResize [%p] %d %d\n", (void *)this,
+ aWidth, aHeight));
+
+ ResizeTransparencyBitmap(aWidth, aHeight);
+
+ // clear our resize flag
+ mNeedsResize = PR_FALSE;
+
+ mDrawingarea->resize( aWidth, aHeight);
+
+ if (aRepaint) {
+ if (mDrawingarea->isVisible())
+ mDrawingarea->repaint();
+ }
+}
+
+void
+nsWindow::NativeResize(PRInt32 aX, PRInt32 aY,
+ PRInt32 aWidth, PRInt32 aHeight,
+ PRBool aRepaint)
+{
+ mNeedsResize = PR_FALSE;
+ mNeedsMove = PR_FALSE;
+
+ LOG(("nsWindow::NativeResize [%p] %d %d %d %d\n", (void *)this,
+ aX, aY, aWidth, aHeight));
+
+ ResizeTransparencyBitmap(aWidth, aHeight);
+
+ QPoint pos(aX, aY);
+ if (mDrawingarea)
+ {
+ if (mParent && mDrawingarea->windowType() == Qt::Popup) {
+ nsRect oldrect, newrect;
+ oldrect.x = aX;
+ oldrect.y = aY;
+
+ mParent->WidgetToScreen(oldrect, newrect);
+
+ pos = QPoint(newrect.x, newrect.y);
+#ifdef DEBUG_WIDGETS
+ qDebug("pos is [%d,%d]", pos.x(), pos.y());
+#endif
+ } else {
+#ifdef DEBUG_WIDGETS
+ qDebug("Widget with original position? (%p)", mDrawingarea);
+#endif
+ }
+ }
+
+ mDrawingarea->setGeometry(pos.x(), pos.y(), aWidth, aHeight);
+
+ if (aRepaint) {
+ if (mDrawingarea->isVisible())
+ mDrawingarea->repaint();
+ }
+}
+
+void
+nsWindow::NativeShow (PRBool aAction)
+{
+ if (aAction) {
+ // GTK wants us to set the window mask before we show the window
+ // for the first time, or setting the mask later won't work.
+ // GTK also wants us to NOT set the window mask if we're not really
+ // going to need it, because GTK won't let us unset the mask properly
+ // later.
+ // So, we delay setting the mask until the last moment: when the window
+ // is shown.
+ // XXX that may or may not be true for GTK+ 2.x
+ if (mTransparencyBitmap) {
+ ApplyTransparencyBitmap();
+ }
+
+ // unset our flag now that our window has been shown
+ mNeedsShow = PR_FALSE;
+ }
+ if (!mDrawingarea) {
+ //XXX: apperently can be null during the printing, check whether
+ // that's true
+ qDebug("nsCommon::Show : widget empty");
+ return;
+ }
+ mDrawingarea->setShown(aAction);
+}
+
+void
+nsWindow::EnsureGrabs(void)
+{
+ if (mRetryPointerGrab)
+ GrabPointer();
+ if (mRetryKeyboardGrab)
+ GrabKeyboard();
+}
+
+NS_IMETHODIMP
+nsWindow::SetHasTransparentBackground(PRBool aTransparent)
+{
+// if (!mDrawingarea) {
+ // Pass the request to the toplevel window
+// return topWindow->SetHasTransparentBackground(aTransparent);
+// }
+
+ if (mIsTransparent == aTransparent)
+ return NS_OK;
+
+ if (!aTransparent) {
+ if (mTransparencyBitmap) {
+ delete[] mTransparencyBitmap;
+ mTransparencyBitmap = nsnull;
+ mTransparencyBitmapWidth = 0;
+ mTransparencyBitmapHeight = 0;
+ // gtk_widget_reset_shapes(mDrawingarea);
+ }
+ } // else the new default alpha values are "all 1", so we don't
+ // need to change anything yet
+
+ mIsTransparent = aTransparent;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWindow::GetHasTransparentBackground(PRBool& aTransparent)
+{
+ if (!mDrawingarea) {
+ // Pass the request to the toplevel window
+// QWidget *topWidget = nsnull;
+// GetToplevelWidget(&topWidget);
+// if (!topWidget) {
+// aTransparent = PR_FALSE;
+// return NS_ERROR_FAILURE;
+// }
+
+// if (!topWindow) {
+// aTransparent = PR_FALSE;
+// return NS_ERROR_FAILURE;
+// }
+
+// return topWindow->GetHasTransparentBackground(aTransparent);
+ }
+
+ aTransparent = mIsTransparent;
+ return NS_OK;
+}
+
+void
+nsWindow::ResizeTransparencyBitmap(PRInt32 aNewWidth, PRInt32 aNewHeight)
+{
+ if (!mTransparencyBitmap)
+ return;
+
+ if (aNewWidth == mTransparencyBitmapWidth &&
+ aNewHeight == mTransparencyBitmapHeight)
+ return;
+
+ PRInt32 newSize = ((aNewWidth+7)/8)*aNewHeight;
+ char* newBits = new char[newSize];
+ if (!newBits) {
+ delete[] mTransparencyBitmap;
+ mTransparencyBitmap = nsnull;
+ mTransparencyBitmapWidth = 0;
+ mTransparencyBitmapHeight = 0;
+ return;
+ }
+ // fill new mask with "opaque", first
+ memset(newBits, 255, newSize);
+
+ // Now copy the intersection of the old and new areas into the new mask
+ PRInt32 copyWidth = PR_MIN(aNewWidth, mTransparencyBitmapWidth);
+ PRInt32 copyHeight = PR_MIN(aNewHeight, mTransparencyBitmapHeight);
+ PRInt32 oldRowBytes = (mTransparencyBitmapWidth+7)/8;
+ PRInt32 newRowBytes = (aNewWidth+7)/8;
+ PRInt32 copyBytes = (copyWidth+7)/8;
+
+ PRInt32 i;
+ char* fromPtr = mTransparencyBitmap;
+ char* toPtr = newBits;
+ for (i = 0; i < copyHeight; i++) {
+ memcpy(toPtr, fromPtr, copyBytes);
+ fromPtr += oldRowBytes;
+ toPtr += newRowBytes;
+ }
+
+ delete[] mTransparencyBitmap;
+ mTransparencyBitmap = newBits;
+ mTransparencyBitmapWidth = aNewWidth;
+ mTransparencyBitmapHeight = aNewHeight;
+}
+
+static PRBool
+ChangedMaskBits(char* aMaskBits, PRInt32 aMaskWidth, PRInt32 aMaskHeight,
+ const nsRect& aRect, PRUint8* aAlphas, PRInt32 aStride)
+{
+ PRInt32 x, y, xMax = aRect.XMost(), yMax = aRect.YMost();
+ PRInt32 maskBytesPerRow = (aMaskWidth + 7)/8;
+ for (y = aRect.y; y < yMax; y++) {
+ char* maskBytes = aMaskBits + y*maskBytesPerRow;
+ PRUint8* alphas = aAlphas;
+ for (x = aRect.x; x < xMax; x++) {
+ PRBool newBit = *alphas > 0;
+ alphas++;
+
+ char maskByte = maskBytes[x >> 3];
+ PRBool maskBit = (maskByte & (1 << (x & 7))) != 0;
+
+ if (maskBit != newBit) {
+ return PR_TRUE;
+ }
+ }
+ aAlphas += aStride;
+ }
+
+ return PR_FALSE;
+}
+
+static
+void UpdateMaskBits(char* aMaskBits, PRInt32 aMaskWidth, PRInt32 aMaskHeight,
+ const nsRect& aRect, PRUint8* aAlphas, PRInt32 aStride)
+{
+ PRInt32 x, y, xMax = aRect.XMost(), yMax = aRect.YMost();
+ PRInt32 maskBytesPerRow = (aMaskWidth + 7)/8;
+ for (y = aRect.y; y < yMax; y++) {
+ char* maskBytes = aMaskBits + y*maskBytesPerRow;
+ PRUint8* alphas = aAlphas;
+ for (x = aRect.x; x < xMax; x++) {
+ PRBool newBit = *alphas > 0;
+ alphas++;
+
+ char mask = 1 << (x & 7);
+ char maskByte = maskBytes[x >> 3];
+ // Note: '-newBit' turns 0 into 00...00 and 1 into 11...11
+ maskBytes[x >> 3] = (maskByte & ~mask) | (-newBit & mask);
+ }
+ aAlphas += aStride;
+ }
+}
+
+void
+nsWindow::ApplyTransparencyBitmap()
+{
+ qDebug("FIXME:>>>>>>Func:%s::%d\n", __PRETTY_FUNCTION__, __LINE__);
+/*
+ gtk_widget_reset_shapes(mDrawingarea);
+ GdkBitmap* maskBitmap = gdk_bitmap_create_from_data(mDrawingarea->window,
+ mTransparencyBitmap,
+ mTransparencyBitmapWidth, mTransparencyBitmapHeight);
+ if (!maskBitmap)
+ return;
+
+ gtk_widget_shape_combine_mask(mDrawingarea, maskBitmap, 0, 0);
+ gdk_bitmap_unref(maskBitmap);
+*/
+}
+
+nsresult
+nsWindow::UpdateTranslucentWindowAlphaInternal(const nsRect& aRect,
+ PRUint8* aAlphas, PRInt32 aStride)
+{
+ if (!mDrawingarea) {
+ // Pass the request to the toplevel window
+// return topWindow->UpdateTranslucentWindowAlphaInternal(aRect, aAlphas, aStride);
+ return NS_ERROR_FAILURE;
+ }
+
+ NS_ASSERTION(mIsTransparent, "Window is not transparent");
+
+ if (mTransparencyBitmap == nsnull) {
+ PRInt32 size = ((mBounds.width+7)/8)*mBounds.height;
+ mTransparencyBitmap = new char[size];
+ if (mTransparencyBitmap == nsnull)
+ return NS_ERROR_FAILURE;
+ memset(mTransparencyBitmap, 255, size);
+ mTransparencyBitmapWidth = mBounds.width;
+ mTransparencyBitmapHeight = mBounds.height;
+ }
+
+ NS_ASSERTION(aRect.x >= 0 && aRect.y >= 0
+ && aRect.XMost() <= mBounds.width && aRect.YMost() <= mBounds.height,
+ "Rect is out of window bounds");
+
+ if (!ChangedMaskBits(mTransparencyBitmap, mBounds.width, mBounds.height,
+ aRect, aAlphas, aStride))
+ // skip the expensive stuff if the mask bits haven't changed; hopefully
+ // this is the common case
+ return NS_OK;
+
+ UpdateMaskBits(mTransparencyBitmap, mBounds.width, mBounds.height,
+ aRect, aAlphas, aStride);
+
+ if (!mNeedsShow) {
+ ApplyTransparencyBitmap();
+ }
+ return NS_OK;
+}
+
+void
+nsWindow::GrabPointer(void)
+{
+ LOG(("GrabPointer %d\n", mRetryPointerGrab));
+
+ mRetryPointerGrab = PR_FALSE;
+
+ // If the window isn't visible, just set the flag to retry the
+ // grab. When this window becomes visible, the grab will be
+ // retried.
+ PRBool visibility = PR_TRUE;
+ IsVisible(visibility);
+ if (!visibility) {
+ LOG(("GrabPointer: window not visible\n"));
+ mRetryPointerGrab = PR_TRUE;
+ return;
+ }
+
+ if (!mDrawingarea)
+ return;
+
+ mDrawingarea->grabMouse();
+}
+
+void
+nsWindow::GrabKeyboard(void)
+{
+ LOG(("GrabKeyboard %d\n", mRetryKeyboardGrab));
+
+ mRetryKeyboardGrab = PR_FALSE;
+
+ // If the window isn't visible, just set the flag to retry the
+ // grab. When this window becomes visible, the grab will be
+ // retried.
+ PRBool visibility = PR_TRUE;
+ IsVisible(visibility);
+ if (!visibility) {
+ LOG(("GrabKeyboard: window not visible\n"));
+ mRetryKeyboardGrab = PR_TRUE;
+ return;
+ }
+
+ if (!mDrawingarea)
+ return;
+
+ mDrawingarea->grabKeyboard();
+}
+
+void
+nsWindow::ReleaseGrabs(void)
+{
+ LOG(("ReleaseGrabs\n"));
+
+ mRetryPointerGrab = PR_FALSE;
+ mRetryKeyboardGrab = PR_FALSE;
+
+// gdk_pointer_ungrab(Qt::Key_CURRENT_TIME);
+// gdk_keyboard_ungrab(Qt::Key_CURRENT_TIME);
+}
+
+void
+nsWindow::GetToplevelWidget(QWidget **aWidget)
+{
+ *aWidget = nsnull;
+
+ if (mDrawingarea) {
+ *aWidget = mDrawingarea;
+ return;
+ }
+}
+
+void
+nsWindow::SetUrgencyHint(QWidget *top_window, PRBool state)
+{
+ if (!top_window)
+ return;
+ qDebug("FIXME:>>>>>>Func:%s::%d\n", __PRETTY_FUNCTION__, __LINE__);
+/*
+ // Try to get a pointer to gdk_window_set_urgency_hint
+ PRLibrary* lib;
+ _gdk_window_set_urgency_hint_fn _gdk_window_set_urgency_hint = nsnull;
+ _gdk_window_set_urgency_hint = (_gdk_window_set_urgency_hint_fn)
+ PR_FindFunctionSymbolAndLibrary("gdk_window_set_urgency_hint", &lib);
+
+ if (_gdk_window_set_urgency_hint) {
+ _gdk_window_set_urgency_hint(top_window->window, state);
+ PR_UnloadLibrary(lib);
+ }
+ else if (state) {
+ gdk_window_show_unraised(top_window->window);
+ }
+*/
+}
+
+void *
+nsWindow::SetupPluginPort(void)
+{
+ if (!mDrawingarea)
+ return nsnull;
+
+ qDebug("FIXME:>>>>>>Func:%s::%d\n", __PRETTY_FUNCTION__, __LINE__);
+
+/*
+ // we have to flush the X queue here so that any plugins that
+ // might be running on separate X connections will be able to use
+ // this window in case it was just created
+ XWindowAttributes xattrs;
+ XGetWindowAttributes(Qt::Key_DISPLAY (),
+ Qt::Key_WINDOW_XWINDOW(mDrawingarea->inner_window),
+ &xattrs);
+ XSelectInput (Qt::Key_DISPLAY (),
+ Qt::Key_WINDOW_XWINDOW(mDrawingarea->inner_window),
+ xattrs.your_event_mask |
+ SubstructureNotifyMask);
+
+ gdk_window_add_filter(mDrawingarea->inner_window,
+ plugin_window_filter_func,
+ this);
+
+ XSync(Qt::Key_DISPLAY(), False);
+
+ return (void *)Qt::Key_WINDOW_XWINDOW(mDrawingarea->inner_window);
+*/
+ return nsnull;
+}
+
+nsresult
+nsWindow::SetWindowIconList(const nsCStringArray &aIconList)
+{
+ qDebug("FIXME:>>>>>>Func:%s::%d\n", __PRETTY_FUNCTION__, __LINE__);
+ return NS_OK;
+}
+
+void
+nsWindow::SetDefaultIcon(void)
+{
+ SetIcon(NS_LITERAL_STRING("default"));
+}
+
+void
+nsWindow::SetPluginType(PluginType aPluginType)
+{
+ mPluginType = aPluginType;
+}
+
+void
+nsWindow::SetNonXEmbedPluginFocus()
+{
+ qDebug("FIXME:>>>>>>Func:%s::%d\n", __PRETTY_FUNCTION__, __LINE__);
+}
+
+void
+nsWindow::LoseNonXEmbedPluginFocus()
+{
+ qDebug("FIXME:>>>>>>Func:%s::%d\n", __PRETTY_FUNCTION__, __LINE__);
+ LOGFOCUS(("nsWindow::LoseNonXEmbedPluginFocus\n"));
+ LOGFOCUS(("nsWindow::LoseNonXEmbedPluginFocus end\n"));
+}
+
+
+qint32
+nsWindow::ConvertBorderStyles(nsBorderStyle aStyle)
+{
+ qint32 w = 0;
+
+ if (aStyle == eBorderStyle_default)
+ return -1;
+
+ qDebug("FIXME:>>>>>>Func:%s::%d\n", __PRETTY_FUNCTION__, __LINE__);
+/*
+ if (aStyle & eBorderStyle_all)
+ w |= Qt::Key_DECOR_ALL;
+ if (aStyle & eBorderStyle_border)
+ w |= Qt::Key_DECOR_BORDER;
+ if (aStyle & eBorderStyle_resizeh)
+ w |= Qt::Key_DECOR_RESIZEH;
+ if (aStyle & eBorderStyle_title)
+ w |= Qt::Key_DECOR_TITLE;
+ if (aStyle & eBorderStyle_menu)
+ w |= Qt::Key_DECOR_MENU;
+ if (aStyle & eBorderStyle_minimize)
+ w |= Qt::Key_DECOR_MINIMIZE;
+ if (aStyle & eBorderStyle_maximize)
+ w |= Qt::Key_DECOR_MAXIMIZE;
+ if (aStyle & eBorderStyle_close) {
+#ifdef DEBUG
+ printf("we don't handle eBorderStyle_close yet... please fix me\n");
+#endif
+ }
+*/
+ return w;
+}
+
+NS_IMETHODIMP
+nsWindow::MakeFullScreen(PRBool aFullScreen)
+{
+/*
+#if GTK_CHECK_VERSION(2,2,0)
+ if (aFullScreen)
+ gdk_window_fullscreen (mDrawingarea->window);
+ else
+ gdk_window_unfullscreen (mDrawingarea->window);
+ return NS_OK;
+#else
+*/
+ return nsBaseWidget::MakeFullScreen(aFullScreen);
+//#endif
+}
+
+NS_IMETHODIMP
+nsWindow::HideWindowChrome(PRBool aShouldHide)
+{
+ if (!mDrawingarea) {
+ // Pass the request to the toplevel window
+ QWidget *topWidget = nsnull;
+ GetToplevelWidget(&topWidget);
+// return topWindow->HideWindowChrome(aShouldHide);
+ return NS_ERROR_FAILURE;
+ }
+
+ // Sawfish, metacity, and presumably other window managers get
+ // confused if we change the window decorations while the window
+ // is visible.
+ PRBool wasVisible = PR_FALSE;
+ if (mDrawingarea->isVisible()) {
+ mDrawingarea->hide();
+ wasVisible = PR_TRUE;
+ }
+
+ qint32 wmd;
+ if (aShouldHide)
+ wmd = 0;
+ else
+ wmd = ConvertBorderStyles(mBorderStyle);
+
+// gdk_window_set_decorations(mDrawingarea->window, (GdkWMDecoration) wmd);
+
+ if (wasVisible) {
+ mDrawingarea->show();
+ }
+
+ // For some window managers, adding or removing window decorations
+ // requires unmapping and remapping our toplevel window. Go ahead
+ // and flush the queue here so that we don't end up with a BadWindow
+ // error later when this happens (when the persistence timer fires
+ // and GetWindowPos is called)
+ XSync(mDrawingarea->x11Info().display(), False);
+
+ return NS_OK;
+}
+
+/* static */
+PRBool
+is_mouse_in_window (QWidget* aWindow, double aMouseX, double aMouseY)
+{
+ qint32 x = 0;
+ qint32 y = 0;
+ qint32 w, h;
+
+ qint32 offsetX = 0;
+ qint32 offsetY = 0;
+
+ QWidget *window;
+
+ window = aWindow;
+
+ while (window) {
+ qint32 tmpX = window->pos().x();
+ qint32 tmpY = window->pos().y();
+
+ // if this is a window, compute x and y given its origin and our
+ // offset
+ x = tmpX + offsetX;
+ y = tmpY + offsetY;
+ break;
+
+ offsetX += tmpX;
+ offsetY += tmpY;
+ }
+
+ w = window->size().width();
+ h = window->size().height();
+
+ if (aMouseX > x && aMouseX < x + w &&
+ aMouseY > y && aMouseY < y + h)
+ return PR_TRUE;
+
+ return PR_FALSE;
+}
+
+/* static */
+nsWindow *
+get_window_for_qt_widget(QWidget *widget)
+{
+ MozQWidget *mozWidget = static_cast<MozQWidget*>(widget);
+ return mozWidget->getReciever();
+}
+
+//////////////////////////////////////////////////////////////////////
+// These are all of our drag and drop operations
+
+void
+nsWindow::InitDragEvent(nsMouseEvent &aEvent)
+{
+ // set the keyboard modifiers
+/*
+ qint32 x, y;
+
+ GdkModifierType state = (GdkModifierType)0;
+ gdk_window_get_pointer(NULL, &x, &y, &state);
+ aEvent.isShift = (state & Qt::Key_SHIFT_MASK) ? PR_TRUE : PR_FALSE;
+ aEvent.isControl = (state & Qt::Key_CONTROL_MASK) ? PR_TRUE : PR_FALSE;
+ aEvent.isAlt = (state & Qt::Key_MOD1_MASK) ? PR_TRUE : PR_FALSE;
+ aEvent.isMeta = PR_FALSE; // GTK+ doesn't support the meta key
+*/
+}
+
+// This will update the drag action based on the information in the
+// drag context. Gtk gets this from a combination of the key settings
+// and what the source is offering.
+
+/* static */
+nsresult
+initialize_prefs(void)
+{
+ // check to see if we should set our raise pref
+ nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
+ if (!prefs)
+ return NS_OK;
+
+ PRBool val = PR_TRUE;
+ nsresult rv;
+ rv = prefs->GetBoolPref("mozilla.widget.raise-on-setfocus", &val);
+
+ return NS_OK;
+}
+
+inline PRBool
+is_context_menu_key(const nsKeyEvent& aKeyEvent)
+{
+ return ((aKeyEvent.keyCode == NS_VK_F10 && aKeyEvent.isShift &&
+ !aKeyEvent.isControl && !aKeyEvent.isMeta && !aKeyEvent.isAlt) ||
+ (aKeyEvent.keyCode == NS_VK_CONTEXT_MENU && !aKeyEvent.isShift &&
+ !aKeyEvent.isControl && !aKeyEvent.isMeta && !aKeyEvent.isAlt));
+}
+
+void
+key_event_to_context_menu_event(nsMouseEvent &aEvent,
+ QKeyEvent *aGdkEvent)
+{
+ aEvent.refPoint = nsPoint(0, 0);
+ aEvent.isShift = PR_FALSE;
+ aEvent.isControl = PR_FALSE;
+ aEvent.isAlt = PR_FALSE;
+ aEvent.isMeta = PR_FALSE;
+ aEvent.time = 0;
+ aEvent.clickCount = 1;
+}
+
+static PRBool
+gdk_keyboard_get_modmap_masks(Display* aDisplay,
+ PRUint32* aCapsLockMask,
+ PRUint32* aNumLockMask,
+ PRUint32* aScrollLockMask)
+{
+ *aCapsLockMask = 0;
+ *aNumLockMask = 0;
+ *aScrollLockMask = 0;
+
+ int min_keycode = 0;
+ int max_keycode = 0;
+ XDisplayKeycodes(aDisplay, &min_keycode, &max_keycode);
+
+ int keysyms_per_keycode = 0;
+ KeySym* xkeymap = XGetKeyboardMapping(aDisplay, min_keycode,
+ max_keycode - min_keycode + 1,
+ &keysyms_per_keycode);
+ if (!xkeymap) {
+ return PR_FALSE;
+ }
+
+ XModifierKeymap* xmodmap = XGetModifierMapping(aDisplay);
+ if (!xmodmap) {
+ XFree(xkeymap);
+ return PR_FALSE;
+ }
+
+ /*
+ The modifiermap member of the XModifierKeymap structure contains 8 sets
+ of max_keypermod KeyCodes, one for each modifier in the order Shift,
+ Lock, Control, Mod1, Mod2, Mod3, Mod4, and Mod5.
+ Only nonzero KeyCodes have meaning in each set, and zero KeyCodes are ignored.
+ */
+ const unsigned int map_size = 8 * xmodmap->max_keypermod;
+ for (unsigned int i = 0; i < map_size; i++) {
+ KeyCode keycode = xmodmap->modifiermap[i];
+ if (!keycode || keycode < min_keycode || keycode > max_keycode)
+ continue;
+
+ const KeySym* syms = xkeymap + (keycode - min_keycode) * keysyms_per_keycode;
+ const unsigned int mask = 1 << (i / xmodmap->max_keypermod);
+ for (int j = 0; j < keysyms_per_keycode; j++) {
+ switch (syms[j]) {
+ case Qt::Key_CapsLock: *aCapsLockMask |= mask; break;
+ case Qt::Key_NumLock: *aNumLockMask |= mask; break;
+ case Qt::Key_ScrollLock: *aScrollLockMask |= mask; break;
+ }
+ }
+ }
+
+ XFreeModifiermap(xmodmap);
+ XFree(xkeymap);
+ return PR_TRUE;
+}
+
+// nsChildWindow class
+
+nsChildWindow::nsChildWindow()
+{
+}
+
+nsChildWindow::~nsChildWindow()
+{
+}
+
+nsPopupWindow::nsPopupWindow()
+{
+ qDebug("===================== popup!");
+}
+
+nsPopupWindow::~nsPopupWindow()
+{
+}
+
+QWidget*
+nsWindow::createQWidget(QWidget *parent, nsWidgetInitData *aInitData)
+{
+ Qt::WFlags flags = Qt::Widget;
+#ifdef DEBUG_WIDGETS
+ qDebug("NEW WIDGET\n\tparent is %p (%s)", (void*)parent,
+ parent ? qPrintable(parent->objectName()) : "null");
+#endif
+ // ok, create our windows
+ switch (mWindowType) {
+ case eWindowType_dialog:
+ case eWindowType_popup:
+ case eWindowType_toplevel:
+ case eWindowType_invisible: {
+ mIsTopLevel = PR_TRUE;
+
+ nsXPIDLString brandName;
+ GetBrandName(brandName);
+ NS_ConvertUTF16toUTF8 cBrand(brandName);
+ if (mWindowType == eWindowType_dialog) {
+ //gtk_window_set_wmclass(GTK_WINDOW(mDrawingarea), "Dialog", cBrand.get());
+ //gtk_window_set_type_hint(GTK_WINDOW(mDrawingarea),
+ // Qt::Key_WINDOW_TYPE_HINT_DIALOG);
+ flags |= Qt::Dialog;
+ mDrawingarea = new MozQWidget(this, parent, "topLevelDialog", flags);
+ qDebug("\t\t#### dialog (%p)", (void*)mDrawingarea);
+ //SetDefaultIcon();
+ }
+ else if (mWindowType == eWindowType_popup) {
+ flags |= Qt::Popup;
+ // gtk_window_set_wmclass(GTK_WINDOW(mDrawingarea), "Toplevel", cBrand.get());
+ //gtk_window_set_decorated(GTK_WINDOW(mDrawingarea), FALSE);
+ mDrawingarea = new MozQWidget(this, parent, "topLevelPopup", flags);
+ qDebug("\t\t#### popup (%p)", (void*)mDrawingarea);
+ mDrawingarea->setFocusPolicy(Qt::WheelFocus);
+ }
+ else { // must be eWindowType_toplevel
+ flags |= Qt::Window;
+ mDrawingarea = new MozQWidget(this, parent, "topLevelWindow", flags);
+ qDebug("\t\t#### toplevel (%p)", (void*)mDrawingarea);
+ //SetDefaultIcon();
+ }
+ if (mWindowType == eWindowType_popup) {
+ // gdk does not automatically set the cursor for "temporary"
+ // windows, which are what gtk uses for popups.
+ mCursor = eCursor_wait; // force SetCursor to actually set the
+ // cursor, even though our internal state
+ // indicates that we already have the
+ // standard cursor.
+ SetCursor(eCursor_standard);
+ }
+ }
+ break;
+ case eWindowType_child: {
+ mDrawingarea = new MozQWidget(this, parent, "paintArea", 0);
+ qDebug("\t\t#### child (%p)", (void*)mDrawingarea);
+ }
+ break;
+ default:
+ break;
+ }
+
+ mDrawingarea->setAttribute(Qt::WA_StaticContents);
+ mDrawingarea->setAttribute(Qt::WA_OpaquePaintEvent); // Transparent Widget Background
+
+ // Disable the double buffer because it will make the caret crazy
+ // For bug#153805 (Gtk2 double buffer makes carets misbehave)
+ mDrawingarea->setAttribute(Qt::WA_NoSystemBackground);
+ mDrawingarea->setAttribute(Qt::WA_PaintOnScreen);
+
+ return mDrawingarea;
+}
+
+// return the gfxASurface for rendering to this widget
gfxASurface*
nsWindow::GetThebesSurface()
{
// XXXvlad always create a new thebes surface for now,
// because the old clip doesn't get cleared otherwise.
// we should fix this at some point, and just reset
// the clip.
mThebesSurface = nsnull;
if (!mThebesSurface) {
- PRInt32 x_offset = 0, y_offset = 0;
- int width = mWidget->width(), height = mWidget->height();
+ qint32 x_offset = 0, y_offset = 0;
+ qint32 width = mDrawingarea->width(), height = mDrawingarea->height();
// Owen Taylor says this is the right thing to do!
- width = PR_MIN(32767, height);
- height = PR_MIN(32767, width);
+ width = PR_MIN(32767, width);
+ height = PR_MIN(32767, height);
if (!gfxPlatform::UseGlitz()) {
mThebesSurface = new gfxXlibSurface
- (mWidget->x11Info().display(),
- (Drawable)mWidget->handle(),
- static_cast<Visual*>(mWidget->x11Info().visual()),
- gfxIntSize(width, height));
- // it works for example from http://www.figuiere.net/hub/blog/?2006/07/29/430-cairo-and-qt3
- // but only with Qt3, with Qt4 we have same (nothing) result. :(
- // Yahoouzzzz.... http://doc.trolltech.com/4.1/qt4-intro.html?pfriend=yes#paint-events
- // Missing flags makes our stuff rendering almost fine
- mWidget->setAttribute(Qt::WA_PaintOnScreen);
-
+ (mDrawingarea->x11Info().display(),
+ (Drawable)mDrawingarea->handle(),
+ static_cast<Visual*>(mDrawingarea->x11Info().visual()),
+ gfxIntSize(width, height));
// if the surface creation is reporting an error, then
// we don't have a surface to give back
if (mThebesSurface && mThebesSurface->CairoStatus() != 0)
mThebesSurface = nsnull;
} else {
#ifdef MOZ_ENABLE_GLITZ
glitz_surface_t *gsurf;
glitz_drawable_t *gdraw;
- glitz_drawable_format_t *gdformat = glitz_glx_find_window_format (GDK_DISPLAY(),
- mWidget->x11Info().appScreen(),
- 0, NULL, 0);
+ glitz_drawable_format_t *gdformat = glitz_glx_find_window_format (Qt::Key_DISPLAY(),
+ gdk_x11_get_default_screen(),
+ 0, NULL, 0);
if (!gdformat)
NS_ERROR("Failed to find glitz drawable format");
- Display* dpy = mWidget->x11Info().display(),;
- Window wnd = (Window)mWidget->x11Info().appRootWindow();
+ Display* dpy = Qt::Key_WINDOW_XDISPLAY(d);
+ Window wnd = Qt::Key_WINDOW_XWINDOW(d);
gdraw =
glitz_glx_create_drawable_for_window (dpy,
DefaultScreen(dpy),
gdformat,
wnd,
width,
height);
@@ -198,34 +2974,58 @@ nsWindow::GetThebesSurface()
if (mThebesSurface) {
mThebesSurface->SetDeviceOffset(gfxPoint(-x_offset, -y_offset));
}
}
return mThebesSurface;
}
-//////////////////////////////////////////////////////////////////////
-ChildWindow::ChildWindow()
-{
-}
-
-ChildWindow::~ChildWindow()
-{
-}
-
-PRBool
-ChildWindow::IsChild() const
+NS_IMETHODIMP
+nsWindow::BeginResizeDrag(nsGUIEvent* aEvent, PRInt32 aHorizontal, PRInt32 aVertical)
{
- return PR_TRUE;
-}
-
-PopupWindow::PopupWindow()
-{
- qDebug("===================== popup!");
+ NS_ENSURE_ARG_POINTER(aEvent);
+
+
+ if (aEvent->eventStructType != NS_MOUSE_EVENT) {
+ // you can only begin a resize drag with a mouse event
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ nsMouseEvent* mouse_event = static_cast<nsMouseEvent*>(aEvent);
+
+ if (mouse_event->button != nsMouseEvent::eLeftButton) {
+ // you can only begin a resize drag with the left mouse button
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ qDebug("FIXME:>>>>>>Func:%s::%d\n", __PRETTY_FUNCTION__, __LINE__);
+
+ return NS_OK;
}
-PopupWindow::~PopupWindow()
+bool
+nsWindow::contextMenuEvent(QContextMenuEvent *)
{
+ //qDebug("context menu");
+ return false;
+}
+
+bool
+nsWindow::imStartEvent(QEvent *)
+{
+ qWarning("XXX imStartEvent");
+ return false;
}
-
-
+bool
+nsWindow::imComposeEvent(QEvent *)
+{
+ qWarning("XXX imComposeEvent");
+ return false;
+}
+
+bool
+nsWindow::imEndEvent(QEvent * )
+{
+ qWarning("XXX imComposeEvent");
+ return false;
+}
--- a/widget/src/qt/nsWindow.h
+++ b/widget/src/qt/nsWindow.h
@@ -1,85 +1,326 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim:expandtab:shiftwidth=4:tabstop=4:
+ */
+/* ***** 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 mozilla.org code.
*
- * The Initial Developer of the Original Code is
- * Zack Rusin <zack@kde.org>.
- * Portions created by the Initial Developer are Copyright (C) 2004
- * the Initial Developer. All Rights Reserved.
+ * The Initial Developer of the Original Code is Christopher Blizzard
+ * <blizzard@mozilla.org>. Portions created by the Initial Developer
+ * are Copyright (C) 2001 the Initial Developer. All Rights Reserved.
*
* Contributor(s):
- * Lars Knoll <knoll@kde.org>
- * Zack Rusin <zack@kde.org>
+ * Masayuki Nakano <masayuki@d-toybox.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 ***** */
-#ifndef NSWINDOWNG_H
-#define NSWINDOWNG_H
+
+#ifndef __nsWindow_h__
+#define __nsWindow_h__
+
+#include "nsAutoPtr.h"
#include "nsCommonWidget.h"
+
#include "nsWeakReference.h"
-#include "nsAutoPtr.h"
-class nsWindow : public nsCommonWidget,
- public nsSupportsWeakReference
+#include "nsIDragService.h"
+#include "nsITimer.h"
+#include "nsWidgetAtoms.h"
+
+#ifdef Q_WS_X11
+#include <QX11Info>
+#endif
+
+class nsWindow : public nsCommonWidget, public nsSupportsWeakReference
{
public:
nsWindow();
virtual ~nsWindow();
+ static void ReleaseGlobals();
NS_DECL_ISUPPORTS_INHERITED
+ // nsIWidget
+ NS_IMETHOD Create(nsIWidget *aParent,
+ const nsRect &aRect,
+ EVENT_CALLBACK aHandleEventFunction,
+ nsIDeviceContext *aContext,
+ nsIAppShell *aAppShell,
+ nsIToolkit *aToolkit,
+ nsWidgetInitData *aInitData);
+ NS_IMETHOD Create(nsNativeWidget aParent,
+ const nsRect &aRect,
+ EVENT_CALLBACK aHandleEventFunction,
+ nsIDeviceContext *aContext,
+ nsIAppShell *aAppShell,
+ nsIToolkit *aToolkit,
+ nsWidgetInitData *aInitData);
+ NS_IMETHOD Destroy(void);
+ NS_IMETHOD SetParent(nsIWidget* aNewParent);
+ NS_IMETHOD SetModal(PRBool aModal);
+ NS_IMETHOD IsVisible(PRBool & aState);
+ NS_IMETHOD ConstrainPosition(PRBool aAllowSlop,
+ PRInt32 *aX,
+ PRInt32 *aY);
+ NS_IMETHOD Move(PRInt32 aX,
+ PRInt32 aY);
+ NS_IMETHOD PlaceBehind(nsTopLevelWidgetZPlacement aPlacement,
+ nsIWidget *aWidget,
+ PRBool aActivate);
+ NS_IMETHOD SetZIndex(PRInt32 aZIndex);
+ NS_IMETHOD SetSizeMode(PRInt32 aMode);
+ NS_IMETHOD Enable(PRBool aState);
+ NS_IMETHOD SetFocus(PRBool aRaise = PR_FALSE);
+ NS_IMETHOD GetScreenBounds(nsRect &aRect);
+ NS_IMETHOD SetForegroundColor(const nscolor &aColor);
+ NS_IMETHOD SetBackgroundColor(const nscolor &aColor);
+ NS_IMETHOD SetCursor(nsCursor aCursor);
+ NS_IMETHOD SetCursor(imgIContainer* aCursor,
+ PRUint32 aHotspotX, PRUint32 aHotspotY);
+ NS_IMETHOD Validate();
+ NS_IMETHOD Invalidate(PRBool aIsSynchronous);
+ NS_IMETHOD Invalidate(const nsRect &aRect,
+ PRBool aIsSynchronous);
+ NS_IMETHOD InvalidateRegion(const nsIRegion *aRegion,
+ PRBool aIsSynchronous);
+ NS_IMETHOD Update();
+ NS_IMETHOD SetColorMap(nsColorMap *aColorMap);
+ NS_IMETHOD Scroll(PRInt32 aDx,
+ PRInt32 aDy,
+ nsRect *aClipRect);
+ NS_IMETHOD ScrollWidgets(PRInt32 aDx,
+ PRInt32 aDy);
+ NS_IMETHOD ScrollRect(nsRect &aSrcRect,
+ PRInt32 aDx,
+ PRInt32 aDy);
+ virtual void* GetNativeData(PRUint32 aDataType);
+ NS_IMETHOD SetBorderStyle(nsBorderStyle aBorderStyle);
+ NS_IMETHOD SetTitle(const nsAString& aTitle);
+ NS_IMETHOD SetIcon(const nsAString& aIconSpec);
+ NS_IMETHOD SetWindowClass(const nsAString& xulWinType);
+ NS_IMETHOD SetMenuBar(nsIMenuBar * aMenuBar);
+ NS_IMETHOD ShowMenuBar(PRBool aShow);
+ NS_IMETHOD WidgetToScreen(const nsRect& aOldRect,
+ nsRect& aNewRect);
+ NS_IMETHOD ScreenToWidget(const nsRect& aOldRect,
+ nsRect& aNewRect);
+ NS_IMETHOD BeginResizingChildren(void);
+ NS_IMETHOD EndResizingChildren(void);
+ NS_IMETHOD EnableDragDrop(PRBool aEnable);
+ virtual void ConvertToDeviceCoordinates(nscoord &aX,
+ nscoord &aY);
NS_IMETHOD PreCreateWidget(nsWidgetInitData *aWidgetInitData);
+ NS_IMETHOD CaptureMouse(PRBool aCapture);
+ NS_IMETHOD CaptureRollupEvents(nsIRollupListener *aListener,
+ PRBool aDoCapture,
+ PRBool aConsumeRollupEvent);
+ NS_IMETHOD GetAttention(PRInt32 aCycleCount);
+ NS_IMETHOD MakeFullScreen(PRBool aFullScreen);
+ NS_IMETHOD HideWindowChrome(PRBool aShouldHide);
- gfxASurface *GetThebesSurface();
+ // utility methods
+ void LoseFocus();
+ qint32 ConvertBorderStyles(nsBorderStyle aStyle);
protected:
- QWidget *createQWidget(QWidget *parent, nsWidgetInitData *aInitData);
+ /**
+ * Event handlers (proxied from the actual qwidget).
+ * They follow normal Qt widget semantics.
+ */
+ void Initialize(QWidget *widget);
+ friend class nsQtEventDispatcher;
+ friend class InterceptContainer;
+ friend class MozQWidget;
+
+ virtual bool OnExposeEvent(QPaintEvent *);
+ virtual bool OnConfigureEvent(QMoveEvent *);
+ virtual bool OnSizeAllocate(QResizeEvent *);
+ virtual bool OnDeleteEvent(QCloseEvent *);
+ virtual bool OnEnterNotifyEvent(QEvent *);
+ virtual bool OnLeaveNotifyEvent(QEvent *);
+ virtual bool OnMotionNotifyEvent(QMouseEvent *);
+ virtual bool OnButtonPressEvent(QMouseEvent *);
+ virtual bool OnButtonReleaseEvent(QMouseEvent *);
+ virtual bool mouseDoubleClickEvent(QMouseEvent *);
+ virtual bool OnContainerFocusInEvent(QFocusEvent *);
+ virtual bool OnContainerFocusOutEvent(QFocusEvent *);
+ virtual bool OnKeyPressEvent(QKeyEvent *);
+ virtual bool OnKeyReleaseEvent(QKeyEvent *);
+ virtual bool OnScrollEvent(QWheelEvent *);
+
+ virtual bool contextMenuEvent(QContextMenuEvent *);
+ virtual bool imStartEvent(QEvent *);
+ virtual bool imComposeEvent(QEvent *);
+ virtual bool imEndEvent(QEvent *);
+ virtual bool OnDragEnter (QDragEnterEvent *);
+ virtual bool OnDragMotionEvent(QDragMoveEvent *);
+ virtual bool OnDragLeaveEvent(QDragLeaveEvent *);
+ virtual bool OnDragDropEvent (QDropEvent *);
+ virtual bool showEvent(QShowEvent *);
+ virtual bool hideEvent(QHideEvent *);
+
+ bool OnWindowStateEvent(QEvent *aEvent);
+
+ nsresult NativeCreate(nsIWidget *aParent,
+ nsNativeWidget aNativeParent,
+ const nsRect &aRect,
+ EVENT_CALLBACK aHandleEventFunction,
+ nsIDeviceContext *aContext,
+ nsIAppShell *aAppShell,
+ nsIToolkit *aToolkit,
+ nsWidgetInitData *aInitData);
+
+ void NativeResize(PRInt32 aWidth,
+ PRInt32 aHeight,
+ PRBool aRepaint);
+
+ void NativeResize(PRInt32 aX,
+ PRInt32 aY,
+ PRInt32 aWidth,
+ PRInt32 aHeight,
+ PRBool aRepaint);
+
+ void NativeShow (PRBool aAction);
+
+ void EnsureGrabs (void);
+ void GrabKeyboard (void);
+ void ReleaseGrabs (void);
+ void GrabPointer(void);
+
+ enum PluginType {
+ PluginType_NONE = 0, /* do not have any plugin */
+ PluginType_XEMBED, /* the plugin support xembed */
+ PluginType_NONXEMBED /* the plugin does not support xembed */
+ };
+
+ void SetPluginType(PluginType aPluginType);
+ void SetNonXEmbedPluginFocus(void);
+ void LoseNonXEmbedPluginFocus(void);
+
+ void ThemeChanged(void);
+
+ NS_IMETHOD BeginResizeDrag (nsGUIEvent* aEvent, PRInt32 aHorizontal, PRInt32 aVertical);
+
+ void ResizeTransparencyBitmap(PRInt32 aNewWidth, PRInt32 aNewHeight);
+ void ApplyTransparencyBitmap();
+ NS_IMETHOD SetHasTransparentBackground(PRBool aTransparent);
+ NS_IMETHOD GetHasTransparentBackground(PRBool& aTransparent);
+ nsresult UpdateTranslucentWindowAlphaInternal(const nsRect& aRect,
+ PRUint8* aAlphas, PRInt32 aStride);
+
+ gfxASurface *GetThebesSurface();
+
+private:
+ void GetToplevelWidget(QWidget **aWidget);
+ void SetUrgencyHint(QWidget *top_window, PRBool state);
+ void *SetupPluginPort(void);
+ nsresult SetWindowIconList(const nsCStringArray &aIconList);
+ void SetDefaultIcon(void);
+ void InitButtonEvent(nsMouseEvent &aEvent, QMouseEvent *aEvent, int aClickCount = 1);
+ PRBool DispatchCommandEvent(nsIAtom* aCommand);
+ QWidget *createQWidget(QWidget *parent, nsWidgetInitData *aInitData);
+
+ QWidget *mDrawingarea;
+
+ PRUint32 mIsVisible : 1,
+ mRetryPointerGrab : 1,
+ mActivatePending : 1,
+ mRetryKeyboardGrab : 1;
+ PRInt32 mSizeState;
+ PluginType mPluginType;
+
+ PRInt32 mTransparencyBitmapWidth;
+ PRInt32 mTransparencyBitmapHeight;
+
nsRefPtr<gfxASurface> mThebesSurface;
+
+ // Transparency
+ PRBool mIsTransparent;
+ // This bitmap tracks which pixels are transparent. We don't support
+ // full translucency at this time; each pixel is either fully opaque
+ // or fully transparent.
+ char* mTransparencyBitmap;
+
+ // all of our DND stuff
+ // this is the last window that had a drag event happen on it.
+ void InitDragEvent (nsMouseEvent &aEvent);
+
+ // this is everything we need to be able to fire motion events
+ // repeatedly
+ PRUint32 mKeyDownFlags[8];
+
+ /* Helper methods for DOM Key Down event suppression. */
+ PRUint32* GetFlagWord32(PRUint32 aKeyCode, PRUint32* aMask) {
+ /* Mozilla DOM Virtual Key Code is from 0 to 224. */
+ NS_ASSERTION((aKeyCode <= 0xFF), "Invalid DOM Key Code");
+ aKeyCode &= 0xFF;
+
+ /* 32 = 2^5 = 0x20 */
+ *aMask = PRUint32(1) << (aKeyCode & 0x1F);
+ return &mKeyDownFlags[(aKeyCode >> 5)];
+ }
+
+ PRBool IsKeyDown(PRUint32 aKeyCode) {
+ PRUint32 mask;
+ PRUint32* flag = GetFlagWord32(aKeyCode, &mask);
+ return ((*flag) & mask) != 0;
+ }
+
+ void SetKeyDownFlag(PRUint32 aKeyCode) {
+ PRUint32 mask;
+ PRUint32* flag = GetFlagWord32(aKeyCode, &mask);
+ *flag |= mask;
+ }
+
+ void ClearKeyDownFlag(PRUint32 aKeyCode) {
+ PRUint32 mask;
+ PRUint32* flag = GetFlagWord32(aKeyCode, &mask);
+ *flag &= ~mask;
+ }
+ PRInt32 mQCursor;
+
};
-class ChildWindow : public nsWindow
+class nsChildWindow : public nsWindow
{
public:
- ChildWindow();
- ~ChildWindow();
- virtual PRBool IsChild() const;
+ nsChildWindow();
+ ~nsChildWindow();
PRInt32 mChildID;
};
-class PopupWindow : public nsWindow
+class nsPopupWindow : public nsWindow
{
public:
- PopupWindow();
- ~PopupWindow();
+ nsPopupWindow ();
+ ~nsPopupWindow ();
PRInt32 mChildID;
};
+#endif /* __nsWindow_h__ */
-#endif