diff --git a/mozilla/widget/src/xlib/nsAppShell.cpp b/mozilla/widget/src/xlib/nsAppShell.cpp index bd0ec611b14..17537220540 100644 --- a/mozilla/widget/src/xlib/nsAppShell.cpp +++ b/mozilla/widget/src/xlib/nsAppShell.cpp @@ -355,10 +355,12 @@ nsAppShell::DispatchEvent(XEvent *event) case FocusOut: HandleFocusOutEvent(event, widget); break; - case NoExpose: + // these annoy me. + break; + case VisibilityNotify: + HandleVisibilityNotifyEvent(event, widget); break; - default: PR_LOG(XlibWidgetsLM, PR_LOG_DEBUG, ("Unhandled window event: Window 0x%lx Got a %s event\n", event->xany.window, event_names[event->type])); @@ -388,16 +390,12 @@ nsAppShell::HandleButtonEvent(XEvent *event, nsWidget *aWidget) nsMouseEvent mevent; PRUint32 eventType = 0; - // XXX hack for now - PRBool doFocus = PR_FALSE; - PR_LOG(XlibWidgetsLM, PR_LOG_DEBUG, ("Button event for window 0x%lx button %d type %s\n", event->xany.window, event->xbutton.button, (event->type == ButtonPress ? "ButtonPress" : "ButtonRelease"))); switch(event->type) { case ButtonPress: switch(event->xbutton.button) { case 1: - doFocus = PR_TRUE; eventType = NS_MOUSE_LEFT_BUTTON_DOWN; break; case 2: @@ -423,30 +421,6 @@ nsAppShell::HandleButtonEvent(XEvent *event, nsWidget *aWidget) break; } - // XXX This is a hack that lets the text widgets get focus - // XXX ill fix it later. - if (doFocus) - { - nsGUIEvent focusEvent; - - focusEvent.message = NS_GOTFOCUS; - focusEvent.widget = aWidget; - - focusEvent.eventStructType = NS_GUI_EVENT; - - focusEvent.time = 0; - focusEvent.point.x = 0; - focusEvent.point.y = 0; - - NS_ADDREF(aWidget); - - printf("Button, and doing focus too, dude\n"); - - aWidget->DispatchFocusEvent(focusEvent); - - NS_ADDREF(aWidget); - } - mevent.message = eventType; mevent.widget = aWidget; mevent.eventStructType = NS_MOUSE_EVENT; @@ -568,6 +542,20 @@ nsAppShell::HandleFocusInEvent(XEvent *event, nsWidget *aWidget) { PR_LOG(XlibWidgetsLM, PR_LOG_DEBUG, ("FocusIn event for window 0x%lx\n", event->xfocus.window)); + nsGUIEvent focusEvent; + + focusEvent.message = NS_GOTFOCUS; + focusEvent.widget = aWidget; + + focusEvent.eventStructType = NS_GUI_EVENT; + + focusEvent.time = 0; + focusEvent.point.x = 0; + focusEvent.point.y = 0; + + NS_ADDREF(aWidget); + aWidget->DispatchFocusEvent(focusEvent); + NS_RELEASE(aWidget); } void @@ -575,4 +563,51 @@ nsAppShell::HandleFocusOutEvent(XEvent *event, nsWidget *aWidget) { PR_LOG(XlibWidgetsLM, PR_LOG_DEBUG, ("FocusOut event for window 0x%lx\n", event->xfocus.window)); + nsGUIEvent focusEvent; + + focusEvent.message = NS_LOSTFOCUS; + focusEvent.widget = aWidget; + + focusEvent.eventStructType = NS_GUI_EVENT; + + focusEvent.time = 0; + focusEvent.point.x = 0; + focusEvent.point.y = 0; + + NS_ADDREF(aWidget); + aWidget->DispatchFocusEvent(focusEvent); + NS_RELEASE(aWidget); +} + +void nsAppShell::HandleVisibilityNotifyEvent(XEvent *event, nsWidget *aWidget) +{ +#ifdef DEBUG + PR_LOG(XlibWidgetsLM, PR_LOG_DEBUG, ("VisibilityNotify event for window 0x%lx ", + event->xfocus.window)); + switch(event->xvisibility.state) { + case VisibilityFullyObscured: + PR_LOG(XlibWidgetsLM, PR_LOG_DEBUG, ("Fully Obscured\n")); + break; + case VisibilityPartiallyObscured: + PR_LOG(XlibWidgetsLM, PR_LOG_DEBUG, ("Partially Obscured\n")); + break; + case VisibilityUnobscured: + PR_LOG(XlibWidgetsLM, PR_LOG_DEBUG, ("Unobscured\n")); + } +#endif + aWidget->SetVisibility(event->xvisibility.state); +} + +void nsAppShell::HandleMapNotifyEvent(XEvent *event, nsWidget *aWidget) +{ + PR_LOG(XlibWidgetsLM, PR_LOG_DEBUG, ("MapNotify event for window 0x%lx\n", + event->xmap.window)); + aWidget->SetMapStatus(PR_TRUE); +} + +void nsAppShell::HandleUnmapNotifyEvent(XEvent *event, nsWidget *aWidget) +{ + PR_LOG(XlibWidgetsLM, PR_LOG_DEBUG, ("UnmapNotifyEvent for window 0x%lx\n", + event->xunmap.window)); + aWidget->SetMapStatus(PR_FALSE); } diff --git a/mozilla/widget/src/xlib/nsAppShell.h b/mozilla/widget/src/xlib/nsAppShell.h index 6b5a67a5169..f7e653ec3a5 100644 --- a/mozilla/widget/src/xlib/nsAppShell.h +++ b/mozilla/widget/src/xlib/nsAppShell.h @@ -56,6 +56,9 @@ class nsAppShell : public nsIAppShell static void HandleKeyReleaseEvent(XEvent *event, nsWidget *aWidget); static void HandleFocusInEvent(XEvent *event, nsWidget *aWidget); static void HandleFocusOutEvent(XEvent *event, nsWidget *aWidget); + static void HandleVisibilityNotifyEvent(XEvent *event, nsWidget *aWidget); + static void HandleMapNotifyEvent(XEvent *event, nsWidget *aWidget); + static void HandleUnmapNotifyEvent(XEvent *event, nsWidget *aWidget); protected: nsIEventQueueService * mEventQueueService; diff --git a/mozilla/widget/src/xlib/nsScrollBar.cpp b/mozilla/widget/src/xlib/nsScrollBar.cpp index 252e09dab66..72cb8443543 100644 --- a/mozilla/widget/src/xlib/nsScrollBar.cpp +++ b/mozilla/widget/src/xlib/nsScrollBar.cpp @@ -225,7 +225,7 @@ void nsScrollbar::CreateNative(Window aParent, nsRect aRect) // be discarded... attr.bit_gravity = SouthEastGravity; // make sure that we listen for events - attr.event_mask = StructureNotifyMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask | FocusChangeMask; + attr.event_mask = StructureNotifyMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask | FocusChangeMask | VisibilityChangeMask; // set the default background color and border to that awful gray attr.background_pixel = mBackgroundPixel; attr.border_pixel = mBorderPixel; @@ -240,7 +240,7 @@ void nsScrollbar::CreateNative(Window aParent, nsRect aRect) CreateNativeWindow(aParent, mBounds, attr, attr_mask); CreateGC(); // set up the scrolling bar. - attr.event_mask = Button1MotionMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask | FocusChangeMask; + attr.event_mask = Button1MotionMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask | FocusChangeMask | VisibilityChangeMask; attr.background_pixel = xlib_rgb_xpixel_from_rgb(NS_RGB(192,192,192)); attr.border_pixel = xlib_rgb_xpixel_from_rgb(NS_RGB(100,100,100)); // set up the size diff --git a/mozilla/widget/src/xlib/nsWidget.cpp b/mozilla/widget/src/xlib/nsWidget.cpp index efef6d72711..655b3632875 100644 --- a/mozilla/widget/src/xlib/nsWidget.cpp +++ b/mozilla/widget/src/xlib/nsWidget.cpp @@ -75,6 +75,8 @@ nsWidget::nsWidget() : nsBaseWidget() mScrollY = 0; mIsShown = PR_FALSE; mIsToplevel = PR_FALSE; + mIsMapped = PR_FALSE; + mVisibility = VisibilityFullyObscured; // this is an X constant. } nsWidget::~nsWidget() @@ -254,6 +256,21 @@ NS_IMETHODIMP nsWidget::Enable(PRBool bState) NS_IMETHODIMP nsWidget::SetFocus(void) { + if (mBaseWindow) { + if (mIsMapped && (mVisibility != VisibilityFullyObscured)) { + PR_LOG(XlibWidgetsLM, PR_LOG_DEBUG, ("nsWidget::SetFocus() setting focus to 0x%lx\n", mBaseWindow)); + XSetInputFocus(mDisplay, + mBaseWindow, + RevertToPointerRoot, // XXX is this the right behavior? + CurrentTime); + } + else { + PR_LOG(XlibWidgetsLM, PR_LOG_DEBUG, ("nsWidget::SetFocus() NOT setting focus to 0x%lx because it's not mapped or is not visible\n", mBaseWindow)); + } + } + else { + PR_LOG(XlibWidgetsLM, PR_LOG_DEBUG, ("nsWidget::SetFocus() tried to set focus to a window that doesn't exist.\n")); + } return NS_OK; } @@ -364,7 +381,7 @@ NS_IMETHODIMP nsWidget::Show(PRBool bState) if (bState) { if (mIsToplevel) { - printf("Someone just used the show method on the toplevel window.\n"); + PR_LOG(XlibWidgetsLM, PR_LOG_DEBUG, ("Someone just used the show method on the toplevel window.\n")); } if (mParentWidget) { ((nsWidget *)mParentWidget)->WidgetShow(this); @@ -372,7 +389,7 @@ NS_IMETHODIMP nsWidget::Show(PRBool bState) else { if (mBaseWindow) { PR_LOG(XlibWidgetsLM, PR_LOG_DEBUG, ("Mapping window 0x%lx...\n", mBaseWindow)); - XMapWindow(mDisplay, mBaseWindow); + Map(); } } mIsShown = PR_TRUE; @@ -380,7 +397,7 @@ NS_IMETHODIMP nsWidget::Show(PRBool bState) else { if (mBaseWindow) { PR_LOG(XlibWidgetsLM, PR_LOG_DEBUG, ("Unmapping window 0x%lx...\n", mBaseWindow)); - XUnmapWindow(mDisplay, mBaseWindow); + Unmap(); } mIsShown = PR_FALSE; } @@ -389,6 +406,12 @@ NS_IMETHODIMP nsWidget::Show(PRBool bState) NS_IMETHODIMP nsWidget::IsVisible(PRBool &aState) { + if (mIsMapped && (mVisibility != VisibilityFullyObscured)) { + aState = PR_TRUE; + } + else { + aState = PR_FALSE; + } return NS_OK; } @@ -479,7 +502,8 @@ nsWidget::GetEventMask() ExposureMask | ButtonPressMask | ButtonReleaseMask | - PointerMotionMask; + PointerMotionMask | + VisibilityChangeMask; return event_mask; } @@ -790,13 +814,13 @@ void nsWidget::WidgetMove(nsWidget *aWidget) aWidget->mBounds.y); if (aWidget->mIsShown == PR_TRUE) { PR_LOG(XlibScrollingLM, PR_LOG_DEBUG, ("Mapping window 0x%lx...\n", mBaseWindow)); - XMapWindow(aWidget->mDisplay, aWidget->mBaseWindow); + aWidget->Map(); } } else { PR_LOG(XlibScrollingLM, PR_LOG_DEBUG, ("Widget is not visible...\n")); PR_LOG(XlibScrollingLM, PR_LOG_DEBUG, ("Unmapping window 0x%lx...\n", mBaseWindow)); - XUnmapWindow(aWidget->mDisplay, aWidget->mBaseWindow); + aWidget->Unmap(); } } @@ -811,13 +835,13 @@ void nsWidget::WidgetResize(nsWidget *aWidget) aWidget->mBounds.height); if (aWidget->mIsShown == PR_TRUE) { PR_LOG(XlibScrollingLM, PR_LOG_DEBUG, ("Mapping window 0x%lx...\n", mBaseWindow)); - XMapWindow(aWidget->mDisplay, aWidget->mBaseWindow); + aWidget->Map(); } } else { PR_LOG(XlibScrollingLM, PR_LOG_DEBUG, ("Widget is not visible...\n")); PR_LOG(XlibScrollingLM, PR_LOG_DEBUG, ("Unmapping window 0x%lx...\n", mBaseWindow)); - XUnmapWindow(aWidget->mDisplay, aWidget->mBaseWindow); + aWidget->Unmap(); } } @@ -834,13 +858,13 @@ void nsWidget::WidgetMoveResize(nsWidget *aWidget) aWidget->mBounds.y); if (aWidget->mIsShown == PR_TRUE) { PR_LOG(XlibScrollingLM, PR_LOG_DEBUG, ("Mapping window 0x%lx...\n", mBaseWindow)); - XMapWindow(aWidget->mDisplay, aWidget->mBaseWindow); + aWidget->Map(); } } else { PR_LOG(XlibScrollingLM, PR_LOG_DEBUG, ("Widget is not visible...\n")); PR_LOG(XlibScrollingLM, PR_LOG_DEBUG, ("Unmapping window 0x%lx...\n", mBaseWindow)); - XUnmapWindow(aWidget->mDisplay, aWidget->mBaseWindow); + aWidget->Unmap(); } } @@ -849,7 +873,7 @@ void nsWidget::WidgetShow(nsWidget *aWidget) if (PR_TRUE == WidgetVisible(aWidget->mBounds)) { PR_LOG(XlibScrollingLM, PR_LOG_DEBUG, ("Mapping window...\n")); PR_LOG(XlibScrollingLM, PR_LOG_DEBUG, ("Mapping window 0x%lx...\n", mBaseWindow)); - XMapWindow(aWidget->mDisplay, aWidget->mBaseWindow); + aWidget->Map(); } else { PR_LOG(XlibScrollingLM, PR_LOG_DEBUG, ("Not Mapping window...\n")); @@ -870,3 +894,23 @@ PRBool nsWidget::WidgetVisible(nsRect &aBounds) PR_LOG(XlibScrollingLM, PR_LOG_DEBUG, ("nsWidget::WidgetVisible(): widget is not visible\n")); return PR_FALSE; } + +void nsWidget::Map(void) +{ + XMapWindow(mDisplay, mBaseWindow); +} + +void nsWidget::Unmap(void) +{ + XUnmapWindow(mDisplay, mBaseWindow); +} + +void nsWidget::SetVisibility(int aState) +{ + mVisibility = aState; +} + +void nsWidget::SetMapStatus(PRBool aState) +{ + mIsMapped = aState; +} diff --git a/mozilla/widget/src/xlib/nsWidget.h b/mozilla/widget/src/xlib/nsWidget.h index db7aaae6470..f89ce009905 100644 --- a/mozilla/widget/src/xlib/nsWidget.h +++ b/mozilla/widget/src/xlib/nsWidget.h @@ -114,6 +114,8 @@ public: static nsWidget * GetWidgetForWindow(Window aWindow); + void SetVisibility(int aState); // using the X constants here + void SetMapStatus(PRBool aState); protected: @@ -127,6 +129,8 @@ protected: virtual void CreateNative(Window aParent, nsRect aRect); virtual void DestroyNative(void); void CreateGC(void); + void Map(void); + void Unmap(void); // Let each sublclass set the event mask according to their needs virtual long GetEventMask(); @@ -151,7 +155,8 @@ protected: PRUint32 mScrollY; PRBool mIsShown; - + PRBool mIsMapped; + int mVisibility; // this is an int because that's the way X likes it PRUint32 mPreferredWidth; PRUint32 mPreferredHeight; diff --git a/mozilla/widget/src/xlib/nsWindow.cpp b/mozilla/widget/src/xlib/nsWindow.cpp index 09bbf0dd40e..e07c3475cfa 100644 --- a/mozilla/widget/src/xlib/nsWindow.cpp +++ b/mozilla/widget/src/xlib/nsWindow.cpp @@ -55,7 +55,7 @@ void nsWindow::CreateNative(Window aParent, nsRect aRect) // be discarded... attr.bit_gravity = NorthWestGravity; // make sure that we listen for events - attr.event_mask = StructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | KeyPressMask | KeyReleaseMask | FocusChangeMask; + attr.event_mask = StructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | KeyPressMask | KeyReleaseMask | FocusChangeMask | VisibilityChangeMask; // set the default background color and border to that awful gray attr.background_pixel = mBackgroundPixel; attr.border_pixel = mBorderPixel; @@ -86,8 +86,8 @@ nsWindow::GetEventMask() PointerMotionMask | KeyPressMask | KeyReleaseMask | - FocusChangeMask; - + FocusChangeMask | + VisibilityChangeMask; return event_mask; }