1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* vim:expandtab:shiftwidth=4:tabstop=4:
4 /* This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 #include "mozilla/ArrayUtils.h"
9 #include "mozilla/MiscEvents.h"
10 #include "mozilla/MouseEvents.h"
11 #include "mozilla/TextEvents.h"
12 #include "mozilla/TouchEvents.h"
14 #include <QGuiApplication>
15 #include <QtGui/QCursor>
17 #include <QMouseEvent>
18 #include <QWheelEvent>
19 #include <QResizeEvent>
20 #include <QPaintEngine>
24 #include <QtCore/QDebug>
25 #include <QtCore/QEvent>
26 #include <QtCore/QVariant>
31 #include <X11/Xutil.h>
32 #include "gfxXlibSurface.h"
35 #include "nsXULAppAPI.h"
40 #include "mozqwidget.h"
42 #include "nsIdleService.h"
43 #include "nsIRollupListener.h"
44 #include "nsWidgetsCID.h"
45 #include "nsQtKeyUtils.h"
46 #include "mozilla/Services.h"
47 #include "mozilla/Preferences.h"
48 #include "mozilla/Likely.h"
49 #include "mozilla/layers/LayersTypes.h"
50 #include "nsIWidgetListener.h"
51 #include "ClientLayerManager.h"
52 #include "BasicLayers.h"
54 #include "nsIStringBundle.h"
55 #include "nsGfxCIID.h"
57 #include "imgIContainer.h"
58 #include "nsGfxCIID.h"
59 #include "nsIInterfaceRequestorUtils.h"
60 #include "nsAutoPtr.h"
62 #include "gfxQtPlatform.h"
64 #include "nsIDOMWheelEvent.h"
66 #include "GLContext.h"
69 #include "keysym2ucs.h"
73 #include "GLContextProvider.h"
75 using namespace mozilla
;
76 using namespace mozilla::gl
;
77 using namespace mozilla::widget
;
78 using namespace mozilla::gfx
;
79 using namespace mozilla::layers
;
80 using mozilla::gl::GLContext
;
82 #define kWindowPositionSlop 20
85 static const int WHEEL_DELTA
= 120;
86 static bool gGlobalsInitialized
= false;
87 static bool sAltGrModifier
= false;
89 static void find_first_visible_parent(QWindow
* aItem
, QWindow
*& aVisibleItem
);
90 static bool is_mouse_in_window (MozQWidget
* aWindow
, double aMouseX
, double aMouseY
);
94 LOG(("%s [%p]\n", __PRETTY_FUNCTION__
, (void *)this));
102 mActivatePending
= false;
103 mWindowType
= eWindowType_child
;
104 mSizeState
= nsSizeMode_Normal
;
105 mLastSizeMode
= nsSizeMode_Normal
;
106 mQCursor
= Qt::ArrowCursor
;
107 mNeedsResize
= false;
109 mListenForResizes
= false;
111 mTimerStarted
= false;
112 mMoveEvent
.needDispatch
= false;
114 if (!gGlobalsInitialized
) {
115 gfxPlatform::GetPlatform();
116 gGlobalsInitialized
= true;
119 memset(mKeyDownFlags
, 0, sizeof(mKeyDownFlags
));
121 mIsTransparent
= false;
123 mCursor
= eCursor_standard
;
126 nsWindow::~nsWindow()
128 LOG(("%s [%p]\n", __PRETTY_FUNCTION__
, (void *)this));
134 nsWindow::Create(nsIWidget
*aParent
,
135 nsNativeWidget aNativeParent
,
136 const nsIntRect
&aRect
,
137 nsDeviceContext
*aContext
,
138 nsWidgetInitData
*aInitData
)
140 // only set the base parent if we're not going to be a dialog or a
142 nsIWidget
*baseParent
= aParent
;
144 // initialize all the common bits of this class
145 BaseCreate(baseParent
, aRect
, aContext
, aInitData
);
149 // and do our common creation
150 mParent
= (nsWindow
*)aParent
;
155 // find native parent
156 MozQWidget
*parent
= nullptr;
158 if (aParent
!= nullptr) {
159 parent
= static_cast<MozQWidget
*>(aParent
->GetNativeData(NS_NATIVE_WIDGET
));
160 } else if (aNativeParent
!= nullptr) {
161 parent
= static_cast<MozQWidget
*>(aNativeParent
);
162 if (parent
&& mParent
== nullptr) {
163 mParent
= parent
->getReceiver();
167 LOG(("Create: nsWindow [%p] mWidget:[%p] parent:[%p], natPar:[%p] mParent:%p\n", (void *)this, (void*)mWidget
, parent
, aNativeParent
, mParent
));
169 // ok, create our QGraphicsWidget
170 mWidget
= createQWidget(parent
, aInitData
);
173 return NS_ERROR_OUT_OF_MEMORY
;
177 // resize so that everything is set to the right dimensions
178 Resize(mBounds
.x
, mBounds
.y
, mBounds
.width
, mBounds
.height
, false);
180 // check if we should listen for resizes
181 mListenForResizes
= (aNativeParent
||
182 (aInitData
&& aInitData
->mListenForResizes
));
188 nsWindow::createQWidget(MozQWidget
* parent
,
189 nsWidgetInitData
* aInitData
)
191 const char *windowName
= nullptr;
192 Qt::WindowFlags flags
= Qt::Widget
;
194 // ok, create our windows
195 switch (mWindowType
) {
196 case eWindowType_dialog
:
197 windowName
= "topLevelDialog";
200 case eWindowType_popup
:
201 windowName
= "topLevelPopup";
204 case eWindowType_toplevel
:
205 windowName
= "topLevelWindow";
208 case eWindowType_invisible
:
209 windowName
= "topLevelInvisible";
211 case eWindowType_child
:
212 case eWindowType_plugin
:
214 windowName
= "paintArea";
218 MozQWidget
* widget
= new MozQWidget(this, parent
);
223 widget
->setObjectName(QString(windowName
));
224 if (mWindowType
== eWindowType_invisible
) {
225 #if (QT_VERSION >= QT_VERSION_CHECK(5, 1, 0))
226 widget
->setVisibility(QWindow::Hidden
);
231 if (mWindowType
== eWindowType_dialog
) {
232 widget
->setModality(Qt::WindowModal
);
237 // create a QGraphicsView if this is a new toplevel window
238 LOG(("nsWindow::%s [%p] Created Window: %s, widget:%p, par:%p\n", __FUNCTION__
, (void *)this, windowName
, widget
, parent
));
244 nsWindow::Destroy(void)
246 if (mIsDestroyed
|| !mWidget
) {
250 LOG(("nsWindow::Destroy [%p]\n", (void *)this));
253 /** Need to clean our LayerManager up while still alive */
255 mLayerManager
->Destroy();
257 mLayerManager
= nullptr;
259 // It is safe to call DestroyeCompositor several times (here and
260 // in the parent class) since it will take effect only once.
261 // The reason we call it here is because on gtk platforms we need
262 // to destroy the compositor before we destroy the gdk window (which
263 // destroys the the gl context attached to it).
266 ClearCachedResources();
268 nsIRollupListener
* rollupListener
= nsBaseWidget::GetActiveRollupListener();
269 if (rollupListener
) {
270 nsCOMPtr
<nsIWidget
> rollupWidget
= rollupListener
->GetRollupWidget();
271 if (static_cast<nsIWidget
*>(this) == rollupWidget
) {
272 rollupListener
->Rollup(0, nullptr, nullptr);
278 // walk the list of children and call destroy on them. Have to be
279 // careful, though -- calling destroy on a kid may actually remove
280 // it from our child list, losing its sibling links.
281 for (nsIWidget
* kid
= mFirstChild
; kid
; ) {
282 nsIWidget
* next
= kid
->GetNextSibling();
287 // Destroy thebes surface now. Badness can happen if we destroy
288 // the surface after its X Window.
290 mWidget
->dropReceiver();
292 // Call deleteLater instead of delete; Qt still needs the object
293 // to be valid even after sending it a Close event. We could
294 // also set WA_DeleteOnClose, but this gives us more control.
295 mWidget
->deleteLater();
305 nsWindow::Show(bool aState
)
307 LOG(("nsWindow::Show [%p] state %d\n", (void *)this, aState
));
308 if (aState
== mIsShown
) {
312 // Clear our cached resources when the window is hidden.
313 if (mIsShown
&& !aState
) {
314 ClearCachedResources();
319 if ((aState
&& !AreBoundsSane()) || !mWidget
) {
320 LOG(("\tbounds are insane or window hasn't been created yet\n"));
327 NativeResize(mBounds
.x
, mBounds
.y
, mBounds
.width
, mBounds
.height
,
329 } else if (mNeedsResize
) {
330 NativeResize(mBounds
.width
, mBounds
.height
, false);
334 // If someone is hiding this widget, clear any needing show flag.
344 nsWindow::IsVisible() const
350 nsWindow::ConstrainPosition(bool aAllowSlop
, int32_t *aX
, int32_t *aY
)
353 return NS_ERROR_FAILURE
;
356 int32_t screenWidth
= qApp
->primaryScreen()->size().width();
357 int32_t screenHeight
= qApp
->primaryScreen()->size().height();
360 if (*aX
< (kWindowPositionSlop
- mBounds
.width
))
361 *aX
= kWindowPositionSlop
- mBounds
.width
;
362 if (*aX
> (screenWidth
- kWindowPositionSlop
))
363 *aX
= screenWidth
- kWindowPositionSlop
;
364 if (*aY
< (kWindowPositionSlop
- mBounds
.height
))
365 *aY
= kWindowPositionSlop
- mBounds
.height
;
366 if (*aY
> (screenHeight
- kWindowPositionSlop
))
367 *aY
= screenHeight
- kWindowPositionSlop
;
371 if (*aX
> (screenWidth
- mBounds
.width
))
372 *aX
= screenWidth
- mBounds
.width
;
375 if (*aY
> (screenHeight
- mBounds
.height
))
376 *aY
= screenHeight
- mBounds
.height
;
383 nsWindow::Move(double aX
, double aY
)
385 LOG(("nsWindow::Move [%p] %f %f\n", (void *)this,
388 int32_t x
= NSToIntRound(aX
);
389 int32_t y
= NSToIntRound(aY
);
392 SetSizeMode(nsSizeMode_Normal
);
395 if (x
== mBounds
.x
&& y
== mBounds
.y
) {
404 mWidget
->setPosition(x
, y
);
407 // the position of the widget is set relative to the parent
408 // so we map the coordinates accordingly
409 pos
= mWidget
->mapToGlobal(pos
);
410 mWidget
->setPosition(pos
);
416 NotifyRollupGeometryChange();
421 nsWindow::Resize(double aWidth
, double aHeight
, bool aRepaint
)
423 mBounds
.width
= NSToIntRound(aWidth
);
424 mBounds
.height
= NSToIntRound(aHeight
);
430 if (AreBoundsSane()) {
431 if (mIsTopLevel
|| mNeedsShow
)
432 NativeResize(mBounds
.x
, mBounds
.y
,
433 mBounds
.width
, mBounds
.height
, aRepaint
);
435 NativeResize(mBounds
.width
, mBounds
.height
, aRepaint
);
437 // Does it need to be shown because it was previously insane?
443 // If someone has set this so that the needs show flag is false
444 // and it needs to be hidden, update the flag and hide the
445 // window. This flag will be cleared the next time someone
446 // hides the window or shows it. It also prevents us from
447 // calling NativeShow(false) excessively on the window which
448 // causes unneeded X traffic.
455 else if (AreBoundsSane() && mListenForResizes
) {
456 // For widgets that we listen for resizes for (widgets created
457 // with native parents) we apparently _always_ have to resize. I
458 // dunno why, but apparently we're lame like that.
459 NativeResize(mBounds
.width
, mBounds
.height
, aRepaint
);
465 // synthesize a resize event if this isn't a toplevel
466 if (mIsTopLevel
|| mListenForResizes
) {
467 nsEventStatus status
;
468 DispatchResizeEvent(mBounds
, status
);
471 NotifyRollupGeometryChange();
476 nsWindow::Resize(double aX
, double aY
, double aWidth
, double aHeight
,
479 mBounds
.x
= NSToIntRound(aX
);
480 mBounds
.y
= NSToIntRound(aY
);
481 mBounds
.width
= NSToIntRound(aWidth
);
482 mBounds
.height
= NSToIntRound(aHeight
);
490 // Has this widget been set to visible?
492 // Are the bounds sane?
493 if (AreBoundsSane()) {
494 // Yep? Resize the window
495 NativeResize(mBounds
.x
, mBounds
.y
, mBounds
.width
, mBounds
.height
,
497 // Does it need to be shown because it was previously insane?
502 // If someone has set this so that the needs show flag is false
503 // and it needs to be hidden, update the flag and hide the
504 // window. This flag will be cleared the next time someone
505 // hides the window or shows it. It also prevents us from
506 // calling NativeShow(false) excessively on the window which
507 // causes unneeded X traffic.
514 // If the widget hasn't been shown, mark the widget as needing to be
515 // resized before it is shown
516 else if (AreBoundsSane() && mListenForResizes
) {
517 // For widgets that we listen for resizes for (widgets created
518 // with native parents) we apparently _always_ have to resize. I
519 // dunno why, but apparently we're lame like that.
520 NativeResize(mBounds
.x
, mBounds
.y
, mBounds
.width
, mBounds
.height
,
528 if (mIsTopLevel
|| mListenForResizes
) {
529 // synthesize a resize event
530 nsEventStatus status
;
531 DispatchResizeEvent(mBounds
, status
);
535 mWidget
->renderLater();
538 NotifyRollupGeometryChange();
543 nsWindow::Enable(bool aState
)
551 nsWindow::IsEnabled() const
557 nsWindow::SetFocus(bool aRaise
)
559 // Make sure that our owning widget has focus. If it doesn't try to
560 // grab it. Note that we don't set our focus flag in this case.
561 LOGFOCUS((" SetFocus [%p]\n", (void *)this));
564 return NS_ERROR_FAILURE
;
567 if (mWidget
->focusObject()) {
571 // Because QGraphicsItem cannot get the focus if they are
572 // invisible, we look up the chain, for the lowest visible
573 // parent and focus that one
574 QWindow
* realFocusItem
= nullptr;
575 find_first_visible_parent(mWidget
, realFocusItem
);
577 if (!realFocusItem
|| realFocusItem
->focusObject()) {
581 if (aRaise
&& mWidget
) {
582 // the raising has to happen on the view widget
586 // XXXndeakin why is this here? It should dispatch only when the OS
588 DispatchActivateEvent();
594 nsWindow::ConfigureChildren(const nsTArray
<nsIWidget::Configuration
>& aConfigurations
)
596 for (uint32_t i
= 0; i
< aConfigurations
.Length(); ++i
) {
597 const Configuration
& configuration
= aConfigurations
[i
];
599 nsWindow
* w
= static_cast<nsWindow
*>(configuration
.mChild
);
600 NS_ASSERTION(w
->GetParent() == this,
601 "Configured widget is not a child");
603 if (w
->mBounds
.Size() != configuration
.mBounds
.Size()) {
604 w
->Resize(configuration
.mBounds
.x
, configuration
.mBounds
.y
,
605 configuration
.mBounds
.width
, configuration
.mBounds
.height
,
607 } else if (w
->mBounds
.TopLeft() != configuration
.mBounds
.TopLeft()) {
608 w
->Move(configuration
.mBounds
.x
, configuration
.mBounds
.y
);
615 nsWindow::Invalidate(const nsIntRect
&aRect
)
617 LOGDRAW(("Invalidate (rect) [%p,%p]: %d %d %d %d\n", (void *)this,
618 (void*)mWidget
,aRect
.x
, aRect
.y
, aRect
.width
, aRect
.height
));
624 mWidget
->renderLater();
630 nsWindow::WidgetToScreenOffset()
632 NS_ENSURE_TRUE(mWidget
, nsIntPoint(0,0));
635 origin
= mWidget
->mapToGlobal(origin
);
637 return nsIntPoint(origin
.x(), origin
.y());
641 nsWindow::GetNativeData(uint32_t aDataType
)
644 case NS_NATIVE_WINDOW
:
645 case NS_NATIVE_WIDGET
: {
648 case NS_NATIVE_SHAREABLE_WINDOW
: {
649 return mWidget
? (void*)mWidget
->winId() : nullptr;
651 case NS_NATIVE_DISPLAY
: {
653 return gfxQtPlatform::GetXDisplay(mWidget
);
657 case NS_NATIVE_PLUGIN_PORT
:
658 case NS_NATIVE_GRAPHIC
:
659 case NS_NATIVE_SHELLWIDGET
: {
663 NS_WARNING("nsWindow::GetNativeData called with bad value");
666 LOG(("nsWindow::%s [%p] aDataType:%i\n", __FUNCTION__
, (void *)this, aDataType
));
671 nsWindow::DispatchEvent(WidgetGUIEvent
* aEvent
, nsEventStatus
& aStatus
)
674 debug_DumpEvent(stdout
, aEvent
->widget
, aEvent
,
675 nsAutoCString("something"), 0);
678 aStatus
= nsEventStatus_eIgnore
;
680 // send it to the standard callback
681 if (mWidgetListener
) {
682 aStatus
= mWidgetListener
->HandleEvent(aEvent
, mUseAttachedEvents
);
689 nsWindow::SetInputContext(const InputContext
& aContext
,
690 const InputContextAction
& aAction
)
692 NS_ENSURE_TRUE_VOID(mWidget
);
694 // SetSoftwareKeyboardState uses mInputContext,
695 // so, before calling that, record aContext in mInputContext.
696 mInputContext
= aContext
;
698 switch (mInputContext
.mIMEState
.mEnabled
) {
699 case IMEState::ENABLED
:
700 case IMEState::PASSWORD
:
701 case IMEState::PLUGIN
:
702 SetSoftwareKeyboardState(true, aAction
);
705 SetSoftwareKeyboardState(false, aAction
);
710 NS_IMETHODIMP_(InputContext
)
711 nsWindow::GetInputContext()
713 mInputContext
.mIMEState
.mOpen
= IMEState::OPEN_STATE_NOT_SUPPORTED
;
714 // Our qt widget looks like using only one context per process.
715 // However, it's better to set the context's pointer.
716 mInputContext
.mNativeIMEContext
= qApp
->inputMethod();
718 return mInputContext
;
722 nsWindow::ReparentNativeWidget(nsIWidget
*aNewParent
)
724 NS_PRECONDITION(aNewParent
, "");
726 MozQWidget
* newParent
= static_cast<MozQWidget
*>(aNewParent
->GetNativeData(NS_NATIVE_WINDOW
));
727 NS_ASSERTION(newParent
, "Parent widget has a null native window handle");
729 mWidget
->setParent(newParent
);
735 nsWindow::MakeFullScreen(bool aFullScreen
)
737 NS_ENSURE_TRUE(mWidget
, NS_ERROR_FAILURE
);
740 if (mSizeMode
!= nsSizeMode_Fullscreen
) {
741 mLastSizeMode
= mSizeMode
;
744 mSizeMode
= nsSizeMode_Fullscreen
;
745 mWidget
->showFullScreen();
748 mSizeMode
= mLastSizeMode
;
751 case nsSizeMode_Maximized
:
752 mWidget
->showMaximized();
754 case nsSizeMode_Minimized
:
755 mWidget
->showMinimized();
757 case nsSizeMode_Normal
:
758 mWidget
->showNormal();
761 mWidget
->showNormal();
766 NS_ASSERTION(mLastSizeMode
!= nsSizeMode_Fullscreen
,
767 "mLastSizeMode should never be fullscreen");
768 return nsBaseWidget::MakeFullScreen(aFullScreen
);
772 nsWindow::GetLayerManager(PLayerTransactionChild
* aShadowManager
,
773 LayersBackend aBackendHint
,
774 LayerManagerPersistence aPersistence
,
775 bool* aAllowRetaining
)
777 if (!mLayerManager
&& eTransparencyTransparent
== GetTransparencyMode()) {
778 mLayerManager
= CreateBasicLayerManager();
781 return nsBaseWidget::GetLayerManager(aShadowManager
, aBackendHint
,
782 aPersistence
, aAllowRetaining
);
786 nsWindow::UserActivity()
789 mIdleService
= do_GetService("@mozilla.org/widget/idleservice;1");
793 mIdleService
->ResetIdleTimeOut(0);
798 nsWindow::GetGLFrameBufferFormat()
801 mLayerManager
->GetBackendType() == mozilla::layers::LayersBackend::LAYERS_OPENGL
) {
804 return LOCAL_GL_NONE
;
807 TemporaryRef
<DrawTarget
>
808 nsWindow::StartRemoteDrawing()
815 Display
* dpy
= gfxQtPlatform::GetXDisplay(mWidget
);
816 Screen
* screen
= DefaultScreenOfDisplay(dpy
);
817 Visual
* defaultVisual
= DefaultVisualOfScreen(screen
);
818 gfxASurface
* surf
= new gfxXlibSurface(dpy
, mWidget
->winId(), defaultVisual
,
819 gfxIntSize(mWidget
->width(),
822 IntSize
size(surf
->GetSize().width
, surf
->GetSize().height
);
823 if (size
.width
<= 0 || size
.height
<= 0) {
827 return gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(surf
, size
);
834 nsWindow::SetCursor(nsCursor aCursor
)
836 if (mCursor
== aCursor
&& !mUpdateCursor
) {
839 mUpdateCursor
= false;
842 mWidget
->SetCursor(mCursor
);
848 nsWindow::SetTitle(const nsAString
& aTitle
)
850 QString
qStr(QString::fromUtf16((const ushort
*)aTitle
.BeginReading(), aTitle
.Length()));
852 mWidget
->setTitle(qStr
);
862 LOGDRAW(("nsWindow::%s [%p]\n", __FUNCTION__
, (void *)this));
863 nsIWidgetListener
* listener
=
864 mAttachedWidgetListener
? mAttachedWidgetListener
: mWidgetListener
;
869 listener
->WillPaintWindow(this);
871 switch (GetLayerManager()->GetBackendType()) {
872 case mozilla::layers::LayersBackend::LAYERS_CLIENT
: {
873 nsIntRegion
region(nsIntRect(0, 0, mWidget
->width(), mWidget
->height()));
874 listener
->PaintWindow(this, region
);
878 NS_ERROR("Invalid layer manager");
881 listener
->DidPaintWindow();
885 nsWindow::moveEvent(QMoveEvent
* aEvent
)
887 LOG(("configure event [%p] %d %d\n", (void *)this,
888 aEvent
->pos().x(), aEvent
->pos().y()));
891 if (!mWidget
|| !mWidgetListener
)
892 return nsEventStatus_eIgnore
;
894 if ((mBounds
.x
== aEvent
->pos().x() &&
895 mBounds
.y
== aEvent
->pos().y()))
897 return nsEventStatus_eIgnore
;
900 NotifyWindowMoved(aEvent
->pos().x(), aEvent
->pos().y());
901 return nsEventStatus_eConsumeNoDefault
;
905 nsWindow::resizeEvent(QResizeEvent
* aEvent
)
909 // Generate XPFE resize event
912 rect
.width
= aEvent
->size().width();
913 rect
.height
= aEvent
->size().height();
915 mBounds
.width
= rect
.width
;
916 mBounds
.height
= rect
.height
;
918 nsEventStatus status
;
919 DispatchResizeEvent(rect
, status
);
924 nsWindow::mouseMoveEvent(QMouseEvent
* aEvent
)
928 mMoveEvent
.pos
= aEvent
->pos();
929 mMoveEvent
.modifiers
= aEvent
->modifiers();
930 mMoveEvent
.needDispatch
= true;
931 DispatchMotionToMainThread();
933 return nsEventStatus_eIgnore
;
937 InitMouseEvent(WidgetMouseEvent
& aMouseEvent
, QMouseEvent
* aEvent
,
940 aMouseEvent
.refPoint
.x
= nscoord(aEvent
->pos().x());
941 aMouseEvent
.refPoint
.y
= nscoord(aEvent
->pos().y());
943 aMouseEvent
.InitBasicModifiers(aEvent
->modifiers() & Qt::ControlModifier
,
944 aEvent
->modifiers() & Qt::AltModifier
,
945 aEvent
->modifiers() & Qt::ShiftModifier
,
946 aEvent
->modifiers() & Qt::MetaModifier
);
947 aMouseEvent
.clickCount
= aClickCount
;
949 switch (aEvent
->button()) {
951 aMouseEvent
.button
= WidgetMouseEvent::eLeftButton
;
953 case Qt::RightButton
:
954 aMouseEvent
.button
= WidgetMouseEvent::eRightButton
;
956 case Qt::MiddleButton
:
957 aMouseEvent
.button
= WidgetMouseEvent::eMiddleButton
;
965 IsAcceptedButton(Qt::MouseButton button
)
969 case Qt::RightButton
:
970 case Qt::MiddleButton
:
978 nsWindow::mousePressEvent(QMouseEvent
* aEvent
)
980 // The user has done something.
983 QPoint pos
= aEvent
->pos();
985 // we check against the widgets geometry, so use parent coordinates
988 pos
= mWidget
->mapToGlobal(pos
);
990 if (CheckForRollup(pos
.x(), pos
.y(), false))
991 return nsEventStatus_eIgnore
;
993 if (!IsAcceptedButton(aEvent
->button())) {
994 if (aEvent
->button() == Qt::BackButton
)
995 return DispatchCommandEvent(nsGkAtoms::Back
);
996 if (aEvent
->button() == Qt::ForwardButton
)
997 return DispatchCommandEvent(nsGkAtoms::Forward
);
998 return nsEventStatus_eIgnore
;
1001 WidgetMouseEvent
event(true, NS_MOUSE_BUTTON_DOWN
, this,
1002 WidgetMouseEvent::eReal
);
1003 InitMouseEvent(event
, aEvent
, 1);
1004 nsEventStatus status
= DispatchEvent(&event
);
1006 // Right click on linux should also pop up a context menu.
1007 if (event
.button
== WidgetMouseEvent::eRightButton
&&
1008 MOZ_LIKELY(!mIsDestroyed
)) {
1009 WidgetMouseEvent
contextMenuEvent(true, NS_CONTEXTMENU
, this,
1010 WidgetMouseEvent::eReal
);
1011 InitMouseEvent(contextMenuEvent
, aEvent
, 1);
1012 DispatchEvent(&contextMenuEvent
, status
);
1019 nsWindow::mouseReleaseEvent(QMouseEvent
* aEvent
)
1021 // The user has done something.
1024 if (!IsAcceptedButton(aEvent
->button()))
1025 return nsEventStatus_eIgnore
;
1027 WidgetMouseEvent
event(true, NS_MOUSE_BUTTON_UP
, this,
1028 WidgetMouseEvent::eReal
);
1029 InitMouseEvent(event
, aEvent
, 1);
1030 return DispatchEvent(&event
);
1034 nsWindow::mouseDoubleClickEvent(QMouseEvent
* aEvent
)
1036 // The user has done something.
1039 if (!IsAcceptedButton(aEvent
->button()))
1040 return nsEventStatus_eIgnore
;
1042 WidgetMouseEvent
event(true, NS_MOUSE_DOUBLECLICK
, this,
1043 WidgetMouseEvent::eReal
);
1044 InitMouseEvent(event
, aEvent
, 2);
1045 return DispatchEvent(&event
);
1049 nsWindow::focusInEvent(QFocusEvent
* aEvent
)
1051 LOGFOCUS(("OnFocusInEvent [%p]\n", (void *)this));
1054 return nsEventStatus_eIgnore
;
1057 DispatchActivateEventOnTopLevelWindow();
1059 LOGFOCUS(("Events sent from focus in event [%p]\n", (void *)this));
1060 return nsEventStatus_eIgnore
;
1064 nsWindow::focusOutEvent(QFocusEvent
* aEvent
)
1066 LOGFOCUS(("OnFocusOutEvent [%p]\n", (void *)this));
1069 return nsEventStatus_eIgnore
;
1072 DispatchDeactivateEventOnTopLevelWindow();
1074 LOGFOCUS(("Done with container focus out [%p]\n", (void *)this));
1075 return nsEventStatus_eIgnore
;
1079 IsContextMenuKeyEvent(const QKeyEvent
* aQEvent
)
1081 if (aQEvent
->modifiers() & (Qt::ControlModifier
|
1083 Qt::MetaModifier
)) {
1087 bool isShift
= aQEvent
->modifiers() & Qt::ShiftModifier
;
1088 uint32_t keyCode
= QtKeyCodeToDOMKeyCode(aQEvent
->key());
1089 return (keyCode
== NS_VK_F10
&& isShift
) ||
1090 (keyCode
== NS_VK_CONTEXT_MENU
&& !isShift
);
1094 InitKeyEvent(WidgetKeyboardEvent
& aEvent
, QKeyEvent
* aQEvent
)
1096 aEvent
.InitBasicModifiers(aQEvent
->modifiers() & Qt::ControlModifier
,
1097 aQEvent
->modifiers() & Qt::AltModifier
,
1098 aQEvent
->modifiers() & Qt::ShiftModifier
,
1099 aQEvent
->modifiers() & Qt::MetaModifier
);
1102 (aEvent
.message
== NS_KEY_DOWN
|| aEvent
.message
== NS_KEY_PRESS
) &&
1103 aQEvent
->isAutoRepeat();
1106 if (sAltGrModifier
) {
1107 aEvent
.modifiers
|= (MODIFIER_CONTROL
| MODIFIER_ALT
);
1110 if (aQEvent
->text().length() && aQEvent
->text()[0].isPrint()) {
1111 aEvent
.charCode
= (int32_t) aQEvent
->text()[0].unicode();
1113 aEvent
.mKeyNameIndex
= KEY_NAME_INDEX_PrintableKey
;
1115 aEvent
.charCode
= 0;
1116 aEvent
.keyCode
= QtKeyCodeToDOMKeyCode(aQEvent
->key());
1117 aEvent
.mKeyNameIndex
= QtKeyCodeToDOMKeyNameIndex(aQEvent
->key());
1120 aEvent
.mCodeNameIndex
= ScanCodeToDOMCodeNameIndex(aQEvent
->nativeScanCode());
1122 // The transformations above and in qt for the keyval are not invertible
1123 // so link to the QKeyEvent (which will vanish soon after return from the
1124 // event callback) to give plugins access to hardware_keycode and state.
1125 // (An XEvent would be nice but the QKeyEvent is good enough.)
1126 aEvent
.mPluginEvent
.Copy(*aQEvent
);
1130 nsWindow::keyPressEvent(QKeyEvent
* aEvent
)
1132 LOGFOCUS(("OnKeyPressEvent [%p]\n", (void *)this));
1134 // The user has done something.
1137 if (aEvent
->key() == Qt::Key_AltGr
) {
1138 sAltGrModifier
= true;
1141 // Before we dispatch a key, check if it's the context menu key.
1142 // If so, send a context menu key event instead.
1143 if (IsContextMenuKeyEvent(aEvent
)) {
1144 WidgetMouseEvent
contextMenuEvent(true, NS_CONTEXTMENU
, this,
1145 WidgetMouseEvent::eReal
,
1146 WidgetMouseEvent::eContextMenuKey
);
1147 return DispatchEvent(&contextMenuEvent
);
1150 //:TODO: fix shortcuts hebrew for non X11,
1151 //see Bug 562195##51
1153 uint32_t domKeyCode
= QtKeyCodeToDOMKeyCode(aEvent
->key());
1155 if (!aEvent
->isAutoRepeat() && !IsKeyDown(domKeyCode
)) {
1156 SetKeyDownFlag(domKeyCode
);
1158 WidgetKeyboardEvent
downEvent(true, NS_KEY_DOWN
, this);
1159 InitKeyEvent(downEvent
, aEvent
);
1161 nsEventStatus status
= DispatchEvent(&downEvent
);
1163 // DispatchEvent can Destroy us (bug 378273)
1164 if (MOZ_UNLIKELY(mIsDestroyed
)) {
1165 qWarning() << "Returning[" << __LINE__
<< "]: " << "Window destroyed";
1169 // If prevent default on keydown, don't dispatch keypress event
1170 if (status
== nsEventStatus_eConsumeNoDefault
) {
1171 return nsEventStatus_eConsumeNoDefault
;
1175 // Don't pass modifiers as NS_KEY_PRESS events.
1176 // Instead of selectively excluding some keys from NS_KEY_PRESS events,
1177 // we instead selectively include (as per MSDN spec
1178 // ( http://msdn.microsoft.com/en-us/library/system.windows.forms.control.keypress%28VS.71%29.aspx );
1179 // no official spec covers KeyPress events).
1180 if (aEvent
->key() == Qt::Key_Shift
||
1181 aEvent
->key() == Qt::Key_Control
||
1182 aEvent
->key() == Qt::Key_Meta
||
1183 aEvent
->key() == Qt::Key_Alt
||
1184 aEvent
->key() == Qt::Key_AltGr
) {
1185 return nsEventStatus_eIgnore
;
1188 // Look for specialized app-command keys
1189 switch (aEvent
->key()) {
1191 return DispatchCommandEvent(nsGkAtoms::Back
);
1192 case Qt::Key_Forward
:
1193 return DispatchCommandEvent(nsGkAtoms::Forward
);
1194 case Qt::Key_Refresh
:
1195 return DispatchCommandEvent(nsGkAtoms::Reload
);
1197 return DispatchCommandEvent(nsGkAtoms::Stop
);
1198 case Qt::Key_Search
:
1199 return DispatchCommandEvent(nsGkAtoms::Search
);
1200 case Qt::Key_Favorites
:
1201 return DispatchCommandEvent(nsGkAtoms::Bookmarks
);
1202 case Qt::Key_HomePage
:
1203 return DispatchCommandEvent(nsGkAtoms::Home
);
1205 case Qt::Key_F16
: // F16, F20, F18, F14 are old keysyms for Copy Cut Paste Undo
1206 return DispatchContentCommandEvent(NS_CONTENT_COMMAND_COPY
);
1209 return DispatchContentCommandEvent(NS_CONTENT_COMMAND_CUT
);
1213 return DispatchContentCommandEvent(NS_CONTENT_COMMAND_PASTE
);
1215 return DispatchContentCommandEvent(NS_CONTENT_COMMAND_UNDO
);
1218 // Qt::Key_Redo and Qt::Key_Undo are not available yet.
1219 if (aEvent
->nativeVirtualKey() == 0xff66) {
1220 return DispatchContentCommandEvent(NS_CONTENT_COMMAND_REDO
);
1222 if (aEvent
->nativeVirtualKey() == 0xff65) {
1223 return DispatchContentCommandEvent(NS_CONTENT_COMMAND_UNDO
);
1226 WidgetKeyboardEvent
event(true, NS_KEY_PRESS
, this);
1227 InitKeyEvent(event
, aEvent
);
1228 // Seend the key press event
1229 return DispatchEvent(&event
);
1233 nsWindow::keyReleaseEvent(QKeyEvent
* aEvent
)
1235 LOGFOCUS(("OnKeyReleaseEvent [%p]\n", (void *)this));
1237 // The user has done something.
1240 if (IsContextMenuKeyEvent(aEvent
)) {
1241 // er, what do we do here? DoDefault or NoDefault?
1242 return nsEventStatus_eConsumeDoDefault
;
1245 // send the key event as a key up event
1246 WidgetKeyboardEvent
event(true, NS_KEY_UP
, this);
1247 InitKeyEvent(event
, aEvent
);
1249 if (aEvent
->key() == Qt::Key_AltGr
) {
1250 sAltGrModifier
= false;
1253 // unset the key down flag
1254 ClearKeyDownFlag(event
.keyCode
);
1256 return DispatchEvent(&event
);
1260 nsWindow::wheelEvent(QWheelEvent
* aEvent
)
1262 // check to see if we should rollup
1263 WidgetWheelEvent
wheelEvent(true, NS_WHEEL_WHEEL
, this);
1264 wheelEvent
.deltaMode
= nsIDOMWheelEvent::DOM_DELTA_LINE
;
1266 // negative values for aEvent->delta indicate downward scrolling;
1267 // this is opposite Gecko usage.
1268 // TODO: Store the unused delta values due to fraction round and add it
1269 // to next event. The stored values should be reset by other
1270 // direction scroll event.
1271 int32_t delta
= (int)(aEvent
->delta() / WHEEL_DELTA
) * -3;
1273 switch (aEvent
->orientation()) {
1275 wheelEvent
.deltaY
= wheelEvent
.lineOrPageDeltaY
= delta
;
1277 case Qt::Horizontal
:
1278 wheelEvent
.deltaX
= wheelEvent
.lineOrPageDeltaX
= delta
;
1285 wheelEvent
.refPoint
.x
= nscoord(aEvent
->pos().x());
1286 wheelEvent
.refPoint
.y
= nscoord(aEvent
->pos().y());
1288 wheelEvent
.InitBasicModifiers(aEvent
->modifiers() & Qt::ControlModifier
,
1289 aEvent
->modifiers() & Qt::AltModifier
,
1290 aEvent
->modifiers() & Qt::ShiftModifier
,
1291 aEvent
->modifiers() & Qt::MetaModifier
);
1292 wheelEvent
.time
= 0;
1294 return DispatchEvent(&wheelEvent
);
1298 nsWindow::showEvent(QShowEvent
*)
1300 LOG(("%s [%p]\n", __PRETTY_FUNCTION__
,(void *)this));
1302 return nsEventStatus_eConsumeDoDefault
;
1306 nsWindow::hideEvent(QHideEvent
*)
1308 LOG(("%s [%p]\n", __PRETTY_FUNCTION__
,(void *)this));
1310 return nsEventStatus_eConsumeDoDefault
;
1313 nsEventStatus
nsWindow::touchEvent(QTouchEvent
* aEvent
)
1315 return nsEventStatus_eIgnore
;
1319 nsWindow::tabletEvent(QTabletEvent
* aEvent
)
1321 LOGFOCUS(("nsWindow::%s [%p]\n", __FUNCTION__
, (void *)this));
1322 return nsEventStatus_eIgnore
;
1328 nsWindow::DispatchEvent(WidgetGUIEvent
* aEvent
)
1330 nsEventStatus status
;
1331 DispatchEvent(aEvent
, status
);
1336 nsWindow::DispatchActivateEvent(void)
1338 if (mWidgetListener
) {
1339 mWidgetListener
->WindowActivated();
1344 nsWindow::DispatchDeactivateEvent(void)
1346 if (mWidgetListener
) {
1347 mWidgetListener
->WindowDeactivated();
1352 nsWindow::DispatchActivateEventOnTopLevelWindow(void)
1354 nsWindow
* topLevelWindow
= static_cast<nsWindow
*>(GetTopLevelWidget());
1355 if (topLevelWindow
!= nullptr) {
1356 topLevelWindow
->DispatchActivateEvent();
1361 nsWindow::DispatchDeactivateEventOnTopLevelWindow(void)
1363 nsWindow
* topLevelWindow
= static_cast<nsWindow
*>(GetTopLevelWidget());
1364 if (topLevelWindow
!= nullptr) {
1365 topLevelWindow
->DispatchDeactivateEvent();
1370 nsWindow::DispatchResizeEvent(nsIntRect
&aRect
, nsEventStatus
&aStatus
)
1372 aStatus
= nsEventStatus_eIgnore
;
1373 if (mWidgetListener
&&
1374 mWidgetListener
->WindowResized(this, aRect
.width
, aRect
.height
)) {
1375 aStatus
= nsEventStatus_eConsumeNoDefault
;
1379 ///////////////////////////////////// OLD GECKO ECENTS need to Sort ///////////////////
1381 NS_IMPL_ISUPPORTS_INHERITED(nsWindow
, nsBaseWidget
, nsISupportsWeakReference
)
1386 nsWindow::ClearCachedResources()
1388 if (mLayerManager
&&
1389 mLayerManager
->GetBackendType() == mozilla::layers::LayersBackend::LAYERS_BASIC
) {
1390 mLayerManager
->ClearCachedResources();
1392 for (nsIWidget
* kid
= mFirstChild
; kid
; ) {
1393 nsIWidget
* next
= kid
->GetNextSibling();
1394 static_cast<nsWindow
*>(kid
)->ClearCachedResources();
1400 nsWindow::SetParent(nsIWidget
*aNewParent
)
1402 NS_ENSURE_ARG_POINTER(aNewParent
);
1404 nsCOMPtr
<nsIWidget
> kungFuDeathGrip(this);
1405 nsIWidget
* parent
= GetParent();
1407 parent
->RemoveChild(this);
1409 ReparentNativeWidget(aNewParent
);
1410 aNewParent
->AddChild(this);
1415 nsWindow::SetModal(bool aModal
)
1417 LOG(("nsWindow::SetModal [%p] %d, widget[%p]\n", (void *)this, aModal
, mWidget
));
1419 mWidget
->setModality(aModal
? Qt::WindowModal
: Qt::NonModal
);
1427 nsWindow::PlaceBehind(nsTopLevelWidgetZPlacement aPlacement
,
1431 return NS_ERROR_NOT_IMPLEMENTED
;
1435 nsWindow::SetSizeMode(int32_t aMode
)
1439 LOG(("nsWindow::SetSizeMode [%p] %d\n", (void *)this, aMode
));
1440 if (aMode
!= nsSizeMode_Minimized
) {
1441 mWidget
->requestActivate();
1444 // Save the requested state.
1445 rv
= nsBaseWidget::SetSizeMode(aMode
);
1447 // return if there's no shell or our current state is the same as
1448 // the mode we were just set to.
1449 if (!mWidget
|| mSizeState
== mSizeMode
) {
1454 case nsSizeMode_Maximized
:
1455 mWidget
->showMaximized();
1457 case nsSizeMode_Minimized
:
1458 mWidget
->showMinimized();
1460 case nsSizeMode_Fullscreen
:
1461 mWidget
->showFullScreen();
1465 // nsSizeMode_Normal, really.
1470 mSizeState
= mSizeMode
;
1475 // Helper function to recursively find the first parent item that
1476 // is still visible (QGraphicsItem can be hidden even if they are
1477 // set to visible if one of their ancestors is invisible)
1479 void find_first_visible_parent(QWindow
* aItem
, QWindow
*& aVisibleItem
)
1481 NS_ENSURE_TRUE_VOID(aItem
);
1483 aVisibleItem
= nullptr;
1484 QWindow
* parItem
= nullptr;
1485 while (!aVisibleItem
) {
1486 if (aItem
->isVisible()) {
1487 aVisibleItem
= aItem
;
1490 parItem
= aItem
->parent();
1495 aItem
->setVisible(true);
1496 aVisibleItem
= aItem
;
1503 nsWindow::GetScreenBounds(nsIntRect
&aRect
)
1505 aRect
= nsIntRect(nsIntPoint(0, 0), mBounds
.Size());
1507 QPoint pos
= mWidget
->position();
1508 aRect
.MoveTo(pos
.x(), pos
.y());
1511 aRect
.MoveTo(WidgetToScreenOffset());
1513 LOG(("GetScreenBounds %d %d | %d %d | %d %d\n",
1515 mBounds
.width
, mBounds
.height
,
1516 aRect
.width
, aRect
.height
));
1521 nsWindow::SetIcon(const nsAString
& aIconSpec
)
1526 nsCOMPtr
<nsIFile
> iconFile
;
1528 nsTArray
<nsCString
> iconList
;
1530 // Look for icons with the following suffixes appended to the base name.
1531 // The last two entries (for the old XPM format) will be ignored unless
1532 // no icons are found using the other suffixes. XPM icons are depricated.
1534 const char extensions
[6][7] = { ".png", "16.png", "32.png", "48.png",
1537 for (uint32_t i
= 0; i
< ArrayLength(extensions
); i
++) {
1538 // Don't bother looking for XPM versions if we found a PNG.
1539 if (i
== ArrayLength(extensions
) - 2 && iconList
.Length())
1542 nsAutoString extension
;
1543 extension
.AppendASCII(extensions
[i
]);
1545 ResolveIconName(aIconSpec
, extension
, getter_AddRefs(iconFile
));
1547 iconFile
->GetNativePath(path
);
1548 iconList
.AppendElement(path
);
1552 // leave the default icon intact if no matching icons were found
1553 if (iconList
.Length() == 0)
1556 return SetWindowIconList(iconList
);
1560 nsWindow::CaptureMouse(bool aCapture
)
1562 LOG(("CaptureMouse %p\n", (void *)this));
1567 mWidget
->setMouseGrabEnabled(aCapture
);
1573 nsWindow::CheckForRollup(double aMouseX
, double aMouseY
,
1576 nsIRollupListener
* rollupListener
= GetActiveRollupListener();
1577 nsCOMPtr
<nsIWidget
> rollupWidget
;
1578 if (rollupListener
) {
1579 rollupWidget
= rollupListener
->GetRollupWidget();
1581 if (!rollupWidget
) {
1582 nsBaseWidget::gRollupListener
= nullptr;
1586 bool retVal
= false;
1587 MozQWidget
*currentPopup
=
1588 (MozQWidget
*)rollupWidget
->GetNativeData(NS_NATIVE_WINDOW
);
1589 if (!is_mouse_in_window(currentPopup
, aMouseX
, aMouseY
)) {
1592 rollup
= rollupListener
->ShouldRollupOnMouseWheelEvent();
1595 // if we're dealing with menus, we probably have submenus and
1596 // we don't want to rollup if the clickis in a parent menu of
1597 // the current submenu
1598 uint32_t popupsToRollup
= UINT32_MAX
;
1599 if (rollupListener
) {
1600 nsAutoTArray
<nsIWidget
*, 5> widgetChain
;
1601 uint32_t sameTypeCount
= rollupListener
->GetSubmenuWidgetChain(&widgetChain
);
1602 for (uint32_t i
=0; i
<widgetChain
.Length(); ++i
) {
1603 nsIWidget
* widget
= widgetChain
[i
];
1604 MozQWidget
* currWindow
=
1605 (MozQWidget
*) widget
->GetNativeData(NS_NATIVE_WINDOW
);
1606 if (is_mouse_in_window(currWindow
, aMouseX
, aMouseY
)) {
1607 if (i
< sameTypeCount
) {
1611 popupsToRollup
= sameTypeCount
;
1615 } // foreach parent menu widget
1616 } // if rollup listener knows about menus
1618 // if we've determined that we should still rollup, do it.
1620 nsIntPoint
pos(aMouseX
, aMouseY
);
1621 retVal
= rollupListener
->Rollup(popupsToRollup
, &pos
, nullptr);
1630 is_mouse_in_window (MozQWidget
* aWindow
, double aMouseX
, double aMouseY
)
1632 return aWindow
->geometry().contains(aMouseX
, aMouseY
);
1636 nsWindow::GetAttention(int32_t aCycleCount
)
1638 LOG(("nsWindow::GetAttention [%p]\n", (void *)this));
1639 return NS_ERROR_NOT_IMPLEMENTED
;
1645 nsWindow::OnCloseEvent(QCloseEvent
*aEvent
)
1647 if (!mWidgetListener
)
1648 return nsEventStatus_eIgnore
;
1649 mWidgetListener
->RequestWindowClose(this);
1650 return nsEventStatus_eConsumeNoDefault
;
1655 is_latin_shortcut_key(quint32 aKeyval
)
1657 return ((Qt::Key_0
<= aKeyval
&& aKeyval
<= Qt::Key_9
) ||
1658 (Qt::Key_A
<= aKeyval
&& aKeyval
<= Qt::Key_Z
));
1662 nsWindow::DispatchCommandEvent(nsIAtom
* aCommand
)
1664 WidgetCommandEvent
event(true, nsGkAtoms::onAppCommand
, aCommand
, this);
1666 nsEventStatus status
;
1667 DispatchEvent(&event
, status
);
1673 nsWindow::DispatchContentCommandEvent(int32_t aMsg
)
1675 WidgetContentCommandEvent
event(true, aMsg
, this);
1677 nsEventStatus status
;
1678 DispatchEvent(&event
, status
);
1685 GetBrandName(nsXPIDLString
& brandName
)
1687 nsCOMPtr
<nsIStringBundleService
> bundleService
=
1688 mozilla::services::GetStringBundleService();
1690 nsCOMPtr
<nsIStringBundle
> bundle
;
1691 if (bundleService
) {
1692 bundleService
->CreateBundle(
1693 "chrome://branding/locale/brand.properties",
1694 getter_AddRefs(bundle
));
1698 bundle
->GetStringFromName(
1699 MOZ_UTF16("brandShortName"),
1700 getter_Copies(brandName
));
1703 if (brandName
.IsEmpty()) {
1704 brandName
.AssignLiteral(MOZ_UTF16("Mozilla"));
1709 nsWindow::SetWindowClass(const nsAString
&xulWinType
)
1712 return NS_ERROR_FAILURE
;
1715 nsXPIDLString brandName
;
1716 GetBrandName(brandName
);
1719 XClassHint
*class_hint
= XAllocClassHint();
1721 return NS_ERROR_OUT_OF_MEMORY
;
1723 const char *role
= nullptr;
1724 class_hint
->res_name
= ToNewCString(xulWinType
);
1725 if (!class_hint
->res_name
) {
1727 return NS_ERROR_OUT_OF_MEMORY
;
1729 class_hint
->res_class
= ToNewCString(brandName
);
1730 if (!class_hint
->res_class
) {
1731 nsMemory::Free(class_hint
->res_name
);
1733 return NS_ERROR_OUT_OF_MEMORY
;
1736 // Parse res_name into a name and role. Characters other than
1737 // [A-Za-z0-9_-] are converted to '_'. Anything after the first
1738 // colon is assigned to role; if there's no colon, assign the
1739 // whole thing to both role and res_name.
1740 for (char *c
= class_hint
->res_name
; *c
; c
++) {
1745 else if (!isascii(*c
) || (!isalnum(*c
) && ('_' != *c
) && ('-' != *c
)))
1748 class_hint
->res_name
[0] = toupper(class_hint
->res_name
[0]);
1749 if (!role
) role
= class_hint
->res_name
;
1751 QWindow
*widget
= mWidget
;
1752 // If widget not show, handle might be null
1753 if (widget
&& widget
->winId()) {
1754 XSetClassHint(gfxQtPlatform::GetXDisplay(widget
),
1759 nsMemory::Free(class_hint
->res_class
);
1760 nsMemory::Free(class_hint
->res_name
);
1768 nsWindow::NativeResize(int32_t aWidth
, int32_t aHeight
, bool aRepaint
)
1770 LOG(("nsWindow::NativeResize [%p] %d %d\n", (void *)this,
1773 mNeedsResize
= false;
1775 mWidget
->resize(aWidth
, aHeight
);
1778 mWidget
->renderLater();
1783 nsWindow::NativeResize(int32_t aX
, int32_t aY
,
1784 int32_t aWidth
, int32_t aHeight
,
1787 LOG(("nsWindow::NativeResize [%p] %d %d %d %d\n", (void *)this,
1788 aX
, aY
, aWidth
, aHeight
));
1790 mNeedsResize
= false;
1793 mWidget
->setGeometry(aX
, aY
, aWidth
, aHeight
);
1796 mWidget
->renderLater();
1801 nsWindow::NativeShow(bool aAction
)
1804 // On e10s, we never want the child process or plugin process
1805 // to go fullscreen because if we do the window because visible
1806 // do to disabled Qt-Xembed
1808 // unset our flag now that our window has been shown
1817 nsWindow::SetHasTransparentBackground(bool aTransparent
)
1819 return NS_ERROR_NOT_IMPLEMENTED
;
1823 nsWindow::GetHasTransparentBackground(bool& aTransparent
)
1825 aTransparent
= mIsTransparent
;
1830 nsWindow::SetupPluginPort(void)
1832 NS_WARNING("Not implemented");
1837 nsWindow::SetWindowIconList(const nsTArray
<nsCString
> &aIconList
)
1841 for (uint32_t i
= 0; i
< aIconList
.Length(); ++i
) {
1842 const char *path
= aIconList
[i
].get();
1843 LOG(("window [%p] Loading icon from %s\n", (void *)this, path
));
1847 mWidget
->setIcon(icon
);
1853 nsWindow::SetDefaultIcon(void)
1855 SetIcon(NS_LITERAL_STRING("default"));
1858 void nsWindow::QWidgetDestroyed()
1865 nsWindow::HideWindowChrome(bool aShouldHide
)
1869 return NS_ERROR_FAILURE
;
1872 // Sawfish, metacity, and presumably other window managers get
1873 // confused if we change the window decorations while the window
1875 bool wasVisible
= false;
1876 if (mWidget
->isVisible()) {
1888 //////////////////////////////////////////////////////////////////////
1890 NS_IMETHODIMP_(bool)
1891 nsWindow::HasGLContext()
1898 nsWindow::GetParent(void)
1906 return qApp
->primaryScreen()->logicalDotsPerInch();
1910 nsWindow::OnDestroy(void)
1912 if (mOnDestroyCalled
) {
1916 mOnDestroyCalled
= true;
1918 // release references to children and device context
1919 nsBaseWidget::OnDestroy();
1921 // let go of our parent
1924 nsCOMPtr
<nsIWidget
> kungFuDeathGrip
= this;
1925 NotifyWindowDestroyed();
1929 nsWindow::AreBoundsSane(void)
1931 if (mBounds
.width
> 0 && mBounds
.height
> 0) {
1939 nsWindow::SetSoftwareKeyboardState(bool aOpen
,
1940 const InputContextAction
& aAction
)
1943 NS_ENSURE_TRUE_VOID(mInputContext
.mIMEState
.mEnabled
!=
1944 IMEState::DISABLED
);
1946 // Ensure that opening the virtual keyboard is allowed for this specific
1947 // InputContext depending on the content.ime.strict.policy pref
1948 if (mInputContext
.mIMEState
.mEnabled
!= IMEState::PLUGIN
&&
1949 Preferences::GetBool("content.ime.strict_policy", false) &&
1950 !aAction
.ContentGotFocusByTrustedCause() &&
1951 !aAction
.UserMightRequestOpenVKB()) {
1957 qApp
->inputMethod()->show();
1959 qApp
->inputMethod()->hide();
1967 nsWindow::ProcessMotionEvent()
1969 if (mMoveEvent
.needDispatch
) {
1970 WidgetMouseEvent
event(true, NS_MOUSE_MOVE
, this,
1971 WidgetMouseEvent::eReal
);
1973 event
.refPoint
.x
= nscoord(mMoveEvent
.pos
.x());
1974 event
.refPoint
.y
= nscoord(mMoveEvent
.pos
.y());
1976 event
.InitBasicModifiers(mMoveEvent
.modifiers
& Qt::ControlModifier
,
1977 mMoveEvent
.modifiers
& Qt::AltModifier
,
1978 mMoveEvent
.modifiers
& Qt::ShiftModifier
,
1979 mMoveEvent
.modifiers
& Qt::MetaModifier
);
1980 event
.clickCount
= 0;
1982 DispatchEvent(&event
);
1983 mMoveEvent
.needDispatch
= false;
1986 mTimerStarted
= false;