зеркало из https://github.com/mozilla/pjs.git
b=500081 use a timestamp when grabbing the pointer and generate timestamps for drags in the same way r=roc
--HG-- extra : transplant_source : %CF%87%19S%2C%8C2%BD%C9%0C%2B%C6%BA%22%EE%CB%06%BC%D2%00
This commit is contained in:
Родитель
049ad9d694
Коммит
f3074628f1
|
@ -323,17 +323,15 @@ nsDragService::InvokeDragSession(nsIDOMNode *aDOMNode,
|
|||
if (aActionType & DRAGDROP_ACTION_LINK)
|
||||
action = (GdkDragAction)(action | GDK_ACTION_LINK);
|
||||
|
||||
// Create a fake event for the drag so we can pass the time
|
||||
// (so to speak.) If we don't do this the drag can end as a
|
||||
// result of a button release that is actually _earlier_ than
|
||||
// CurrentTime. So we use the time on the last button press
|
||||
// event, as that will always be older than the button release
|
||||
// that ends any drag.
|
||||
// Create a fake event for the drag so we can pass the time (so to speak).
|
||||
// If we don't do this, then, when the timestamp for the pending button
|
||||
// release event is used for the ungrab, the ungrab can fail due to the
|
||||
// timestamp being _earlier_ than CurrentTime.
|
||||
GdkEvent event;
|
||||
memset(&event, 0, sizeof(GdkEvent));
|
||||
event.type = GDK_BUTTON_PRESS;
|
||||
event.button.window = mHiddenWidget->window;
|
||||
event.button.time = nsWindow::sLastButtonPressTime;
|
||||
event.button.time = nsWindow::GetCurrentEventTime();
|
||||
|
||||
// start our drag.
|
||||
GdkDragContext *context = gtk_drag_begin(mHiddenWidget,
|
||||
|
|
|
@ -295,12 +295,10 @@ UpdateLastInputEventTime()
|
|||
nsWindow *nsWindow::sLastDragMotionWindow = NULL;
|
||||
bool nsWindow::sIsDraggingOutOf = false;
|
||||
|
||||
// This is the time of the last button press event. The drag service
|
||||
// uses it as the time to start drags.
|
||||
guint32 nsWindow::sLastButtonPressTime = 0;
|
||||
// Time of the last button release event. We use it to detect when the
|
||||
// drag ended before we could properly setup drag and drop.
|
||||
guint32 nsWindow::sLastButtonReleaseTime = 0;
|
||||
static guint32 sRetryGrabTime;
|
||||
|
||||
static NS_DEFINE_IID(kCDragServiceCID, NS_DRAGSERVICE_CID);
|
||||
|
||||
|
@ -1428,6 +1426,31 @@ SetUserTimeAndStartupIDForActivatedWindow(GtkWidget* aWindow)
|
|||
GTKToolkit->SetDesktopStartupID(EmptyCString());
|
||||
}
|
||||
|
||||
/* static */ guint32
|
||||
nsWindow::GetCurrentEventTime()
|
||||
{
|
||||
static guint32 sLastCurrentEventTime = GDK_CURRENT_TIME;
|
||||
|
||||
guint32 timestamp = gtk_get_current_event_time();
|
||||
|
||||
if (timestamp == GDK_CURRENT_TIME) {
|
||||
timestamp = gdk_x11_display_get_user_time(gdk_display_get_default());
|
||||
|
||||
// The user_time is not updated on all user events, so check that we
|
||||
// haven't returned a more recent timestamp. If so, use the more
|
||||
// recent timestamp to ensure that subsequent requests will override
|
||||
// previous requests. Timestamps are just the least significant bits
|
||||
// of a monotonically increasing function, and so the use of unsigned
|
||||
// overflow arithmetic.
|
||||
if (sLastCurrentEventTime != GDK_CURRENT_TIME &&
|
||||
sLastCurrentEventTime - timestamp <= G_MAXUINT32/2)
|
||||
return sLastCurrentEventTime;
|
||||
}
|
||||
|
||||
sLastCurrentEventTime = timestamp;
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindow::SetFocus(bool aRaise)
|
||||
{
|
||||
|
@ -1881,7 +1904,7 @@ nsWindow::CaptureMouse(bool aCapture)
|
|||
|
||||
if (aCapture) {
|
||||
gtk_grab_add(widget);
|
||||
GrabPointer();
|
||||
GrabPointer(GetCurrentEventTime());
|
||||
}
|
||||
else {
|
||||
ReleaseGrabs();
|
||||
|
@ -1913,7 +1936,7 @@ nsWindow::CaptureRollupEvents(nsIRollupListener *aListener,
|
|||
// real grab is only done when there is no dragging
|
||||
if (!nsWindow::DragInProgress()) {
|
||||
gtk_grab_add(widget);
|
||||
GrabPointer();
|
||||
GrabPointer(GetCurrentEventTime());
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -2739,8 +2762,7 @@ nsWindow::OnButtonPressEvent(GtkWidget *aWidget, GdkEventButton *aEvent)
|
|||
return;
|
||||
}
|
||||
|
||||
// Always save the time of this event
|
||||
sLastButtonPressTime = aEvent->time;
|
||||
// We haven't received the corresponding release event yet.
|
||||
sLastButtonReleaseTime = 0;
|
||||
|
||||
nsWindow *containerWindow = GetContainerWindow();
|
||||
|
@ -4494,7 +4516,7 @@ void
|
|||
nsWindow::EnsureGrabs(void)
|
||||
{
|
||||
if (mRetryPointerGrab)
|
||||
GrabPointer();
|
||||
GrabPointer(sRetryGrabTime);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -4883,7 +4905,7 @@ nsWindow::UpdateTranslucentWindowAlphaInternal(const nsIntRect& aRect,
|
|||
}
|
||||
|
||||
void
|
||||
nsWindow::GrabPointer(void)
|
||||
nsWindow::GrabPointer(guint32 aTime)
|
||||
{
|
||||
LOG(("GrabPointer %d\n", mRetryPointerGrab));
|
||||
|
||||
|
@ -4911,11 +4933,12 @@ nsWindow::GrabPointer(void)
|
|||
GDK_POINTER_MOTION_HINT_MASK |
|
||||
#endif
|
||||
GDK_POINTER_MOTION_MASK),
|
||||
(GdkWindow *)NULL, NULL, GDK_CURRENT_TIME);
|
||||
(GdkWindow *)NULL, NULL, aTime);
|
||||
|
||||
if (retval == GDK_GRAB_NOT_VIEWABLE) {
|
||||
LOG(("GrabPointer: window not viewable; will retry\n"));
|
||||
mRetryPointerGrab = true;
|
||||
sRetryGrabTime = aTime;
|
||||
} else if (retval != GDK_GRAB_SUCCESS) {
|
||||
LOG(("GrabPointer: pointer grab failed: %i\n", retval));
|
||||
// A failed grab indicates that another app has grabbed the pointer.
|
||||
|
|
|
@ -191,6 +191,13 @@ public:
|
|||
NS_IMETHOD MakeFullScreen(bool aFullScreen);
|
||||
NS_IMETHOD HideWindowChrome(bool aShouldHide);
|
||||
|
||||
/**
|
||||
* GetCurrentEventTime guesses a timestamp for the most recent user input
|
||||
* event (when the event is not available). This is intended for pointer
|
||||
* grab or focus requests, for example.
|
||||
*/
|
||||
static guint32 GetCurrentEventTime();
|
||||
|
||||
// utility method, -1 if no change should be made, otherwise returns a
|
||||
// value that can be passed to gdk_window_set_decorations
|
||||
gint ConvertBorderStyles(nsBorderStyle aStyle);
|
||||
|
@ -275,7 +282,7 @@ private:
|
|||
nsIntSize GetSafeWindowSize(nsIntSize aSize);
|
||||
|
||||
void EnsureGrabs (void);
|
||||
void GrabPointer (void);
|
||||
void GrabPointer (guint32 aTime);
|
||||
void ReleaseGrabs (void);
|
||||
|
||||
public:
|
||||
|
|
Загрузка…
Ссылка в новой задаче