Bug 118299 - "NS_THEME_RESIZER implementation (GTK)" (use window manager's resize and support it in gtk2) [p=ian@mckellar.org (Ian McKellar) r+sr=roc a1.9=mconnor]

This commit is contained in:
reed@reedloden.com 2007-12-11 02:08:35 -08:00
parent 82a6bee14d
commit 6e42dba785
7 changed files with 132 additions and 12 deletions

View File

@ -100,16 +100,36 @@ nsResizerFrame::HandleEvent(nsPresContext* aPresContext,
static_cast<nsMouseEvent*>(aEvent)->button ==
nsMouseEvent::eLeftButton)
{
// we're tracking.
mTrackingMouseMove = PR_TRUE;
// start capture.
aEvent->widget->CaptureMouse(PR_TRUE);
CaptureMouseEvents(aPresContext,PR_TRUE);
nsresult rv = NS_OK;
// remember current mouse coordinates.
mLastPoint = aEvent->refPoint;
aEvent->widget->GetScreenBounds(mWidgetRect);
// what direction should we go in?
// convert eDirection to horizontal and vertical directions
static const PRInt8 directions[][2] = {
{-1, -1}, {0, -1}, {1, -1},
{-1, 0}, {1, 0},
{-1, 1}, {0, 1}, {1, 1}
};
// ask the widget implementation to begin a resize drag if it can
rv = aEvent->widget->BeginResizeDrag(aEvent,
directions[mDirection][0], directions[mDirection][1]);
if (rv == NS_ERROR_NOT_IMPLEMENTED) {
// there's no native resize support,
// we need to window resizing ourselves
// we're tracking.
mTrackingMouseMove = PR_TRUE;
// start capture.
aEvent->widget->CaptureMouse(PR_TRUE);
CaptureMouseEvents(aPresContext,PR_TRUE);
// remember current mouse coordinates.
mLastPoint = aEvent->refPoint;
aEvent->widget->GetScreenBounds(mWidgetRect);
}
*aEventStatus = nsEventStatus_eConsumeNoDefault;
doDefault = PR_FALSE;

View File

@ -95,10 +95,10 @@ typedef nsEventStatus (*PR_CALLBACK EVENT_CALLBACK)(nsGUIEvent *event);
#define NS_NATIVE_PLUGIN_PORT_CG 101
#endif
// 092c37e8-2806-4ebc-b04b-e0bb624ce0d4
// d7d1aae8-fcb9-4fe7-be62-b20ffc53f1f9
#define NS_IWIDGET_IID \
{ 0x092c37e8, 0x2806, 0x4ebc, \
{ 0xb0, 0x4b, 0xe0, 0xbb, 0x62, 0x4c, 0xe0, 0xd4 } }
{ 0xd7d1aae8, 0xfcb9, 0x4fe7, \
{ 0xbe, 0x62, 0xb2, 0x0f, 0xfc, 0x53, 0xf1, 0xf9 } }
// Hide the native window systems real window type so as to avoid
// including native window system types and api's. This is necessary
@ -1045,6 +1045,11 @@ class nsIWidget : public nsISupports {
*/
virtual nsIContent* GetLastRollup() = 0;
/**
* Begin a window resizing drag, based on the event passed in.
*/
NS_IMETHOD BeginResizeDrag(nsGUIEvent* aEvent, PRInt32 aHorizontal, PRInt32 aVertical) = 0;
protected:
// keep the list of children. We also keep track of our siblings.
// The ownership model is as follows: parent holds a strong ref to

View File

@ -981,6 +981,10 @@ nsNativeThemeGTK::GetMinimumWidgetSize(nsIRenderingContext* aContext,
aResult->width = 14;
aResult->height = 13;
break;
case NS_THEME_RESIZER:
// same as Windows to make our lives easier
aResult->width = aResult->height = 15;
break;
case NS_THEME_TREEVIEW_TWISTY:
case NS_THEME_TREEVIEW_TWISTY_OPEN:
{
@ -1082,7 +1086,7 @@ nsNativeThemeGTK::ThemeSupportsWidget(nsPresContext* aPresContext,
case NS_THEME_STATUSBAR:
case NS_THEME_STATUSBAR_PANEL:
case NS_THEME_STATUSBAR_RESIZER_PANEL:
// case NS_THEME_RESIZER: // _VERY_BROKEN_ in gtk2
case NS_THEME_RESIZER:
case NS_THEME_LISTBOX:
// case NS_THEME_LISTBOX_LISTITEM:
case NS_THEME_TREEVIEW:

View File

@ -6058,3 +6058,85 @@ nsWindow::GetThebesSurface()
return mThebesSurface;
}
NS_IMETHODIMP
nsWindow::BeginResizeDrag(nsGUIEvent* aEvent, PRInt32 aHorizontal, PRInt32 aVertical)
{
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;
}
// work out what GdkWindowEdge we're talking about
GdkWindowEdge window_edge;
if (aVertical < 0) {
if (aHorizontal < 0) {
window_edge = GDK_WINDOW_EDGE_NORTH_WEST;
} else if (aHorizontal == 0) {
window_edge = GDK_WINDOW_EDGE_NORTH;
} else {
window_edge = GDK_WINDOW_EDGE_NORTH_EAST;
}
} else if (aVertical == 0) {
if (aHorizontal < 0) {
window_edge = GDK_WINDOW_EDGE_WEST;
} else if (aHorizontal == 0) {
return NS_ERROR_INVALID_ARG;
} else {
window_edge = GDK_WINDOW_EDGE_EAST;
}
} else {
if (aHorizontal < 0) {
window_edge = GDK_WINDOW_EDGE_SOUTH_WEST;
} else if (aHorizontal == 0) {
window_edge = GDK_WINDOW_EDGE_SOUTH;
} else {
window_edge = GDK_WINDOW_EDGE_SOUTH_EAST;
}
}
// get the gdk window for this widget
GdkWindow* gdk_window = mDrawingarea->inner_window;
if (!GDK_IS_WINDOW(gdk_window)) {
return NS_ERROR_FAILURE;
}
// find the top-level window
gdk_window = gdk_window_get_toplevel(gdk_window);
if (!GDK_IS_WINDOW(gdk_window)) {
return NS_ERROR_FAILURE;
}
// get the current (default) display
GdkDisplay* display = gdk_display_get_default();
if (!GDK_IS_DISPLAY(display)) {
return NS_ERROR_FAILURE;
}
// get the current pointer position and button state
GdkScreen* screen = NULL;
gint screenX, screenY;
GdkModifierType mask;
gdk_display_get_pointer(display, &screen, &screenX, &screenY, &mask);
// we only support resizing with button 1
if (!(mask & GDK_BUTTON1_MASK)) {
return NS_ERROR_FAILURE;
}
// tell the window manager to start the resize
gdk_window_begin_resize_drag(gdk_window, window_edge, 1,
screenX, screenY, aEvent->time);
return NS_OK;
}

View File

@ -266,6 +266,8 @@ public:
static guint32 mLastButtonPressTime;
static guint32 mLastButtonReleaseTime;
NS_IMETHOD BeginResizeDrag (nsGUIEvent* aEvent, PRInt32 aHorizontal, PRInt32 aVertical);
#ifdef USE_XIM
void IMEInitData (void);
void IMEReleaseData (void);

View File

@ -929,6 +929,12 @@ nsBaseWidget::ResolveIconName(const nsAString &aIconName,
NS_ADDREF(*aResult = file);
}
NS_IMETHODIMP
nsBaseWidget::BeginResizeDrag(nsGUIEvent* aEvent, PRInt32 aHorizontal, PRInt32 aVertical)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
#ifdef DEBUG
//////////////////////////////////////////////////////////////
//

View File

@ -138,6 +138,7 @@ public:
NS_IMETHOD SetWindowTitlebarColor(nscolor aColor);
virtual void ConvertToDeviceCoordinates(nscoord &aX,nscoord &aY) {}
virtual void FreeNativeData(void * data, PRUint32 aDataType) {}
NS_IMETHOD BeginResizeDrag(nsGUIEvent* aEvent, PRInt32 aHorizontal, PRInt32 aVertical);
protected: