Skip to content
This repository has been archived by the owner on Nov 4, 2023. It is now read-only.

Bring in multiscreen and workspace support #360

Draft
wants to merge 277 commits into
base: xenial
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
277 commits
Select commit Hold shift + click to select a range
2f4159a
add hover item to screens
Jan 23, 2017
1062cbb
drop empty line
Jan 23, 2017
23f461e
merge prereq
Jan 23, 2017
c6a9a00
Added screens::activate
nickdedekind Jan 23, 2017
13a7e08
fixups
nickdedekind Jan 23, 2017
0487745
fixed whitespace again
nickdedekind Jan 23, 2017
3160af0
merge prereq
Jan 23, 2017
8f35850
activate the other screen on timeout
Jan 23, 2017
0144005
add icon, adjust visuals
Jan 23, 2017
6848933
merge with trunk
nickdedekind Jan 27, 2017
450ce31
active screen
nickdedekind Feb 2, 2017
e73e035
make workspaces a listview
Feb 3, 2017
beafaa2
merge prereq
Feb 3, 2017
4816066
activate screen
nickdedekind Feb 3, 2017
a70a372
updated mock
nickdedekind Feb 3, 2017
7f5356b
make it a listview, update to latest api
Feb 3, 2017
bc9e93f
some more work on the workspace preview spread
Feb 7, 2017
1c77322
add drag and drop wor workspaces between screens
Feb 9, 2017
a6cff49
api version bump
nickdedekind Feb 10, 2017
5d0ab19
play with the size
Feb 10, 2017
f57eab2
merge prereq
Feb 10, 2017
54c109e
merged with trunk
nickdedekind Feb 10, 2017
ec5e816
add scrolling areas
Feb 13, 2017
0278b41
merge trunk
Feb 13, 2017
051de42
fix imports
Feb 14, 2017
94c2a09
use qtmir-api
nickdedekind Feb 17, 2017
14f1570
added workspaces
nickdedekind Feb 17, 2017
53626b8
removed screen mock
nickdedekind Feb 17, 2017
792e2c9
add support for dragging apps out of the spread
Feb 20, 2017
f20331b
improve dragging and hover scrolling
Feb 20, 2017
563bcf4
optimize it a little
Feb 20, 2017
2710ca1
policy override
nickdedekind Feb 22, 2017
d53ef7f
merged trunk
nickdedekind Feb 23, 2017
886352b
merged with parent
nickdedekind Feb 23, 2017
01de8a1
merge new prereq
Feb 23, 2017
17872af
merge new prereq
Feb 23, 2017
6c68622
make use of actual workspace model instead of dummy ListModels
Feb 23, 2017
44063d4
properly create and destroy workspaces
Feb 23, 2017
925a0a9
more workspaces
nickdedekind Feb 24, 2017
9a5c01f
shellapp->unityapp
nickdedekind Feb 24, 2017
e4d9829
removed tlwm from workspace
nickdedekind Feb 24, 2017
f1035e3
TopLevelWindowModel per workspace
nickdedekind Feb 28, 2017
747a319
packaging fix
nickdedekind Feb 28, 2017
a0ca0a0
Workspaces revisited
nickdedekind Mar 1, 2017
60b3653
mem management
nickdedekind Mar 1, 2017
e3f4e0a
mock
nickdedekind Mar 1, 2017
8b8a6fa
SurfaceManager singleton
nickdedekind Mar 1, 2017
d70f5f5
Better window management mocks
nickdedekind Mar 1, 2017
327be6d
fixed crash on delete
nickdedekind Mar 1, 2017
43cba0c
more SurfaceManager singleton
nickdedekind Mar 2, 2017
781c37d
merge prereq
Mar 2, 2017
2a2e38c
Fixed crash on exit
nickdedekind Mar 2, 2017
7d9e47d
check for surfaces
nickdedekind Mar 2, 2017
47aff7b
mock fixes
nickdedekind Mar 2, 2017
0373f3c
allow qml access to move
nickdedekind Mar 2, 2017
1d9e43b
merge prereq
Mar 2, 2017
a705d30
dynamic remove surface
nickdedekind Mar 2, 2017
b3c03fa
added workspace check
nickdedekind Mar 3, 2017
27b74cd
Fixed mocking WMPolicy
nickdedekind Mar 3, 2017
2b18653
fixes for workspaces
nickdedekind Mar 4, 2017
3a0ec61
update to latest backend code
Mar 6, 2017
3a2b921
Fixed WorkspaceManager.activeWorkspace=WorkspaceProxy
nickdedekind Mar 6, 2017
f820352
cpp ownership
nickdedekind Mar 6, 2017
364028b
merge prereq
Mar 7, 2017
4e8f28f
Fixed duplicate apps
nickdedekind Mar 7, 2017
1e54aa3
merge prereq
Mar 8, 2017
78a1984
bump u-a-l version requirement
Mar 8, 2017
79f3c07
added mirtest deps
nickdedekind Mar 8, 2017
53904db
merge prereq
Mar 8, 2017
325ade4
use a toplevelwindowmodel per workspace
Mar 8, 2017
20b95b0
fixed crash on remove ws
nickdedekind Mar 8, 2017
75d41d4
merge prereq
Mar 8, 2017
1721c43
Screen.currentWorkspace
nickdedekind Mar 8, 2017
d4d6901
Added testShellApplication
nickdedekind Mar 8, 2017
ab4ffb8
merge prereq
Mar 9, 2017
67df091
some improvements
Mar 9, 2017
77b7257
some more fixes
Mar 9, 2017
9b5b6c1
add close button on hover
Mar 9, 2017
fa498d0
fix imports
Mar 9, 2017
b9739cb
fix workspace preview scaling
Mar 9, 2017
b4c4b67
add outputTypeName to Screen
Mar 10, 2017
bbd0b9b
WMScreens attached property & screen fixes
nickdedekind Mar 10, 2017
7367193
proxy syncs with source
nickdedekind Mar 10, 2017
d73aca0
merge prereq
Mar 13, 2017
6c275e4
minor tweaks
Mar 13, 2017
548b0c6
Move window to Workspace
nickdedekind Mar 14, 2017
6008b1d
merge prereq
Mar 14, 2017
61ee479
finalize drag and drop for apps to another workspace
Mar 14, 2017
b50f6a9
fix drag and drop of applications
Mar 14, 2017
888c73c
highlight active workspace
Mar 14, 2017
bcbc40d
focus
nickdedekind Mar 14, 2017
abaacf0
add feature to drop to the left/right of a workspace
Mar 15, 2017
f4d6026
merge prereq
Mar 15, 2017
cf4f2ea
better focus condensing
nickdedekind Mar 15, 2017
ccd07fa
add text to drop targets
Mar 15, 2017
f4827a6
merge prereq
Mar 15, 2017
fb33178
merged with trunk
nickdedekind Mar 15, 2017
3e9bf40
merged with parent
nickdedekind Mar 15, 2017
f222265
merge prereq
Mar 16, 2017
be6c6a3
add missing graphics file
Mar 16, 2017
67f725b
cancel dnd operation properly
Mar 16, 2017
64a046c
Added ErrorApplication to debian
nickdedekind Mar 16, 2017
46da459
use correct graphic
Mar 16, 2017
42e4c1a
merge parent
Mar 16, 2017
dcb2e88
merge prereq
Mar 16, 2017
6e2f048
don't apply transitions if a delegate is created while we're in spread
Mar 16, 2017
0bcac19
improve listview animations and handling
Mar 16, 2017
e174ec3
TLWM as workspace property
nickdedekind Mar 17, 2017
83d36b3
fix screen sizes in mocks
Mar 17, 2017
ca7d40d
merged with prereq
nickdedekind Mar 17, 2017
117f2d8
fix the mock to not be funky with screen sizes at startup
Mar 17, 2017
942c252
implement our own popup
Mar 17, 2017
6efc4c4
fix workspace drag reordering again
Mar 17, 2017
421d2a7
fixed move workspace content order
nickdedekind Mar 17, 2017
12ff9b4
merged prereq
nickdedekind Mar 17, 2017
fbc9a88
removed old headers
nickdedekind Mar 20, 2017
785f8e4
merged parent
nickdedekind Mar 20, 2017
735fd4f
update normal geo directly on load
nickdedekind Mar 20, 2017
e4499be
bring the splash screen back, drop the screenshot image (surfaces kee…
Mar 21, 2017
59e31a6
merge
Mar 21, 2017
7dd8766
merge
Mar 21, 2017
07f86b2
some tweaks and cleanups
Mar 21, 2017
7e68062
prevent closing a workspace if it's the last one
Mar 21, 2017
b8150af
apply nick's patch for fixing tiny window sizes
Mar 21, 2017
ac93886
Fixed issues with syncing
nickdedekind Mar 22, 2017
b7ad64f
removed debug
nickdedekind Mar 22, 2017
71284ff
merged with parent
nickdedekind Mar 22, 2017
8fdf9a4
merge prereq
Mar 22, 2017
4f8a090
add WorkspaceSwitcher
Mar 22, 2017
15874dd
focus window gets global shortcuts
nickdedekind Mar 22, 2017
ce2ac7d
merged with parent
nickdedekind Mar 22, 2017
27ac232
WindowManagerObjects bindings in UnityTestCase
nickdedekind Mar 22, 2017
ae545ea
merged with prereq
nickdedekind Mar 22, 2017
d1867f5
fixed mock stretch sizing
nickdedekind Mar 22, 2017
d1c0163
make it build with older Qt
Mar 22, 2017
2317308
fix the panelState nocking in tst_DesktopStage
Mar 23, 2017
58e65b8
make testDesktopStage work again
Mar 23, 2017
013e5b1
don't reach out of context
Mar 23, 2017
7b1ff45
merge
Mar 23, 2017
d55286b
merge parent
Mar 23, 2017
4711c55
fixed recursion
nickdedekind Mar 23, 2017
93fa06f
merged parent
nickdedekind Mar 23, 2017
f670b0e
Added Workspace config
nickdedekind Mar 23, 2017
211fde5
merged prereq
nickdedekind Mar 23, 2017
80fc88d
fixed workspace crash
nickdedekind Mar 23, 2017
02d6bc0
workspace switcher now working
Mar 23, 2017
90d9bd9
Destroy Workspaces
nickdedekind Mar 23, 2017
7b68b97
merged prereq
nickdedekind Mar 23, 2017
916a0ea
mreged trunk
nickdedekind Mar 24, 2017
bfeaf9d
merged parent
nickdedekind Mar 24, 2017
acb5d8b
merged parent
nickdedekind Mar 24, 2017
c9164f6
fix focus issue and activate the surface once dropped on a workspace
Mar 27, 2017
37d6ae4
fix testPhoneStage
Mar 27, 2017
3667e72
fix testTabletStage
Mar 27, 2017
d55f783
fixed proxy syncing
nickdedekind Mar 27, 2017
c403943
merged with pre-req
nickdedekind Mar 27, 2017
ee0e9fd
removed debug log
nickdedekind Mar 27, 2017
c56d828
removed InputWindow
nickdedekind Mar 27, 2017
5d2d85c
fixed surfaceManager in tstShell
nickdedekind Mar 27, 2017
fd604be
merged with parent
nickdedekind Mar 27, 2017
4236ded
fixed surfacelist in test
nickdedekind Mar 27, 2017
be6cc65
removed Unity.Debug import
nickdedekind Mar 28, 2017
abe56ae
install libmockwindowmanagmentpolicy, needed for installed tests
Mar 28, 2017
b8a5dcc
add Windowmanager mock dir to LD_LIBRARY_PATH
Mar 28, 2017
1897f10
fix panel tests
Mar 28, 2017
5174a14
decrease timer timeout for hiding the workspaceswitcher
Mar 28, 2017
7283c79
merge prereq
Mar 28, 2017
91e99ec
merge
Mar 28, 2017
e1ba4b7
Fixed shortcuts parented to non QuickItems
nickdedekind Mar 28, 2017
5d5daa3
Panel bidnings for app menus
nickdedekind Mar 28, 2017
e88688e
panelState fixes
nickdedekind Mar 28, 2017
87d6679
Fixed PhoneStage & ShellWithPin tests
nickdedekind Mar 28, 2017
b5e6fbf
Stage fixes for panelState
nickdedekind Mar 28, 2017
03ae81f
more test fixes
nickdedekind Mar 29, 2017
27a262b
merged parent
nickdedekind Mar 29, 2017
9eb2692
more test fixes
nickdedekind Mar 29, 2017
3fdf3b5
Added requestActivate to view
nickdedekind Mar 29, 2017
5032e8f
merge prereq
Mar 29, 2017
28d0c9b
fix testApplicationWindow
Mar 30, 2017
8cd3b33
Mock fixes & test fixes
nickdedekind Mar 30, 2017
43f0793
fixed GlobalShortcut test
nickdedekind Mar 30, 2017
f661fa4
fix testDesktopStage
Mar 30, 2017
187b3f7
some more tabletstage test fixes
Mar 30, 2017
86a9c75
merge prereq
Mar 30, 2017
84880a7
some more test fixes
Mar 30, 2017
cc5a4ec
testShell should be working again
Mar 31, 2017
4944c2a
don't show minimized apps in the workspace previews
Mar 31, 2017
8ff8a21
merged with trunk
nickdedekind Mar 31, 2017
ae24227
merged with trunk
nickdedekind Mar 31, 2017
2fc9b0a
Added Mouse and KB controls
nickdedekind Mar 31, 2017
545b58b
don't really activate a workspace just yet when clicking on it
Mar 31, 2017
805f30c
Dont allow proxy to be used as current workspace
nickdedekind Apr 3, 2017
945dd8e
merged pre-req
nickdedekind Apr 3, 2017
d7a2837
Fixed wm policy init
nickdedekind Apr 3, 2017
3212fb9
merged with pre-req
nickdedekind Apr 3, 2017
0b8de44
fixed sync end
nickdedekind Apr 3, 2017
b5135e7
merged pre-req
nickdedekind Apr 3, 2017
e2b3955
display id
nickdedekind Apr 3, 2017
27430d5
ScreenConfig
nickdedekind Apr 3, 2017
9b92f18
merged prereq
nickdedekind Apr 3, 2017
ea49134
display config storage
nickdedekind Apr 3, 2017
a81362c
merged prereq
nickdedekind Apr 3, 2017
2adba16
mock screen active
nickdedekind Apr 4, 2017
e9f4c43
merged pre-req
nickdedekind Apr 4, 2017
06f42e7
isSameAs
nickdedekind Apr 5, 2017
b6ab28f
merged pre-req
nickdedekind Apr 5, 2017
fb0297b
Active Scree visuals in Spread
nickdedekind Apr 5, 2017
842cadc
removed lastClickedWorkspace
nickdedekind Apr 5, 2017
4cbd70f
test fixes
Apr 5, 2017
22d678a
merge
Apr 5, 2017
e058685
rework workspace switcher for up/down navigation for screens
Apr 5, 2017
de450aa
removed debug
nickdedekind Apr 6, 2017
e961d7c
Merge remote-tracking branch 'screens-workspaces-switcher' into xenia…
mariogrip Jul 2, 2019
5b9edb1
Fixup TabletStage tests after merge with multi monitor changes
mariogrip Jul 6, 2019
b42823e
Add missing copyright to new files
mariogrip Jul 6, 2019
7f53309
Fixup panel tests after bad merge
mariogrip Jul 6, 2019
797b062
Test trying to find unknown child
mariogrip Jul 6, 2019
c4c05ce
Merge remote-tracking branch 'origin/xenial_-_edge' into xenial_-_edg…
mariogrip Sep 13, 2019
dabba02
Make workspaces disabled by default (gsetting to enable)
mariogrip Sep 14, 2019
e729429
Make sure right tutorial gets skipped if spread has been shown
mariogrip Sep 15, 2019
a4b2707
Fix panel test by making verifying synchronous
mariogrip Sep 15, 2019
71d53fc
Fix multiscreen tests
mariogrip Sep 15, 2019
60db746
Merge remote-tracking branch 'origin/xenial_-_edge' into xenial_-_edg…
mariogrip Sep 23, 2019
d1b0fbf
Make sure to clear m_previousWindow when the window is deleted
mariogrip Sep 29, 2019
f3ada84
Disable workspace switcher and FakeSurface if workspace is disabled
mariogrip Sep 29, 2019
bf5076c
[tests] Make sure to set surface to null if surface is not live
mariogrip Sep 29, 2019
c549645
[tests] Make sure to close spread on cleanup
mariogrip Sep 29, 2019
fbba3e5
[tests] Set var that got removed but should be set on live surface
mariogrip Sep 29, 2019
4c873ec
[tests] Add downwards swipe function as this will be needed for works…
mariogrip Sep 29, 2019
a47895e
[Stage] Use correct close function and Make sure to trigger propery
mariogrip Sep 29, 2019
00e5c7b
[VirtualTouchPad] Move need for windowManager out to main root
mariogrip Sep 30, 2019
77038f1
[tests] Skip two compeare functions (FIXME)
mariogrip Sep 30, 2019
fa0af33
Make sure to display promt animation correctly on stopped promt
mariogrip Sep 30, 2019
efc760f
[WM] Move surfaceManager to local memeber with same tread destroy signal
mariogrip Oct 2, 2019
3e71837
[Shell] Make sure we unset WM objects before destroying
mariogrip Oct 2, 2019
00e1ec0
Merge remote-tracking branch 'origin/xenial' into xenial_-_edge_-_mul…
mariogrip Aug 24, 2020
956eecf
Fix tests after bad merge
mariogrip Aug 26, 2020
5e9a35f
Fix input tests and remove unused varables
mariogrip Aug 26, 2020
632c6ac
[qml/launcher] Show drawer if bfb is pressed even if no apps are open
mariogrip Aug 26, 2020
dddb225
[tests/PhoneStage] Remove expected fail as surprise launch works now
mariogrip Aug 26, 2020
9de5082
[qml/OrientedShell] screens is now static
mariogrip Aug 26, 2020
11d0d63
[tests] Temporarily skip 2 non critical tests
mariogrip Aug 26, 2020
c5241da
Merge remote-tracking branch 'origin/xenial' into xenial_-_edge_-_qt-…
mariogrip Jan 16, 2021
d8e3e78
Merge remote-tracking branch 'origin/xenial_-_qt-5-12' into xenial_-_…
mariogrip Jan 16, 2021
aab8ce6
Merge remote-tracking branch 'origin/xenial' into xenial_-_edge_-_qt-…
mariogrip Jan 19, 2021
0ddcd29
tests: qmltests: greeter: enable working test
mariogrip Jan 26, 2021
e87603d
tests: qmltests: shell: ExpectFail on broken compeare instead
mariogrip Jan 26, 2021
82c223b
tests: Fix tests after bringing in qt 5.12 fixes
mariogrip Jan 26, 2021
33ceebd
Merge remote-tracking branch 'origin/xenial' into xenial_-_edge
mariogrip Apr 7, 2021
e07a351
tests: re-enable fixed test
mariogrip Apr 8, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ find_package(Qt5Network 5.6 REQUIRED)
find_package(Qt5Xml 5.6 REQUIRED)

pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application=27)
pkg_check_modules(QTMIRSERVER REQUIRED qtmirserver>=0.6.0)
pkg_check_modules(GEONAMES REQUIRED geonames>=0.2)
pkg_check_modules(GIO REQUIRED gio-2.0>=2.32)
pkg_check_modules(GLIB REQUIRED glib-2.0>=2.32)
Expand All @@ -87,6 +88,7 @@ pkg_check_modules(QTDBUSTEST REQUIRED
libqtdbustest-1
libqtdbusmock-1
)
pkg_check_modules(MIRAL REQUIRED miral)

### Check UbuntuGestures private headers. No pkg-config (.pc) file is provided for them
find_path(UBUNTUGESTUREPRIV
Expand Down Expand Up @@ -121,7 +123,9 @@ if(SHELL_PLUGINDIR STREQUAL "")
message(FATAL_ERROR "Could not determine plugin import dir.")
endif()

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fno-permissive -pedantic -Wall -Wextra")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-permissive -pedantic -Wall -Wextra")

set (CMAKE_CXX_STANDARD 14)

if ("${CMAKE_BUILD_TYPE}" STREQUAL "release" OR "${CMAKE_BUILD_TYPE}" STREQUAL "relwithdebinfo")
option(Werror "Treat warnings as errors" ON)
Expand Down
10 changes: 10 additions & 0 deletions data/com.canonical.Unity8.gschema.xml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,16 @@
<summary>Whether the OSK switch should be visible</summary>
<description>Toggle the visibility of the OSK switch</description>
</key>
<key type="b" name="enable-workspace">
<default>false</default>
<summary>Enable or disable workspaces</summary>
<description>Toggle the availability of workspaces</description>
</key>
<key type="b" name="force-enable-workspace">
<default>false</default>
<summary>Force enable workspaces</summary>
<description>Forces workspaces availability even when not in windowed mode</description>
</key>
</schema>

<schema path="/com/canonical/unity8/greeter/" id="com.canonical.Unity8.Greeter" gettext-domain="unity8">
Expand Down
6 changes: 6 additions & 0 deletions debian/control
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ Build-Depends:
libpam0g-dev,
libpulse-dev,
libqmenumodel-dev (>= 0.2.12),
libqtmirserver-dev (>= 0.6.0),
libqt5sql5-sqlite,
libqt5svg5-dev,
libqt5xmlpatterns5-dev,
Expand All @@ -46,6 +47,7 @@ Build-Depends:
libx11-dev[!arm64 !armhf],
libxcb1-dev[!arm64 !armhf],
libxi-dev[!arm64 !armhf],
mirtest-dev,
pkg-config,
python3-all:any,
python3-setuptools,
Expand Down Expand Up @@ -73,6 +75,9 @@ Build-Depends:
ttf-ubuntu-font-family,
ubports-wallpapers,
xvfb,
# mirtest pkgconfig requires these, but doesn't have a deb dependency. Bug lp:1633537
libboost-filesystem-dev,
libboost-system-dev,
Standards-Version: 3.9.4
Homepage: https://github.com/ubports/unity8
Vcs-Git: https://github.com/ubports/unity8
Expand Down Expand Up @@ -122,6 +127,7 @@ Depends:
qml-module-qtsysteminfo,
qtdeclarative5-qtmir-plugin (>= 0.4.8),
qtdeclarative5-ubuntu-telephony0.1,
qtmir-desktop (>= 0.6.0) | qtmir-android (>= 0.6.0),
ubuntu-system-settings (>= 0.4),
unity-launcher-impl-13,
unity8-common (= ${source:Version}),
Expand Down
5 changes: 5 additions & 0 deletions debian/unity8.install
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@ usr/share/unity8/Launcher
usr/share/unity8/OrientedShell.qml
usr/share/unity8/Panel
usr/share/unity8/Rotation
usr/share/unity8/ErrorApplication.qml
usr/share/unity8/qmldir
usr/share/unity8/Shell.qml
usr/share/unity8/ShellApplication.qml
usr/share/unity8/ShellNotifier.qml
usr/share/unity8/ShellScreen.qml
usr/share/unity8/Stage
usr/share/unity8/Tutorial
usr/share/unity8/Wizard
Expand Down
1 change: 1 addition & 0 deletions plugins/Cursor/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ set(QMLPLUGIN_SRC
CursorImageInfo.cpp
CursorImageProvider.cpp
MousePointer.cpp
InputDispatcherFilter.cpp
# We need to run moc on this header
${APPLICATION_API_INCLUDEDIR}/unity/shell/application/MirMousePointerInterface.h
)
Expand Down
175 changes: 175 additions & 0 deletions plugins/Cursor/InputDispatcherFilter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
/*
* Copyright (C) 2016 Canonical, Ltd.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License version 3, as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
* SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include "InputDispatcherFilter.h"
#include "MousePointer.h"

#include <QEvent>
#include <QGuiApplication>
#include <QQuickWindow>
#include <QScreen>
#include <QtMath>
#include <qpa/qplatformnativeinterface.h>
#include <qpa/qplatformscreen.h>

InputDispatcherFilter *InputDispatcherFilter::instance()
{
static InputDispatcherFilter filter;
return &filter;
}

InputDispatcherFilter::InputDispatcherFilter(QObject *parent)
: QObject(parent)
, m_pushing(false)
{
QPlatformNativeInterface *ni = QGuiApplication::platformNativeInterface();
m_inputDispatcher = static_cast<QObject*>(ni->nativeResourceForIntegration("InputDispatcher"));
if (m_inputDispatcher) {
m_inputDispatcher->installEventFilter(this);
}
}

void InputDispatcherFilter::registerPointer(MousePointer *pointer)
{
// allow first registered pointer to be visible.
m_pointers.insert(pointer);
}

void InputDispatcherFilter::unregisterPointer(MousePointer *pointer)
{
m_pointers.remove(pointer);
}

bool InputDispatcherFilter::eventFilter(QObject *o, QEvent *e)
{
if (o != m_inputDispatcher) return false;

switch (e->type()) {
case QEvent::MouseMove:
case QEvent::MouseButtonPress:
case QEvent::MouseButtonRelease:
{
// if we don't have any pointers, filter all mouse events.
auto pointer = currentPointer();
if (!pointer) return true;

QMouseEvent* me = static_cast<QMouseEvent*>(e);

// Local position gives relative change of mouse pointer.
QPointF movement = me->localPos();

// Adjust the position
QPointF oldPos = pointer->window()->geometry().topLeft() + pointer->position();
QPointF newPos = adjustedPositionForMovement(oldPos, movement);

QScreen* currentScreen = screenAt(newPos);
if (currentScreen) {
QRect screenRect = currentScreen->geometry();
qreal newX = (oldPos + movement).x();
qreal newY = (oldPos + movement).y();

if (newX <= screenRect.left() && newY < screenRect.top() + pointer->topBoundaryOffset()) { // top left corner
const auto distance = qSqrt(qPow(newX, 2) + qPow(newY- screenRect.top() - pointer->topBoundaryOffset(), 2));
Q_EMIT pushedTopLeftCorner(currentScreen, qAbs(distance), me->buttons());
m_pushing = true;
} else if (newX >= screenRect.right()-1 && newY < screenRect.top() + pointer->topBoundaryOffset()) { // top right corner
const auto distance = qSqrt(qPow(newX-screenRect.right(), 2) + qPow(newY - screenRect.top() - pointer->topBoundaryOffset(), 2));
Q_EMIT pushedTopRightCorner(currentScreen, qAbs(distance), me->buttons());
m_pushing = true;
} else if (newX < 0 && newY >= screenRect.bottom()-1) { // bottom left corner
const auto distance = qSqrt(qPow(newX, 2) + qPow(newY-screenRect.bottom(), 2));
Q_EMIT pushedBottomLeftCorner(currentScreen, qAbs(distance), me->buttons());
m_pushing = true;
} else if (newX >= screenRect.right()-1 && newY >= screenRect.bottom()-1) { // bottom right corner
const auto distance = qSqrt(qPow(newX-screenRect.right(), 2) + qPow(newY-screenRect.bottom(), 2));
Q_EMIT pushedBottomRightCorner(currentScreen, qAbs(distance), me->buttons());
m_pushing = true;
} else if (newX < screenRect.left()) { // left edge
Q_EMIT pushedLeftBoundary(currentScreen, qAbs(newX), me->buttons());
m_pushing = true;
} else if (newX >= screenRect.right()) { // right edge
Q_EMIT pushedRightBoundary(currentScreen, newX - (screenRect.right() - 1), me->buttons());
m_pushing = true;
} else if (newY < screenRect.top() + pointer->topBoundaryOffset()) { // top edge
Q_EMIT pushedTopBoundary(currentScreen, qAbs(newY - screenRect.top() - pointer->topBoundaryOffset()), me->buttons());
m_pushing = true;
} else if (Q_LIKELY(newX > 0 && newX < screenRect.right()-1 && newY > 0 && newY < screenRect.bottom()-1)) { // normal pos, not pushing
if (m_pushing) {
Q_EMIT pushStopped(currentScreen);
m_pushing = false;
}
}
}

// Send the event
QMouseEvent eCopy(me->type(), me->localPos(), newPos, me->button(), me->buttons(), me->modifiers());
eCopy.setTimestamp(me->timestamp());
o->event(&eCopy);
return true;
}
default:
break;
}
return false;
}

QPointF InputDispatcherFilter::adjustedPositionForMovement(const QPointF &pt, const QPointF &movement) const
{
QPointF adjusted = pt + movement;

auto screen = screenAt(adjusted); // first check if our move was to a screen with an enabled pointer.
if (screen) {
return adjusted;
} else if ((screen = screenAt(pt))) { // then check if our old position was valid
QRectF screenBounds = screen->geometry();
// bound the new position to the old screen geometry
adjusted.rx() = qMax(screenBounds.left(), qMin(adjusted.x(), screenBounds.right()-1));
adjusted.ry() = qMax(screenBounds.top(), qMin(adjusted.y(), screenBounds.bottom()-1));
} else {
auto screens = QGuiApplication::screens();

// center of first screen with a pointer.
Q_FOREACH(QScreen* screen, screens) {
Q_FOREACH(MousePointer* pointer, m_pointers) {
if (pointer->isEnabled() && pointer->screen() == screen) {
return screen->geometry().center();
}
}
}
}
return adjusted;
}

QScreen *InputDispatcherFilter::screenAt(const QPointF &pt) const
{
Q_FOREACH(MousePointer* pointer, m_pointers) {
if (!pointer->isEnabled()) continue;

QScreen* screen = pointer->screen();
if (screen && screen->geometry().contains(pt.toPoint()))
return screen;
}
return nullptr;
}

MousePointer *InputDispatcherFilter::currentPointer() const
{
Q_FOREACH(MousePointer* pointer, m_pointers) {
if (!pointer->isEnabled()) continue;
return pointer;
}
return nullptr;
}
62 changes: 62 additions & 0 deletions plugins/Cursor/InputDispatcherFilter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* Copyright (C) 2016 Canonical, Ltd.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License version 3, as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
* SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef INPUTDISPATCHERFILTER_H
#define INPUTDISPATCHERFILTER_H

#include <QObject>
#include <QPointF>
#include <QSet>

class MousePointer;
class QScreen;

class InputDispatcherFilter : public QObject
{
Q_OBJECT
public:
static InputDispatcherFilter *instance();

void registerPointer(MousePointer* pointer);
void unregisterPointer(MousePointer* pointer);

Q_SIGNALS:
void pushedLeftBoundary(QScreen* screen, qreal amount, Qt::MouseButtons buttons);
void pushedRightBoundary(QScreen* screen, qreal amount, Qt::MouseButtons buttons);
void pushedTopBoundary(QScreen* screen, qreal amount, Qt::MouseButtons buttons);
void pushedTopLeftCorner(QScreen* screen, qreal amount, Qt::MouseButtons buttons);
void pushedTopRightCorner(QScreen* screen, qreal amount, Qt::MouseButtons buttons);
void pushedBottomLeftCorner(QScreen* screen, qreal amount, Qt::MouseButtons buttons);
void pushedBottomRightCorner(QScreen* screen, qreal amount, Qt::MouseButtons buttons);
void pushStopped(QScreen* screen);

protected:
InputDispatcherFilter(QObject* parent = nullptr);

bool eventFilter(QObject *o, QEvent *e) override;

QPointF adjustedPositionForMovement(const QPointF& pt, const QPointF& movement) const;
QScreen* screenAt(const QPointF& pt) const;

MousePointer* currentPointer() const;

private:
QObject* m_inputDispatcher;
QSet<MousePointer*> m_pointers;
bool m_pushing;
};

#endif // INPUTDISPATCHERFILTER_H
Loading