From patchwork Tue Jun 4 09:36:00 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "shiju.jose--- via" X-Patchwork-Id: 10974495 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D6D2E912 for ; Tue, 4 Jun 2019 09:37:09 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C4E0720000 for ; Tue, 4 Jun 2019 09:37:09 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B7133287CC; Tue, 4 Jun 2019 09:37:09 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.0 required=2.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 4C3BD20000 for ; Tue, 4 Jun 2019 09:37:09 +0000 (UTC) Received: from localhost ([127.0.0.1]:49397 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hY5sS-0000zl-IZ for patchwork-qemu-devel@patchwork.kernel.org; Tue, 04 Jun 2019 05:37:08 -0400 Received: from eggs.gnu.org ([209.51.188.92]:49268) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hY5rS-0000MY-BO for qemu-devel@nongnu.org; Tue, 04 Jun 2019 05:36:07 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hY5rR-0003zz-AV for qemu-devel@nongnu.org; Tue, 04 Jun 2019 05:36:06 -0400 Received: from pv50p00im-ztdg10021901.me.com ([17.58.6.55]:40890) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hY5rR-0003zC-1i for qemu-devel@nongnu.org; Tue, 04 Jun 2019 05:36:05 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=me.com; s=04042017; t=1559640964; bh=YtIj/xfcacfqcYvQpZJ+7YOy5ZwqniykS7f5iqbxwRI=; h=Content-Type:Mime-Version:Subject:From:Date:Message-Id:To; b=yOhgdlpruWZHDzhG9ej8LtE8StuyJGc2gLzK7pPPPXjZgpXQr93XRioqqrMmNHXCP BJu4n3qMLaxMYjVz9vnxvJELKl56QfyQ6eDLlNOVg/LkJyhreGrsjQ8sJ3wdDI+WFq 7HZufCXZRMdDYiyn2JETWAyz2NR/adErJYKjF7fypsYcIosn8DfhoIIAasLF6K55gd i1SoeLhUY3uOhRlbosR7zySdl4y4HPHO5DsA6h+J5C1d8jNmoEwrjPhjx40A59jlrs +L99QAll0djUZ6ifPNkEUpjlWOW1v4rtag+bkaylpOKz8Cn74kd+bB4eHsvObVhaQB G/Zacmus/ofeA== Received: from [172.18.2.102] (unknown [36.106.167.139]) by pv50p00im-ztdg10021901.me.com (Postfix) with ESMTPSA id 419D1880578; Tue, 4 Jun 2019 09:36:03 +0000 (UTC) Mime-Version: 1.0 (Mac OS X Mail 12.4 \(3445.104.11\)) In-Reply-To: Date: Tue, 4 Jun 2019 17:36:00 +0800 Message-Id: References: To: Gerd Hoffmann , Peter Maydell X-Mailer: Apple Mail (2.3445.104.11) X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2019-06-04_07:, , signatures=0 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=0 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 mlxscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1812120000 definitions=main-1906040064 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 17.58.6.55 Subject: [Qemu-devel] [PATCH 1/2] ui/cocoa: Fix absolute input device grabbing issue on Mojave X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Chen Zhang via Qemu-devel From: "shiju.jose--- via" Reply-To: Chen Zhang Cc: qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP On Mojave, absolute input device, i.e. tablet, had trouble re-grabbing the cursor in re-entry into the virtual screen area. In some cases, the `window` property of NSEvent object was nil after cursor exiting from window, hinting that the `-locationInWindow` method would return value in screen coordinates. The current implementation used raw locations from NSEvent without considering whether the value was for the window coordinates or the macOS screen coordinates, nor the zooming factor for Zoom-to-Fit in fullscreen mode. In fullscreen mode, the fullscreen cocoa window might not be the key window, therefore the location of event in virtual coordinates should suffice. This patches fixed boundary check methods for cursor in normal and fullscreen with/without Zoom-to-Fit in Mojave. Note: CGRect, -convertRectToScreen: and -convertRectFromScreen: were used in coordinates conversion for compatibility reason. Signed-off-by: Chen Zhang --- ui/cocoa.m | 43 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/ui/cocoa.m b/ui/cocoa.m index 420b2411c1..474d44cb9f 100644 --- a/ui/cocoa.m +++ b/ui/cocoa.m @@ -405,6 +405,41 @@ QemuCocoaView *cocoaView; return (p.x > -1 && p.x < screen.width && p.y > -1 && p.y < screen.height); } +/* Get location of event and convert to virtual screen coordinate */ +- (CGPoint) screenLocationOfEvent:(NSEvent *)ev +{ + NSWindow *eventWindow = [ev window]; + // XXX: Use CGRect and -convertRectFromScreen: to support macOS 10.10 + CGRect r = CGRectZero; + r.origin = [ev locationInWindow]; + if (!eventWindow) { + if (!isFullscreen) { + return [[self window] convertRectFromScreen:r].origin; + } else { + CGPoint locationInSelfWindow = [[self window] convertRectFromScreen:r].origin; + CGPoint loc = [self convertPoint:locationInSelfWindow fromView:nil]; + if (stretch_video) { + loc.x /= cdx; + loc.y /= cdy; + } + return loc; + } + } else if ([[self window] isEqual:eventWindow]) { + if (!isFullscreen) { + return r.origin; + } else { + CGPoint loc = [self convertPoint:r.origin fromView:nil]; + if (stretch_video) { + loc.x /= cdx; + loc.y /= cdy; + } + return loc; + } + } else { + return [[self window] convertRectFromScreen:[eventWindow convertRectToScreen:r]].origin; + } +} + - (void) hideCursor { if (!cursor_hide) { @@ -704,7 +739,8 @@ QemuCocoaView *cocoaView; int keycode = 0; bool mouse_event = false; static bool switched_to_fullscreen = false; - NSPoint p = [event locationInWindow]; + // Location of event in virtual screen coordinates + NSPoint p = [self screenLocationOfEvent:event]; switch ([event type]) { case NSEventTypeFlagsChanged: @@ -815,7 +851,10 @@ QemuCocoaView *cocoaView; break; case NSEventTypeMouseMoved: if (isAbsoluteEnabled) { - if (![self screenContainsPoint:p] || ![[self window] isKeyWindow]) { + // Cursor re-entered into a window might generate events bound to screen coordinates + // and `nil` window property, and in full screen mode, current window might not be + // key window, where event location alone should suffice. + if (![self screenContainsPoint:p] || !([[self window] isKeyWindow] || isFullscreen)) { if (isMouseGrabbed) { [self ungrabMouse]; }