Mir

Merge lp:~alan-griffiths/mir/move-miral-to-mir into lp:mir

Proposed by Alan Griffiths
Status: Merged
Approved by: Gerry Boland
Approved revision: no longer in the source branch.
Merged at revision: 4235
Proposed branch: lp:~alan-griffiths/mir/move-miral-to-mir
Merge into: lp:mir
Diff against target: 18088 lines (+17392/-3)
127 files modified
CMakeLists.txt (+0/-2)
cmake/FindPIL.cmake (+8/-0)
debian/changelog (+4/-1)
debian/control (+51/-0)
debian/libmiral-dev.install (+3/-0)
debian/libmiral2.install (+1/-0)
debian/libmiral2.symbols (+399/-0)
debian/libmirclientcpp-dev.install (+2/-0)
debian/miral-examples.install (+9/-0)
examples/CMakeLists.txt (+3/-0)
examples/miral-kiosk/CMakeLists.txt (+12/-0)
examples/miral-kiosk/kiosk_main.cpp (+94/-0)
examples/miral-kiosk/kiosk_window_manager.cpp (+148/-0)
examples/miral-kiosk/kiosk_window_manager.h (+52/-0)
examples/miral-kiosk/sw_splash.cpp (+173/-0)
examples/miral-kiosk/sw_splash.h (+44/-0)
examples/miral-shell/CMakeLists.txt (+65/-0)
examples/miral-shell/decoration_provider.cpp (+666/-0)
examples/miral-shell/decoration_provider.h (+119/-0)
examples/miral-shell/desktop/CMakeLists.txt (+12/-0)
examples/miral-shell/desktop/miral-shell.desktop.in (+18/-0)
examples/miral-shell/desktop/ubuntu-logo.svg (+27/-0)
examples/miral-shell/floating_window_manager.cpp (+801/-0)
examples/miral-shell/floating_window_manager.h (+146/-0)
examples/miral-shell/miral-app.sh (+51/-0)
examples/miral-shell/miral-desktop.sh (+45/-0)
examples/miral-shell/miral-run.sh (+17/-0)
examples/miral-shell/miral-screencast.sh (+48/-0)
examples/miral-shell/miral-xrun.sh (+45/-0)
examples/miral-shell/shell_main.cpp (+98/-0)
examples/miral-shell/spinner/CMakeLists.txt (+67/-0)
examples/miral-shell/spinner/eglapp.cpp (+83/-0)
examples/miral-shell/spinner/eglapp.h (+33/-0)
examples/miral-shell/spinner/eglspinner.cpp (+372/-0)
examples/miral-shell/spinner/miregl.cpp (+239/-0)
examples/miral-shell/spinner/miregl.h (+67/-0)
examples/miral-shell/spinner/png2header.py (+87/-0)
examples/miral-shell/spinner/splash.h (+45/-0)
examples/miral-shell/tiling_window_manager.cpp (+688/-0)
examples/miral-shell/tiling_window_manager.h (+140/-0)
examples/miral-shell/titlebar_config.cpp (+38/-0)
examples/miral-shell/titlebar_config.h (+30/-0)
include/miral/mir/client/blob.h (+50/-0)
include/miral/mir/client/connection.h (+54/-0)
include/miral/mir/client/cookie.h (+50/-0)
include/miral/mir/client/display_config.h (+78/-0)
include/miral/mir/client/surface.h (+50/-0)
include/miral/mir/client/window.h (+53/-0)
include/miral/mir/client/window_id.h (+48/-0)
include/miral/mir/client/window_spec.h (+253/-0)
include/miral/miral/active_outputs.h (+74/-0)
include/miral/miral/add_init_callback.h (+47/-0)
include/miral/miral/append_event_filter.h (+44/-0)
include/miral/miral/application.h (+42/-0)
include/miral/miral/application_authorizer.h (+103/-0)
include/miral/miral/application_info.h (+55/-0)
include/miral/miral/canonical_window_manager.h (+59/-0)
include/miral/miral/command_line_option.h (+109/-0)
include/miral/miral/cursor_theme.h (+44/-0)
include/miral/miral/debug_extension.h (+47/-0)
include/miral/miral/display_configuration_option.h (+30/-0)
include/miral/miral/internal_client.h (+88/-0)
include/miral/miral/keymap.h (+58/-0)
include/miral/miral/output.h (+113/-0)
include/miral/miral/runner.h (+74/-0)
include/miral/miral/set_command_line_handler.h (+50/-0)
include/miral/miral/set_terminator.h (+47/-0)
include/miral/miral/set_window_management_policy.h (+55/-0)
include/miral/miral/version.h (+67/-0)
include/miral/miral/window.h (+82/-0)
include/miral/miral/window_info.h (+130/-0)
include/miral/miral/window_management_options.h (+65/-0)
include/miral/miral/window_management_policy.h (+194/-0)
include/miral/miral/window_management_policy_addendum2.h (+70/-0)
include/miral/miral/window_management_policy_addendum3.h (+68/-0)
include/miral/miral/window_manager_tools.h (+254/-0)
include/miral/miral/window_specification.h (+134/-0)
include/miral/miral/workspace_policy.h (+88/-0)
src/CMakeLists.txt (+1/-0)
src/miral/CMakeLists.txt (+140/-0)
src/miral/active_outputs.cpp (+65/-0)
src/miral/add_init_callback.cpp (+33/-0)
src/miral/append_event_filter.cpp (+48/-0)
src/miral/application.cpp (+51/-0)
src/miral/application_authorizer.cpp (+129/-0)
src/miral/application_info.cpp (+99/-0)
src/miral/basic_window_manager.cpp (+2234/-0)
src/miral/basic_window_manager.h (+272/-0)
src/miral/both_versions.h (+33/-0)
src/miral/canonical_window_manager.cpp (+77/-0)
src/miral/command_line_option.cpp (+210/-0)
src/miral/coordinate_translator.cpp (+51/-0)
src/miral/coordinate_translator.h (+52/-0)
src/miral/cursor_theme.cpp (+62/-0)
src/miral/debug_extension.cpp (+51/-0)
src/miral/display_configuration_listeners.cpp (+120/-0)
src/miral/display_configuration_listeners.h (+67/-0)
src/miral/display_configuration_option.cpp (+115/-0)
src/miral/internal_client.cpp (+215/-0)
src/miral/join_client_threads.h (+24/-0)
src/miral/keymap.cpp (+173/-0)
src/miral/miral.pc.in (+9/-0)
src/miral/mirclientcpp.pc.in (+7/-0)
src/miral/mru_window_list.cpp (+65/-0)
src/miral/mru_window_list.h (+46/-0)
src/miral/output.cpp (+117/-0)
src/miral/runner.cpp (+278/-0)
src/miral/set_command_line_handler.cpp (+33/-0)
src/miral/set_terminator.cpp (+33/-0)
src/miral/set_window_management_policy.cpp (+91/-0)
src/miral/symbols.map (+438/-0)
src/miral/version.h.in (+67/-0)
src/miral/window.cpp (+127/-0)
src/miral/window_info.cpp (+594/-0)
src/miral/window_management_options.cpp (+99/-0)
src/miral/window_management_policy.cpp (+37/-0)
src/miral/window_management_trace.cpp (+798/-0)
src/miral/window_management_trace.h (+146/-0)
src/miral/window_manager_tools.cpp (+141/-0)
src/miral/window_manager_tools_implementation.h (+108/-0)
src/miral/window_specification.cpp (+587/-0)
src/miral/workspace_policy.cpp (+29/-0)
src/miral/xcursor.c (+899/-0)
src/miral/xcursor.h (+62/-0)
src/miral/xcursor_loader.cpp (+215/-0)
src/miral/xcursor_loader.h (+66/-0)
tools/update_package_abis.sh (+1/-0)
To merge this branch: bzr merge lp:~alan-griffiths/mir/move-miral-to-mir
Reviewer Review Type Date Requested Status
Mir CI Bot continuous-integration Approve
Gerry Boland (community) Approve
Brandon Schaefer (community) Approve
Review via email: mp+329455@code.launchpad.net

Commit message

Incorporate miral project into mir source tree - part 1

Description of the change

Incorporate miral project into mir source tree

***
Let me call out that this introduces an epoch to the package version. The need for this is that miral has already reached version 1.4, so it using 1.0 would causes upgrade problems. The alternative to an epoch would be to use a version >> 1.4 (e.g. 1.5).
***

This is a first-cut:

1. It lacks miral-test
2. The utility script for generating the libmiral symbols file hasn't been ported
3. There's no attempt to remove code obsoleted by MirAL

To post a comment you must log in.
Revision history for this message
Mir CI Bot (mir-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Mir CI Bot (mir-ci-bot) wrote :

PASSED: Continuous integration, rev:4248
https://mir-jenkins.ubuntu.com/job/mir-ci/3575/
Executed test runs:
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-mir/4898
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/5120
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=artful/5109
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/5109
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=zesty/5109
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=artful/4937
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=artful/4937/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4937
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4937/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=artful/4937
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=artful/4937/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial/4937
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial/4937/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4937
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4937/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=artful/4937
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=artful/4937/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=zesty/4937
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=zesty/4937/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial/4937
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial/4937/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://mir-jenkins.ubuntu.com/job/mir-ci/3575/rebuild

review: Approve (continuous-integration)
Revision history for this message
Brandon Schaefer (brandontschaefer) wrote :

seems to be working for me, and i do see anything wrong with the debian bits. LGTM

review: Approve
Revision history for this message
Brandon Schaefer (brandontschaefer) wrote :

dont*

Revision history for this message
Gerry Boland (gerboland) wrote :

I'm worried about the miral dpkg version numbers. From the old repo, miral is at 1.4.0+stuff. But miral generated from this will be at 1.0.0+stuff here. That will prevent the 'newer' package being installed.

TBH I'm unsure what can be done, we'd need a Debian package expert.

review: Needs Fixing
Revision history for this message
Gerry Boland (gerboland) wrote :

In miral.pc, the Version: string is missing.

Revision history for this message
Gerry Boland (gerboland) wrote :

In miral.pc, I think the include dir is also wrong (missing /miral)

Revision history for this message
Gerry Boland (gerboland) wrote :

Should copyright years be updated?

Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

> Should copyright years be updated?

Surely that's only when the text is updated, not when it is copied.

Revision history for this message
Mir CI Bot (mir-ci-bot) wrote :

FAILED: Continuous integration, rev:4249
https://mir-jenkins.ubuntu.com/job/mir-ci/3595/
Executed test runs:
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-mir/4919/console
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/5144
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=artful/5133/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/5133/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=zesty/5133/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=artful/4958/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4958/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=artful/4958/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial/4958/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4958/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=artful/4958/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=zesty/4958/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial/4958/console

Click here to trigger a rebuild:
https://mir-jenkins.ubuntu.com/job/mir-ci/3595/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Mir CI Bot (mir-ci-bot) wrote :

FAILED: Continuous integration, rev:4250
https://mir-jenkins.ubuntu.com/job/mir-ci/3596/
Executed test runs:
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-mir/4920/console
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/5145
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=artful/5134/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/5134/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=zesty/5134/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=artful/4959/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4959/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=artful/4959/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial/4959/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4959/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=artful/4959/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=zesty/4959/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial/4959/console

Click here to trigger a rebuild:
https://mir-jenkins.ubuntu.com/job/mir-ci/3596/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Mir CI Bot (mir-ci-bot) wrote :

FAILED: Continuous integration, rev:4250
https://mir-jenkins.ubuntu.com/job/mir-ci/3597/
Executed test runs:
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-mir/4921/console
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/5146
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=artful/5135/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/5135/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=zesty/5135/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=artful/4960/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4960/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=artful/4960/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial/4960/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4960/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=artful/4960/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=zesty/4960/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial/4960/console

Click here to trigger a rebuild:
https://mir-jenkins.ubuntu.com/job/mir-ci/3597/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Mir CI Bot (mir-ci-bot) wrote :

FAILED: Continuous integration, rev:4250
https://mir-jenkins.ubuntu.com/job/mir-ci/3598/
Executed test runs:
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-mir/4922/console
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/5147
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=artful/5137/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/5137/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=zesty/5137/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=artful/4961/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4961/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=artful/4961/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial/4961/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4961/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=artful/4961/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=zesty/4961/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial/4961/console

Click here to trigger a rebuild:
https://mir-jenkins.ubuntu.com/job/mir-ci/3598/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Mir CI Bot (mir-ci-bot) wrote :

PASSED: Continuous integration, rev:4250
https://mir-jenkins.ubuntu.com/job/mir-ci/3599/
Executed test runs:
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-mir/4923
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/5148
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=artful/5138
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/5138
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=zesty/5138
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=artful/4962
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=artful/4962/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4962
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4962/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=artful/4962
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=artful/4962/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial/4962
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial/4962/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4962
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4962/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=artful/4962
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=artful/4962/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=zesty/4962
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=zesty/4962/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial/4962
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial/4962/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://mir-jenkins.ubuntu.com/job/mir-ci/3599/rebuild

review: Approve (continuous-integration)
Revision history for this message
Gerry Boland (gerboland) wrote :

dpkg --compare-versions 1:1.0.0 gt 1.3.0 && echo "yes"
> yes
I'm ok with it, as long as a packaging expert is too.

Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

> dpkg --compare-versions 1:1.0.0 gt 1.3.0 && echo "yes"
> > yes
> I'm ok with it, as long as a packaging expert is too.

Well, the suggestion to use an "epoch" came from Chris.

Revision history for this message
Gerry Boland (gerboland) wrote :

The pkgconfig files are fixed too. I think it looks ok.

review: Approve
Revision history for this message
Mir CI Bot (mir-ci-bot) :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'CMakeLists.txt'
--- CMakeLists.txt 2017-08-10 10:25:55 +0000
+++ CMakeLists.txt 2017-08-29 09:17:20 +0000
@@ -81,8 +81,6 @@
81endif()81endif()
8282
83# Link time optimization allows leaner, cleaner libraries83# Link time optimization allows leaner, cleaner libraries
84message(STATUS "CMAKE_C_COMPILER: " ${CMAKE_C_COMPILER})
85
86option(MIR_LINK_TIME_OPTIMIZATION "Enables the linker to optimize binaries." OFF)84option(MIR_LINK_TIME_OPTIMIZATION "Enables the linker to optimize binaries." OFF)
87if(MIR_LINK_TIME_OPTIMIZATION)85if(MIR_LINK_TIME_OPTIMIZATION)
88 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -flto -ffat-lto-objects")86 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -flto -ffat-lto-objects")
8987
=== added file 'cmake/FindPIL.cmake'
--- cmake/FindPIL.cmake 1970-01-01 00:00:00 +0000
+++ cmake/FindPIL.cmake 2017-08-29 09:17:20 +0000
@@ -0,0 +1,8 @@
1execute_process(
2 COMMAND python3 -c "from PIL import Image"
3 RESULT_VARIABLE HAVE_PIL
4)
5
6if (NOT ${HAVE_PIL} EQUAL 0)
7 message(FATAL_ERROR "Python Imaging Library (PIL) not found")
8endif()
09
=== modified file 'debian/changelog'
--- debian/changelog 2017-08-16 13:52:52 +0000
+++ debian/changelog 2017-08-29 09:17:20 +0000
@@ -1,8 +1,9 @@
1mir (1.0.0-0ubuntu1) UNRELEASED; urgency=medium1mir (1:1.0.0-0ubuntu1) UNRELEASED; urgency=medium
22
3 * New upstream release 1.0.0(https://launchpad.net/mir/+milestone/1.0.0)3 * New upstream release 1.0.0(https://launchpad.net/mir/+milestone/1.0.0)
4 - ABI summary:4 - ABI summary:
5 . mirclient ABI unchanged at 95 . mirclient ABI unchanged at 9
6 . miral ABI introduced at 2
6 . mirserver ABI bumped to 457 . mirserver ABI bumped to 45
7 . mircommon ABI unchanged at 78 . mircommon ABI unchanged at 7
8 . mirplatform ABI unchanged at 619 . mirplatform ABI unchanged at 61
@@ -15,6 +16,8 @@
15 . Update licences to (L)GPL3 or (L)GPL2.16 . Update licences to (L)GPL3 or (L)GPL2.
16 . [mir_demo_client_display_config] add orientation changing17 . [mir_demo_client_display_config] add orientation changing
17 . RPC: Don't require the server ACK client's buffer-release requests.18 . RPC: Don't require the server ACK client's buffer-release requests.
19 . Added libmirclientcpp to Mir source package
20 . Added libmiral to Mir source package
18 - Bugs fixed:21 - Bugs fixed:
19 . Fix handling of invalid display configuration. (LP: #1643446)22 . Fix handling of invalid display configuration. (LP: #1643446)
20 . Move full responsibility for buffer IPC into frontend. (LP: #1395421)23 . Move full responsibility for buffer IPC into frontend. (LP: #1395421)
2124
=== modified file 'debian/control'
--- debian/control 2017-08-02 13:18:44 +0000
+++ debian/control 2017-08-29 09:17:20 +0000
@@ -45,6 +45,7 @@
45 libcapnp-dev,45 libcapnp-dev,
46 capnproto,46 capnproto,
47 libepoxy-dev,47 libepoxy-dev,
48 python3-pil:native,
48Standards-Version: 3.9.449Standards-Version: 3.9.4
49Homepage: https://launchpad.net/mir50Homepage: https://launchpad.net/mir
50# If you aren't a member of ~mir-team but need to upload packaging changes,51# If you aren't a member of ~mir-team but need to upload packaging changes,
@@ -477,3 +478,53 @@
477 .478 .
478 Contains header files that define the interfaces through which platforms and479 Contains header files that define the interfaces through which platforms and
479 renderers access the functionality needed to render with GL.480 renderers access the functionality needed to render with GL.
481
482Package: libmiral2
483Section: libs
484Architecture: linux-any
485Multi-Arch: same
486Pre-Depends: ${misc:Pre-Depends}
487Depends: ${misc:Depends},
488 ${shlibs:Depends},
489Description: Display server for Ubuntu - ABI preserving abstraction layer
490 MirAL provides an ABI-stable abstraction layer for Mir based shells,
491 insulating them from mirserver ABI breaks.
492 .
493 Contains the shared library containing MirAL abstraction layer.
494
495Package: libmiral-dev
496Section: libdevel
497Architecture: linux-any
498Multi-Arch: same
499Pre-Depends: ${misc:Pre-Depends}
500Depends: libmiral2 (= ${binary:Version}),
501 libmirclientcpp-dev (= ${binary:Version}),
502 ${misc:Depends},
503Description: Developer files for the Mir ABI-stable abstraction layer
504 MirAL provides an ABI-stable abstraction layer for Mir based shells,
505 insulating them from mirserver ABI breaks.
506 .
507 Contains header files required for development using the MirAL abstraction
508 layer.
509
510Package: libmirclientcpp-dev
511Section: libdevel
512Architecture: linux-any
513Multi-Arch: same
514Pre-Depends: ${misc:Pre-Depends}
515Depends: libmirclient-dev,
516Description: A C++ wrapper for libmirclient-dev
517 Provides RAII (and other facilities) for Mir client library types.
518 .
519 Contains header files useful for C++ development against Mir.
520
521Package: miral-examples
522Architecture: linux-any
523Depends: ${misc:Depends},
524 ${shlibs:Depends},
525Recommends: dmz-cursor-theme,
526Description: Display server for Ubuntu - demonstration programs
527 MirAL provides an ABI-stable abstraction layer for Mir based shells,
528 insulating them from mirserver ABI breaks.
529 .
530 Contains demo applications that use the MirAL abstraction layer
480531
=== added file 'debian/libmiral-dev.install'
--- debian/libmiral-dev.install 1970-01-01 00:00:00 +0000
+++ debian/libmiral-dev.install 2017-08-29 09:17:20 +0000
@@ -0,0 +1,3 @@
1usr/include/miral/miral/*
2usr/lib/*/pkgconfig/miral.pc
3usr/lib/*/libmiral.so
04
=== added file 'debian/libmiral2.install'
--- debian/libmiral2.install 1970-01-01 00:00:00 +0000
+++ debian/libmiral2.install 2017-08-29 09:17:20 +0000
@@ -0,0 +1,1 @@
1usr/lib/*/libmiral.so.2
02
=== added file 'debian/libmiral2.symbols'
--- debian/libmiral2.symbols 1970-01-01 00:00:00 +0000
+++ debian/libmiral2.symbols 2017-08-29 09:17:20 +0000
@@ -0,0 +1,399 @@
1libmiral.so.2 libmiral2 #MINVER#
2 MIRAL_1.0@MIRAL_1.0 1.0.0
3 (c++)"miral::WindowInfo::height_inc(mir::geometry::detail::IntWrapper<mir::geometry::DeltaYTag>)@MIRAL_1.0" 1.0.0
4 (c++)"miral::WindowInfo::max_aspect(miral::WindowSpecification::AspectRatio)@MIRAL_1.0" 1.0.0
5 (c++)"miral::WindowInfo::max_height(mir::geometry::detail::IntWrapper<mir::geometry::HeightTag>)@MIRAL_1.0" 1.0.0
6 (c++)"miral::WindowInfo::min_aspect(miral::WindowSpecification::AspectRatio)@MIRAL_1.0" 1.0.0
7 (c++)"miral::WindowInfo::min_height(mir::geometry::detail::IntWrapper<mir::geometry::HeightTag>)@MIRAL_1.0" 1.0.0
8 (c++)"miral::WindowInfo::remove_child(miral::Window const&)@MIRAL_1.0" 1.0.0
9 (c++)"miral::WindowInfo::restore_rect(mir::geometry::Rectangle const&)@MIRAL_1.0" 1.0.0
10 (c++)"miral::WindowInfo::needs_titlebar(MirSurfaceType)@MIRAL_1.0" 1.0.0
11 (c++)"miral::WindowInfo::confine_pointer(MirPointerConfinementState)@MIRAL_1.0" 1.0.0
12 (c++)"miral::WindowInfo::preferred_orientation(MirOrientationMode)@MIRAL_1.0" 1.0.0
13 (c++)"miral::WindowInfo::name(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@MIRAL_1.0" 1.0.0
14 (c++)"miral::WindowInfo::type(MirSurfaceType)@MIRAL_1.0" 1.0.0
15 (c++)"miral::WindowInfo::state(MirSurfaceState)@MIRAL_1.0" 1.0.0
16 (c++)"miral::WindowInfo::parent(miral::Window const&)@MIRAL_1.0" 1.0.0
17 (c++)"miral::WindowInfo::userdata(std::shared_ptr<void>)@MIRAL_1.0" 1.0.0
18 (c++)"miral::WindowInfo::add_child(miral::Window const&)@MIRAL_1.0" 1.0.0
19 (c++)"miral::WindowInfo::max_width(mir::geometry::detail::IntWrapper<mir::geometry::WidthTag>)@MIRAL_1.0" 1.0.0
20 (c++)"miral::WindowInfo::min_width(mir::geometry::detail::IntWrapper<mir::geometry::WidthTag>)@MIRAL_1.0" 1.0.0
21 (c++)"miral::WindowInfo::output_id(mir::optional_value<int>)@MIRAL_1.0" 1.0.0
22 (c++)"miral::WindowInfo::width_inc(mir::geometry::detail::IntWrapper<mir::geometry::DeltaXTag>)@MIRAL_1.0" 1.0.0
23 (c++)"miral::WindowInfo::WindowInfo(miral::Window const&, miral::WindowSpecification const&)@MIRAL_1.0" 1.0.0
24 (c++)"miral::WindowInfo::WindowInfo(miral::WindowInfo const&)@MIRAL_1.0" 1.0.0
25 (c++)"miral::WindowInfo::WindowInfo()@MIRAL_1.0" 1.0.0
26 (c++)"miral::WindowInfo::WindowInfo(miral::Window const&, miral::WindowSpecification const&)@MIRAL_1.0" 1.0.0
27 (c++)"miral::WindowInfo::WindowInfo(miral::WindowInfo const&)@MIRAL_1.0" 1.0.0
28 (c++)"miral::WindowInfo::WindowInfo()@MIRAL_1.0" 1.0.0
29 (c++)"miral::WindowInfo::~WindowInfo()@MIRAL_1.0" 1.0.0
30 (c++)"miral::WindowInfo::~WindowInfo()@MIRAL_1.0" 1.0.0
31 (c++)"miral::WindowInfo::operator=(miral::WindowInfo const&)@MIRAL_1.0" 1.0.0
32 (c++)"miral::CursorTheme::CursorTheme(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@MIRAL_1.0" 1.0.0
33 (c++)"miral::CursorTheme::CursorTheme(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@MIRAL_1.0" 1.0.0
34 (c++)"miral::CursorTheme::~CursorTheme()@MIRAL_1.0" 1.0.0
35 (c++)"miral::CursorTheme::~CursorTheme()@MIRAL_1.0" 1.0.0
36 (c++)"miral::SetTerminator::SetTerminator(std::function<void (int)> const&)@MIRAL_1.0" 1.0.0
37 (c++)"miral::SetTerminator::SetTerminator(std::function<void (int)> const&)@MIRAL_1.0" 1.0.0
38 (c++)"miral::SetTerminator::~SetTerminator()@MIRAL_1.0" 1.0.0
39 (c++)"miral::SetTerminator::~SetTerminator()@MIRAL_1.0" 1.0.0
40 (c++)"miral::DebugExtension::enable()@MIRAL_1.0" 1.0.0
41 (c++)"miral::DebugExtension::disable()@MIRAL_1.0" 1.0.0
42 (c++)"miral::DebugExtension::DebugExtension(miral::DebugExtension const&)@MIRAL_1.0" 1.0.0
43 (c++)"miral::DebugExtension::DebugExtension()@MIRAL_1.0" 1.0.0
44 (c++)"miral::DebugExtension::DebugExtension(miral::DebugExtension const&)@MIRAL_1.0" 1.0.0
45 (c++)"miral::DebugExtension::DebugExtension()@MIRAL_1.0" 1.0.0
46 (c++)"miral::DebugExtension::operator=(miral::DebugExtension const&)@MIRAL_1.0" 1.0.0
47 (c++)"miral::AddInitCallback::AddInitCallback(std::function<void ()> const&)@MIRAL_1.0" 1.0.0
48 (c++)"miral::AddInitCallback::AddInitCallback(std::function<void ()> const&)@MIRAL_1.0" 1.0.0
49 (c++)"miral::AddInitCallback::~AddInitCallback()@MIRAL_1.0" 1.0.0
50 (c++)"miral::AddInitCallback::~AddInitCallback()@MIRAL_1.0" 1.0.0
51 (c++)"miral::ApplicationInfo::add_window(miral::Window const&)@MIRAL_1.0" 1.0.0
52 (c++)"miral::ApplicationInfo::remove_window(miral::Window const&)@MIRAL_1.0" 1.0.0
53 (c++)"miral::ApplicationInfo::userdata(std::shared_ptr<void>)@MIRAL_1.0" 1.0.0
54 (c++)"miral::ApplicationInfo::ApplicationInfo(miral::ApplicationInfo const&)@MIRAL_1.0" 1.0.0
55 (c++)"miral::ApplicationInfo::ApplicationInfo(std::shared_ptr<mir::scene::Session> const&)@MIRAL_1.0" 1.0.0
56 (c++)"miral::ApplicationInfo::ApplicationInfo()@MIRAL_1.0" 1.0.0
57 (c++)"miral::ApplicationInfo::ApplicationInfo(miral::ApplicationInfo const&)@MIRAL_1.0" 1.0.0
58 (c++)"miral::ApplicationInfo::ApplicationInfo(std::shared_ptr<mir::scene::Session> const&)@MIRAL_1.0" 1.0.0
59 (c++)"miral::ApplicationInfo::ApplicationInfo()@MIRAL_1.0" 1.0.0
60 (c++)"miral::ApplicationInfo::~ApplicationInfo()@MIRAL_1.0" 1.0.0
61 (c++)"miral::ApplicationInfo::~ApplicationInfo()@MIRAL_1.0" 1.0.0
62 (c++)"miral::ApplicationInfo::operator=(miral::ApplicationInfo const&)@MIRAL_1.0" 1.0.0
63 (c++)"miral::AppendEventFilter::AppendEventFilter(std::function<int (MirEvent const*)> const&)@MIRAL_1.0" 1.0.0
64 (c++)"miral::AppendEventFilter::AppendEventFilter(std::function<int (MirEvent const*)> const&)@MIRAL_1.0" 1.0.0
65 (c++)"miral::AppendEventFilter::operator()(mir::Server&)@MIRAL_1.0" 1.0.0
66 (c++)"miral::CommandLineOption::CommandLineOption(miral::CommandLineOption const&)@MIRAL_1.0" 1.0.0
67 (c++)"miral::CommandLineOption::CommandLineOption(std::function<void (mir::optional_value<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&)>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@MIRAL_1.0" 1.0.0
68 (c++)"miral::CommandLineOption::CommandLineOption(std::function<void (mir::optional_value<bool> const&)>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@MIRAL_1.0" 1.0.0
69 (c++)"miral::CommandLineOption::CommandLineOption(std::function<void (mir::optional_value<int> const&)>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@MIRAL_1.0" 1.0.0
70 (c++)"miral::CommandLineOption::CommandLineOption(std::function<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, char const*)@MIRAL_1.0" 1.0.0
71 (c++)"miral::CommandLineOption::CommandLineOption(std::function<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@MIRAL_1.0" 1.0.0
72 (c++)"miral::CommandLineOption::CommandLineOption(std::function<void (bool)>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@MIRAL_1.0" 1.0.0
73 (c++)"miral::CommandLineOption::CommandLineOption(std::function<void (bool)>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool)@MIRAL_1.0" 1.0.0
74 (c++)"miral::CommandLineOption::CommandLineOption(std::function<void (double)>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, double)@MIRAL_1.0" 1.0.0
75 (c++)"miral::CommandLineOption::CommandLineOption(std::function<void (int)>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int)@MIRAL_1.0" 1.0.0
76 (c++)"miral::CommandLineOption::CommandLineOption(miral::CommandLineOption const&)@MIRAL_1.0" 1.0.0
77 (c++)"miral::CommandLineOption::CommandLineOption(std::function<void (mir::optional_value<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&)>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@MIRAL_1.0" 1.0.0
78 (c++)"miral::CommandLineOption::CommandLineOption(std::function<void (mir::optional_value<bool> const&)>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@MIRAL_1.0" 1.0.0
79 (c++)"miral::CommandLineOption::CommandLineOption(std::function<void (mir::optional_value<int> const&)>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@MIRAL_1.0" 1.0.0
80 (c++)"miral::CommandLineOption::CommandLineOption(std::function<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, char const*)@MIRAL_1.0" 1.0.0
81 (c++)"miral::CommandLineOption::CommandLineOption(std::function<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@MIRAL_1.0" 1.0.0
82 (c++)"miral::CommandLineOption::CommandLineOption(std::function<void (bool)>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@MIRAL_1.0" 1.0.0
83 (c++)"miral::CommandLineOption::CommandLineOption(std::function<void (bool)>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool)@MIRAL_1.0" 1.0.0
84 (c++)"miral::CommandLineOption::CommandLineOption(std::function<void (double)>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, double)@MIRAL_1.0" 1.0.0
85 (c++)"miral::CommandLineOption::CommandLineOption(std::function<void (int)>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int)@MIRAL_1.0" 1.0.0
86 (c++)"miral::CommandLineOption::~CommandLineOption()@MIRAL_1.0" 1.0.0
87 (c++)"miral::CommandLineOption::~CommandLineOption()@MIRAL_1.0" 1.0.0
88 (c++)"miral::CommandLineOption::operator=(miral::CommandLineOption const&)@MIRAL_1.0" 1.0.0
89 (c++)"miral::WindowManagerTools::raise_tree(miral::Window const&)@MIRAL_1.0" 1.0.0
90 (c++)"miral::WindowManagerTools::force_close(miral::Window const&)@MIRAL_1.0" 1.0.0
91 (c++)"miral::WindowManagerTools::modify_window(miral::Window const&, miral::WindowSpecification const&)@MIRAL_1.0" 1.0.0
92 (c++)"miral::WindowManagerTools::modify_window(miral::WindowInfo&, miral::WindowSpecification const&)@MIRAL_1.0" 1.0.0
93 (c++)"miral::WindowManagerTools::active_display()@MIRAL_1.0" 1.0.0
94 (c++)"miral::WindowManagerTools::find_application(std::function<bool (miral::ApplicationInfo const&)> const&)@MIRAL_1.0" 1.0.0
95 (c++)"miral::WindowManagerTools::invoke_under_lock(std::function<void ()> const&)@MIRAL_1.0" 1.0.0
96 (c++)"miral::WindowManagerTools::drag_active_window(mir::geometry::Displacement)@MIRAL_1.0" 1.0.0
97 (c++)"miral::WindowManagerTools::ask_client_to_close(miral::Window const&)@MIRAL_1.0" 1.0.0
98 (c++)"miral::WindowManagerTools::for_each_application(std::function<void (miral::ApplicationInfo&)> const&)@MIRAL_1.0" 1.0.0
99 (c++)"miral::WindowManagerTools::select_active_window(miral::Window const&)@MIRAL_1.0" 1.0.0
100 (c++)"miral::WindowManagerTools::focus_next_application()@MIRAL_1.0" 1.0.0
101 (c++)"miral::WindowManagerTools::focus_next_within_application()@MIRAL_1.0" 1.0.0
102 (c++)"miral::WindowManagerTools::WindowManagerTools(miral::WindowManagerToolsImplementation*)@MIRAL_1.0" 1.0.0
103 (c++)"miral::WindowManagerTools::WindowManagerTools(miral::WindowManagerTools const&)@MIRAL_1.0" 1.0.0
104 (c++)"miral::WindowManagerTools::WindowManagerTools(miral::WindowManagerToolsImplementation*)@MIRAL_1.0" 1.0.0
105 (c++)"miral::WindowManagerTools::WindowManagerTools(miral::WindowManagerTools const&)@MIRAL_1.0" 1.0.0
106 (c++)"miral::WindowManagerTools::~WindowManagerTools()@MIRAL_1.0" 1.0.0
107 (c++)"miral::WindowManagerTools::~WindowManagerTools()@MIRAL_1.0" 1.0.0
108 (c++)"miral::WindowManagerTools::operator=(miral::WindowManagerTools const&)@MIRAL_1.0" 1.0.0
109 (c++)"miral::WindowSpecification::height_inc()@MIRAL_1.0" 1.0.0
110 (c++)"miral::WindowSpecification::input_mode()@MIRAL_1.0" 1.0.0
111 (c++)"miral::WindowSpecification::max_aspect()@MIRAL_1.0" 1.0.0
112 (c++)"miral::WindowSpecification::max_height()@MIRAL_1.0" 1.0.0
113 (c++)"miral::WindowSpecification::min_aspect()@MIRAL_1.0" 1.0.0
114 (c++)"miral::WindowSpecification::min_height()@MIRAL_1.0" 1.0.0
115 (c++)"miral::WindowSpecification::input_shape()@MIRAL_1.0" 1.0.0
116 (c++)"miral::WindowSpecification::shell_chrome()@MIRAL_1.0" 1.0.0
117 (c++)"miral::WindowSpecification::confine_pointer()@MIRAL_1.0" 1.0.0
118 (c++)"miral::WindowSpecification::placement_hints()@MIRAL_1.0" 1.0.0
119 (c++)"miral::WindowSpecification::preferred_orientation()@MIRAL_1.0" 1.0.0
120 (c++)"miral::WindowSpecification::window_placement_gravity()@MIRAL_1.0" 1.0.0
121 (c++)"miral::WindowSpecification::aux_rect_placement_offset()@MIRAL_1.0" 1.0.0
122 (c++)"miral::WindowSpecification::aux_rect_placement_gravity()@MIRAL_1.0" 1.0.0
123 (c++)"miral::WindowSpecification::name[abi:cxx11]()@MIRAL_1.0" 1.0.0
124 (c++)"miral::WindowSpecification::size()@MIRAL_1.0" 1.0.0
125 (c++)"miral::WindowSpecification::type()@MIRAL_1.0" 1.0.0
126 (c++)"miral::WindowSpecification::state()@MIRAL_1.0" 1.0.0
127 (c++)"miral::WindowSpecification::parent()@MIRAL_1.0" 1.0.0
128 (c++)"miral::WindowSpecification::aux_rect()@MIRAL_1.0" 1.0.0
129 (c++)"miral::WindowSpecification::top_left()@MIRAL_1.0" 1.0.0
130 (c++)"miral::WindowSpecification::userdata()@MIRAL_1.0" 1.0.0
131 (c++)"miral::WindowSpecification::max_width()@MIRAL_1.0" 1.0.0
132 (c++)"miral::WindowSpecification::min_width()@MIRAL_1.0" 1.0.0
133 (c++)"miral::WindowSpecification::output_id()@MIRAL_1.0" 1.0.0
134 (c++)"miral::WindowSpecification::width_inc()@MIRAL_1.0" 1.0.0
135 (c++)"miral::WindowSpecification::WindowSpecification(mir::scene::SurfaceCreationParameters const&)@MIRAL_1.0" 1.0.0
136 (c++)"miral::WindowSpecification::WindowSpecification(mir::shell::SurfaceSpecification const&)@MIRAL_1.0" 1.0.0
137 (c++)"miral::WindowSpecification::WindowSpecification(miral::WindowSpecification const&)@MIRAL_1.0" 1.0.0
138 (c++)"miral::WindowSpecification::WindowSpecification()@MIRAL_1.0" 1.0.0
139 (c++)"miral::WindowSpecification::WindowSpecification(mir::scene::SurfaceCreationParameters const&)@MIRAL_1.0" 1.0.0
140 (c++)"miral::WindowSpecification::WindowSpecification(mir::shell::SurfaceSpecification const&)@MIRAL_1.0" 1.0.0
141 (c++)"miral::WindowSpecification::WindowSpecification(miral::WindowSpecification const&)@MIRAL_1.0" 1.0.0
142 (c++)"miral::WindowSpecification::WindowSpecification()@MIRAL_1.0" 1.0.0
143 (c++)"miral::WindowSpecification::~WindowSpecification()@MIRAL_1.0" 1.0.0
144 (c++)"miral::WindowSpecification::~WindowSpecification()@MIRAL_1.0" 1.0.0
145 (c++)"miral::WindowSpecification::operator=(miral::WindowSpecification const&)@MIRAL_1.0" 1.0.0
146 (c++)"miral::ActiveOutputsMonitor::add_listener(miral::ActiveOutputsListener*)@MIRAL_1.0" 1.0.0
147 (c++)"miral::ActiveOutputsMonitor::delete_listener(miral::ActiveOutputsListener*)@MIRAL_1.0" 1.0.0
148 (c++)"miral::ActiveOutputsMonitor::ActiveOutputsMonitor(miral::ActiveOutputsMonitor const&)@MIRAL_1.0" 1.0.0
149 (c++)"miral::ActiveOutputsMonitor::ActiveOutputsMonitor()@MIRAL_1.0" 1.0.0
150 (c++)"miral::ActiveOutputsMonitor::ActiveOutputsMonitor(miral::ActiveOutputsMonitor const&)@MIRAL_1.0" 1.0.0
151 (c++)"miral::ActiveOutputsMonitor::ActiveOutputsMonitor()@MIRAL_1.0" 1.0.0
152 (c++)"miral::ActiveOutputsMonitor::~ActiveOutputsMonitor()@MIRAL_1.0" 1.0.0
153 (c++)"miral::ActiveOutputsMonitor::~ActiveOutputsMonitor()@MIRAL_1.0" 1.0.0
154 (c++)"miral::ActiveOutputsMonitor::operator=(miral::ActiveOutputsMonitor const&)@MIRAL_1.0" 1.0.0
155 (c++)"miral::ActiveOutputsMonitor::operator()(mir::Server&)@MIRAL_1.0" 1.0.0
156 (c++)"miral::ActiveOutputsListener::advise_output_end()@MIRAL_1.0" 1.0.0
157 (c++)"miral::ActiveOutputsListener::advise_output_begin()@MIRAL_1.0" 1.0.0
158 (c++)"miral::ActiveOutputsListener::advise_output_create(miral::Output const&)@MIRAL_1.0" 1.0.0
159 (c++)"miral::ActiveOutputsListener::advise_output_delete(miral::Output const&)@MIRAL_1.0" 1.0.0
160 (c++)"miral::ActiveOutputsListener::advise_output_update(miral::Output const&, miral::Output const&)@MIRAL_1.0" 1.0.0
161 (c++)"miral::SetCommandLineHandler::SetCommandLineHandler(std::function<void (int, char const* const*)> const&)@MIRAL_1.0" 1.0.0
162 (c++)"miral::SetCommandLineHandler::SetCommandLineHandler(std::function<void (int, char const* const*)> const&)@MIRAL_1.0" 1.0.0
163 (c++)"miral::SetCommandLineHandler::~SetCommandLineHandler()@MIRAL_1.0" 1.0.0
164 (c++)"miral::SetCommandLineHandler::~SetCommandLineHandler()@MIRAL_1.0" 1.0.0
165 (c++)"miral::StartupInternalClient::StartupInternalClient(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::function<void (miral::toolkit::Connection)>, std::function<void (std::weak_ptr<mir::scene::Session>)>)@MIRAL_1.0" 1.0.0
166 (c++)"miral::StartupInternalClient::StartupInternalClient(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::function<void (miral::toolkit::Connection)>, std::function<void (std::weak_ptr<mir::scene::Session>)>)@MIRAL_1.0" 1.0.0
167 (c++)"miral::StartupInternalClient::~StartupInternalClient()@MIRAL_1.0" 1.0.0
168 (c++)"miral::StartupInternalClient::~StartupInternalClient()@MIRAL_1.0" 1.0.0
169 (c++)"miral::StartupInternalClient::operator()(mir::Server&)@MIRAL_1.0" 1.0.0
170 (c++)"miral::ApplicationCredentials::ApplicationCredentials(mir::frontend::SessionCredentials const&)@MIRAL_1.0" 1.0.0
171 (c++)"miral::ApplicationCredentials::ApplicationCredentials(mir::frontend::SessionCredentials const&)@MIRAL_1.0" 1.0.0
172 (c++)"miral::InternalClientLauncher::InternalClientLauncher()@MIRAL_1.0" 1.0.0
173 (c++)"miral::InternalClientLauncher::InternalClientLauncher()@MIRAL_1.0" 1.0.0
174 (c++)"miral::InternalClientLauncher::~InternalClientLauncher()@MIRAL_1.0" 1.0.0
175 (c++)"miral::InternalClientLauncher::~InternalClientLauncher()@MIRAL_1.0" 1.0.0
176 (c++)"miral::InternalClientLauncher::operator()(mir::Server&)@MIRAL_1.0" 1.0.0
177 (c++)"miral::WindowManagementPolicy::advise_end()@MIRAL_1.0" 1.0.0
178 (c++)"miral::WindowManagementPolicy::advise_begin()@MIRAL_1.0" 1.0.0
179 (c++)"miral::WindowManagementPolicy::advise_raise(std::vector<miral::Window, std::allocator<miral::Window> > const&)@MIRAL_1.0" 1.0.0
180 (c++)"miral::WindowManagementPolicy::advise_resize(miral::WindowInfo const&, mir::geometry::Size const&)@MIRAL_1.0" 1.0.0
181 (c++)"miral::WindowManagementPolicy::advise_move_to(miral::WindowInfo const&, mir::geometry::Point)@MIRAL_1.0" 1.0.0
182 (c++)"miral::WindowManagementPolicy::advise_new_app(miral::ApplicationInfo&)@MIRAL_1.0" 1.0.0
183 (c++)"miral::WindowManagementPolicy::advise_delete_app(miral::ApplicationInfo const&)@MIRAL_1.0" 1.0.0
184 (c++)"miral::WindowManagementPolicy::advise_focus_lost(miral::WindowInfo const&)@MIRAL_1.0" 1.0.0
185 (c++)"miral::WindowManagementPolicy::advise_new_window(miral::WindowInfo const&)@MIRAL_1.0" 1.0.0
186 (c++)"miral::WindowManagementPolicy::advise_focus_gained(miral::WindowInfo const&)@MIRAL_1.0" 1.0.0
187 (c++)"miral::WindowManagementPolicy::advise_state_change(miral::WindowInfo const&, MirSurfaceState)@MIRAL_1.0" 1.0.0
188 (c++)"miral::WindowManagementPolicy::advise_delete_window(miral::WindowInfo const&)@MIRAL_1.0" 1.0.0
189 (c++)"miral::equivalent_display_area(miral::Output const&, miral::Output const&)@MIRAL_1.0" 1.0.0
190 (c++)"miral::SetWindowManagmentPolicy::SetWindowManagmentPolicy(std::function<std::unique_ptr<miral::WindowManagementPolicy, std::default_delete<miral::WindowManagementPolicy> > (miral::WindowManagerTools const&)> const&)@MIRAL_1.0" 1.0.0
191 (c++)"miral::SetWindowManagmentPolicy::SetWindowManagmentPolicy(std::function<std::unique_ptr<miral::WindowManagementPolicy, std::default_delete<miral::WindowManagementPolicy> > (miral::WindowManagerTools const&)> const&)@MIRAL_1.0" 1.0.0
192 (c++)"miral::SetWindowManagmentPolicy::~SetWindowManagmentPolicy()@MIRAL_1.0" 1.0.0
193 (c++)"miral::SetWindowManagmentPolicy::~SetWindowManagmentPolicy()@MIRAL_1.0" 1.0.0
194 (c++)"miral::apply_lifecycle_state_to(std::shared_ptr<mir::scene::Session> const&, MirLifecycleState)@MIRAL_1.0" 1.0.0
195 (c++)"miral::CanonicalWindowManagerPolicy::place_new_surface(miral::ApplicationInfo const&, miral::WindowSpecification const&)@MIRAL_1.0" 1.0.0
196 (c++)"miral::CanonicalWindowManagerPolicy::advise_focus_gained(miral::WindowInfo const&)@MIRAL_1.0" 1.0.0
197 (c++)"miral::CanonicalWindowManagerPolicy::handle_raise_window(miral::WindowInfo&)@MIRAL_1.0" 1.0.0
198 (c++)"miral::CanonicalWindowManagerPolicy::handle_window_ready(miral::WindowInfo&)@MIRAL_1.0" 1.0.0
199 (c++)"miral::CanonicalWindowManagerPolicy::handle_modify_window(miral::WindowInfo&, miral::WindowSpecification const&)@MIRAL_1.0" 1.0.0
200 (c++)"miral::CanonicalWindowManagerPolicy::confirm_inherited_move(miral::WindowInfo const&, mir::geometry::Displacement)@MIRAL_1.0" 1.0.0
201 (c++)"miral::CanonicalWindowManagerPolicy::CanonicalWindowManagerPolicy(miral::WindowManagerTools const&)@MIRAL_1.0" 1.0.0
202 (c++)"miral::CanonicalWindowManagerPolicy::CanonicalWindowManagerPolicy(miral::WindowManagerTools const&)@MIRAL_1.0" 1.0.0
203 (c++)"miral::BasicSetApplicationAuthorizer::BasicSetApplicationAuthorizer(std::function<std::shared_ptr<miral::ApplicationAuthorizer> ()> const&)@MIRAL_1.0" 1.0.0
204 (c++)"miral::BasicSetApplicationAuthorizer::BasicSetApplicationAuthorizer(std::function<std::shared_ptr<miral::ApplicationAuthorizer> ()> const&)@MIRAL_1.0" 1.0.0
205 (c++)"miral::BasicSetApplicationAuthorizer::~BasicSetApplicationAuthorizer()@MIRAL_1.0" 1.0.0
206 (c++)"miral::BasicSetApplicationAuthorizer::~BasicSetApplicationAuthorizer()@MIRAL_1.0" 1.0.0
207 (c++)"miral::BasicSetApplicationAuthorizer::operator()(mir::Server&)@MIRAL_1.0" 1.0.0
208 (c++)"miral::display_configuration_options(mir::Server&)@MIRAL_1.0" 1.0.0
209 (c++)"miral::kill(std::shared_ptr<mir::scene::Session> const&, int)@MIRAL_1.0" 1.0.0
210 (c++)"miral::Keymap::set_keymap(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@MIRAL_1.0" 1.0.0
211 (c++)"miral::Keymap::Keymap(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@MIRAL_1.0" 1.0.0
212 (c++)"miral::Keymap::Keymap(miral::Keymap const&)@MIRAL_1.0" 1.0.0
213 (c++)"miral::Keymap::Keymap()@MIRAL_1.0" 1.0.0
214 (c++)"miral::Keymap::Keymap(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@MIRAL_1.0" 1.0.0
215 (c++)"miral::Keymap::Keymap(miral::Keymap const&)@MIRAL_1.0" 1.0.0
216 (c++)"miral::Keymap::Keymap()@MIRAL_1.0" 1.0.0
217 (c++)"miral::Keymap::~Keymap()@MIRAL_1.0" 1.0.0
218 (c++)"miral::Keymap::~Keymap()@MIRAL_1.0" 1.0.0
219 (c++)"miral::Keymap::operator=(miral::Keymap const&)@MIRAL_1.0" 1.0.0
220 (c++)"miral::Output::Output(mir::graphics::DisplayConfigurationOutput const&)@MIRAL_1.0" 1.0.0
221 (c++)"miral::Output::Output(miral::Output const&)@MIRAL_1.0" 1.0.0
222 (c++)"miral::Output::Output(mir::graphics::DisplayConfigurationOutput const&)@MIRAL_1.0" 1.0.0
223 (c++)"miral::Output::Output(miral::Output const&)@MIRAL_1.0" 1.0.0
224 (c++)"miral::Output::~Output()@MIRAL_1.0" 1.0.0
225 (c++)"miral::Output::~Output()@MIRAL_1.0" 1.0.0
226 (c++)"miral::Output::operator=(miral::Output const&)@MIRAL_1.0" 1.0.0
227 (c++)"miral::Window::resize(mir::geometry::Size const&)@MIRAL_1.0" 1.0.0
228 (c++)"miral::Window::move_to(mir::geometry::Point)@MIRAL_1.0" 1.0.0
229 (c++)"miral::Window::Window(std::shared_ptr<mir::scene::Session> const&, std::shared_ptr<mir::scene::Surface> const&)@MIRAL_1.0" 1.0.0
230 (c++)"miral::Window::Window()@MIRAL_1.0" 1.0.0
231 (c++)"miral::Window::Window(std::shared_ptr<mir::scene::Session> const&, std::shared_ptr<mir::scene::Surface> const&)@MIRAL_1.0" 1.0.0
232 (c++)"miral::Window::Window()@MIRAL_1.0" 1.0.0
233 (c++)"miral::Window::~Window()@MIRAL_1.0" 1.0.0
234 (c++)"miral::Window::~Window()@MIRAL_1.0" 1.0.0
235 (c++)"miral::pid_of(std::shared_ptr<mir::scene::Session> const&)@MIRAL_1.0" 1.0.0
236 (c++)"miral::name_of[abi:cxx11](std::shared_ptr<mir::scene::Session> const&)@MIRAL_1.0" 1.0.0
237 (c++)"miral::MirRunner::add_stop_callback(std::function<void ()> const&)@MIRAL_1.0" 1.0.0
238 (c++)"miral::MirRunner::add_start_callback(std::function<void ()> const&)@MIRAL_1.0" 1.0.0
239 (c++)"miral::MirRunner::set_exception_handler(std::function<void ()> const&)@MIRAL_1.0" 1.0.0
240 (c++)"miral::MirRunner::stop()@MIRAL_1.0" 1.0.0
241 (c++)"miral::MirRunner::run_with(std::initializer_list<std::function<void (mir::Server&)> >)@MIRAL_1.0" 1.0.0
242 (c++)"miral::MirRunner::MirRunner(int, char const**)@MIRAL_1.0" 1.0.0
243 (c++)"miral::MirRunner::MirRunner(int, char const**, char const*)@MIRAL_1.0" 1.0.0
244 (c++)"miral::MirRunner::MirRunner(int, char const**)@MIRAL_1.0" 1.0.0
245 (c++)"miral::MirRunner::MirRunner(int, char const**, char const*)@MIRAL_1.0" 1.0.0
246 (c++)"miral::MirRunner::~MirRunner()@MIRAL_1.0" 1.0.0
247 (c++)"miral::MirRunner::~MirRunner()@MIRAL_1.0" 1.0.0
248 (c++)"miral::operator==(miral::Output::PhysicalSizeMM const&, miral::Output::PhysicalSizeMM const&)@MIRAL_1.0" 1.0.0
249 (c++)"miral::operator==(miral::Window const&, std::shared_ptr<mir::scene::Surface> const&)@MIRAL_1.0" 1.0.0
250 (c++)"miral::operator==(miral::Window const&, miral::Window const&)@MIRAL_1.0" 1.0.0
251 (c++)"miral::operator==(std::shared_ptr<mir::scene::Surface> const&, miral::Window const&)@MIRAL_1.0" 1.0.0
252 (c++)"miral::WindowInfo::height_inc() const@MIRAL_1.0" 1.0.0
253 (c++)"miral::WindowInfo::is_visible() const@MIRAL_1.0" 1.0.0
254 (c++)"miral::WindowInfo::max_aspect() const@MIRAL_1.0" 1.0.0
255 (c++)"miral::WindowInfo::max_height() const@MIRAL_1.0" 1.0.0
256 (c++)"miral::WindowInfo::min_aspect() const@MIRAL_1.0" 1.0.0
257 (c++)"miral::WindowInfo::min_height() const@MIRAL_1.0" 1.0.0
258 (c++)"miral::WindowInfo::can_morph_to(MirSurfaceType) const@MIRAL_1.0" 1.0.0
259 (c++)"miral::WindowInfo::restore_rect() const@MIRAL_1.0" 1.0.0
260 (c++)"miral::WindowInfo::can_be_active() const@MIRAL_1.0" 1.0.0
261 (c++)"miral::WindowInfo::has_output_id() const@MIRAL_1.0" 1.0.0
262 (c++)"miral::WindowInfo::confine_pointer() const@MIRAL_1.0" 1.0.0
263 (c++)"miral::WindowInfo::constrain_resize(mir::geometry::Point&, mir::geometry::Size&) const@MIRAL_1.0" 1.0.0
264 (c++)"miral::WindowInfo::must_have_parent() const@MIRAL_1.0" 1.0.0
265 (c++)"miral::WindowInfo::must_not_have_parent() const@MIRAL_1.0" 1.0.0
266 (c++)"miral::WindowInfo::preferred_orientation() const@MIRAL_1.0" 1.0.0
267 (c++)"miral::WindowInfo::name[abi:cxx11]() const@MIRAL_1.0" 1.0.0
268 (c++)"miral::WindowInfo::type() const@MIRAL_1.0" 1.0.0
269 (c++)"miral::WindowInfo::state() const@MIRAL_1.0" 1.0.0
270 (c++)"miral::WindowInfo::parent() const@MIRAL_1.0" 1.0.0
271 (c++)"miral::WindowInfo::window() const@MIRAL_1.0" 1.0.0
272 (c++)"miral::WindowInfo::children() const@MIRAL_1.0" 1.0.0
273 (c++)"miral::WindowInfo::userdata() const@MIRAL_1.0" 1.0.0
274 (c++)"miral::WindowInfo::max_width() const@MIRAL_1.0" 1.0.0
275 (c++)"miral::WindowInfo::min_width() const@MIRAL_1.0" 1.0.0
276 (c++)"miral::WindowInfo::output_id() const@MIRAL_1.0" 1.0.0
277 (c++)"miral::WindowInfo::width_inc() const@MIRAL_1.0" 1.0.0
278 (c++)"miral::CursorTheme::operator()(mir::Server&) const@MIRAL_1.0" 1.0.0
279 (c++)"miral::SetTerminator::operator()(mir::Server&) const@MIRAL_1.0" 1.0.0
280 (c++)"miral::DebugExtension::operator()(mir::Server&) const@MIRAL_1.0" 1.0.0
281 (c++)"miral::AddInitCallback::operator()(mir::Server&) const@MIRAL_1.0" 1.0.0
282 (c++)"miral::ApplicationInfo::application() const@MIRAL_1.0" 1.0.0
283 (c++)"miral::ApplicationInfo::name[abi:cxx11]() const@MIRAL_1.0" 1.0.0
284 (c++)"miral::ApplicationInfo::windows() const@MIRAL_1.0" 1.0.0
285 (c++)"miral::ApplicationInfo::userdata() const@MIRAL_1.0" 1.0.0
286 (c++)"miral::CommandLineOption::operator()(mir::Server&) const@MIRAL_1.0" 1.0.0
287 (c++)"miral::WindowManagerTools::active_window() const@MIRAL_1.0" 1.0.0
288 (c++)"miral::WindowManagerTools::id_for_window[abi:cxx11](miral::Window const&) const@MIRAL_1.0" 1.0.0
289 (c++)"miral::WindowManagerTools::count_applications() const@MIRAL_1.0" 1.0.0
290 (c++)"miral::WindowManagerTools::info_for_window_id(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const@MIRAL_1.0" 1.0.0
291 (c++)"miral::WindowManagerTools::place_and_size_for_state(miral::WindowSpecification&, miral::WindowInfo const&) const@MIRAL_1.0" 1.0.0
292 (c++)"miral::WindowManagerTools::info_for(miral::Window const&) const@MIRAL_1.0" 1.0.0
293 (c++)"miral::WindowManagerTools::info_for(std::weak_ptr<mir::scene::Session> const&) const@MIRAL_1.0" 1.0.0
294 (c++)"miral::WindowManagerTools::info_for(std::weak_ptr<mir::scene::Surface> const&) const@MIRAL_1.0" 1.0.0
295 (c++)"miral::WindowManagerTools::window_at(mir::geometry::Point) const@MIRAL_1.0" 1.0.0
296 (c++)"miral::WindowSpecification::height_inc() const@MIRAL_1.0" 1.0.0
297 (c++)"miral::WindowSpecification::input_mode() const@MIRAL_1.0" 1.0.0
298 (c++)"miral::WindowSpecification::max_aspect() const@MIRAL_1.0" 1.0.0
299 (c++)"miral::WindowSpecification::max_height() const@MIRAL_1.0" 1.0.0
300 (c++)"miral::WindowSpecification::min_aspect() const@MIRAL_1.0" 1.0.0
301 (c++)"miral::WindowSpecification::min_height() const@MIRAL_1.0" 1.0.0
302 (c++)"miral::WindowSpecification::input_shape() const@MIRAL_1.0" 1.0.0
303 (c++)"miral::WindowSpecification::shell_chrome() const@MIRAL_1.0" 1.0.0
304 (c++)"miral::WindowSpecification::confine_pointer() const@MIRAL_1.0" 1.0.0
305 (c++)"miral::WindowSpecification::placement_hints() const@MIRAL_1.0" 1.0.0
306 (c++)"miral::WindowSpecification::preferred_orientation() const@MIRAL_1.0" 1.0.0
307 (c++)"miral::WindowSpecification::window_placement_gravity() const@MIRAL_1.0" 1.0.0
308 (c++)"miral::WindowSpecification::aux_rect_placement_offset() const@MIRAL_1.0" 1.0.0
309 (c++)"miral::WindowSpecification::aux_rect_placement_gravity() const@MIRAL_1.0" 1.0.0
310 (c++)"miral::WindowSpecification::name[abi:cxx11]() const@MIRAL_1.0" 1.0.0
311 (c++)"miral::WindowSpecification::size() const@MIRAL_1.0" 1.0.0
312 (c++)"miral::WindowSpecification::type() const@MIRAL_1.0" 1.0.0
313 (c++)"miral::WindowSpecification::state() const@MIRAL_1.0" 1.0.0
314 (c++)"miral::WindowSpecification::parent() const@MIRAL_1.0" 1.0.0
315 (c++)"miral::WindowSpecification::update(mir::scene::SurfaceCreationParameters&) const@MIRAL_1.0" 1.0.0
316 (c++)"miral::WindowSpecification::aux_rect() const@MIRAL_1.0" 1.0.0
317 (c++)"miral::WindowSpecification::top_left() const@MIRAL_1.0" 1.0.0
318 (c++)"miral::WindowSpecification::userdata() const@MIRAL_1.0" 1.0.0
319 (c++)"miral::WindowSpecification::max_width() const@MIRAL_1.0" 1.0.0
320 (c++)"miral::WindowSpecification::min_width() const@MIRAL_1.0" 1.0.0
321 (c++)"miral::WindowSpecification::output_id() const@MIRAL_1.0" 1.0.0
322 (c++)"miral::WindowSpecification::width_inc() const@MIRAL_1.0" 1.0.0
323 (c++)"miral::ActiveOutputsMonitor::process_outputs(std::function<void (std::vector<miral::Output, std::allocator<miral::Output> > const&)> const&) const@MIRAL_1.0" 1.0.0
324 (c++)"miral::WindowManagerOptions::operator()(mir::Server&) const@MIRAL_1.0" 1.0.0
325 (c++)"miral::SetCommandLineHandler::operator()(mir::Server&) const@MIRAL_1.0" 1.0.0
326 (c++)"miral::ApplicationCredentials::gid() const@MIRAL_1.0" 1.0.0
327 (c++)"miral::ApplicationCredentials::pid() const@MIRAL_1.0" 1.0.0
328 (c++)"miral::ApplicationCredentials::uid() const@MIRAL_1.0" 1.0.0
329 (c++)"miral::InternalClientLauncher::launch(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::function<void (miral::toolkit::Connection)> const&, std::function<void (std::weak_ptr<mir::scene::Session>)> const&) const@MIRAL_1.0" 1.0.0
330 (c++)"miral::SetWindowManagmentPolicy::operator()(mir::Server&) const@MIRAL_1.0" 1.0.0
331 (c++)"miral::BasicSetApplicationAuthorizer::the_application_authorizer() const@MIRAL_1.0" 1.0.0
332 (c++)"miral::Keymap::operator()(mir::Server&) const@MIRAL_1.0" 1.0.0
333 (c++)"miral::Output::power_mode() const@MIRAL_1.0" 1.0.0
334 (c++)"miral::Output::form_factor() const@MIRAL_1.0" 1.0.0
335 (c++)"miral::Output::orientation() const@MIRAL_1.0" 1.0.0
336 (c++)"miral::Output::pixel_format() const@MIRAL_1.0" 1.0.0
337 (c++)"miral::Output::refresh_rate() const@MIRAL_1.0" 1.0.0
338 (c++)"miral::Output::is_same_output(miral::Output const&) const@MIRAL_1.0" 1.0.0
339 (c++)"miral::Output::physical_size_mm() const@MIRAL_1.0" 1.0.0
340 (c++)"miral::Output::type() const@MIRAL_1.0" 1.0.0
341 (c++)"miral::Output::used() const@MIRAL_1.0" 1.0.0
342 (c++)"miral::Output::scale() const@MIRAL_1.0" 1.0.0
343 (c++)"miral::Output::valid() const@MIRAL_1.0" 1.0.0
344 (c++)"miral::Output::extents() const@MIRAL_1.0" 1.0.0
345 (c++)"miral::Output::connected() const@MIRAL_1.0" 1.0.0
346 (c++)"miral::Window::application() const@MIRAL_1.0" 1.0.0
347 (c++)"miral::Window::size() const@MIRAL_1.0" 1.0.0
348 (c++)"miral::Window::top_left() const@MIRAL_1.0" 1.0.0
349 (c++)"miral::Window::operator std::shared_ptr<mir::scene::Surface>() const@MIRAL_1.0" 1.0.0
350 (c++)"miral::Window::operator std::weak_ptr<mir::scene::Surface>() const@MIRAL_1.0" 1.0.0
351 (c++)"miral::Window::operator bool() const@MIRAL_1.0" 1.0.0
352 (c++)"typeinfo for miral::ActiveOutputsListener@MIRAL_1.0" 1.0.0
353 (c++)"typeinfo for miral::WindowManagementPolicy@MIRAL_1.0" 1.0.0
354 (c++)"typeinfo for miral::CanonicalWindowManagerPolicy@MIRAL_1.0" 1.0.0
355 (c++)"vtable for miral::ActiveOutputsListener@MIRAL_1.0" 1.0.0
356 (c++)"vtable for miral::WindowManagementPolicy@MIRAL_1.0" 1.0.0
357 (c++)"vtable for miral::CanonicalWindowManagerPolicy@MIRAL_1.0" 1.0.0
358 MIRAL_1.1@MIRAL_1.1 1.0.0
359 (c++)"miral::WindowInfo::needs_titlebar(MirWindowType)@MIRAL_1.1" 1.0.0
360 (c++)"miral::WindowInfo::type(MirWindowType)@MIRAL_1.1" 1.0.0
361 (c++)"miral::WindowInfo::state(MirWindowState)@MIRAL_1.1" 1.0.0
362 (c++)"miral::WindowManagementPolicy::advise_state_change(miral::WindowInfo const&, MirWindowState)@MIRAL_1.1" 1.0.0
363 (c++)"miral::WindowInfo::can_morph_to(MirWindowType) const@MIRAL_1.1" 1.0.0
364 (c++)"miral::CanonicalWindowManagerPolicy::place_new_window(miral::ApplicationInfo const&, miral::WindowSpecification const&)@MIRAL_1.1" 1.0.0
365 MIRAL_1.2@MIRAL_1.2 1.0.0
366 (c++)"miral::StartupInternalClient::StartupInternalClient(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::function<void (mir::client::Connection)>, std::function<void (std::weak_ptr<mir::scene::Session>)>)@MIRAL_1.2" 1.0.0
367 (c++)"miral::InternalClientLauncher::launch(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::function<void (mir::client::Connection)> const&, std::function<void (std::weak_ptr<mir::scene::Session>)> const&) const@MIRAL_1.2" 1.0.0
368 (c++)"miral::WindowInfo::shell_chrome(MirShellChrome)@MIRAL_1.2" 1.0.0
369 (c++)"miral::WindowInfo::shell_chrome() const@MIRAL_1.2" 1.0.0
370 (c++)"miral::WindowManagerTools::drag_window(miral::Window const&, mir::geometry::Displacement)@MIRAL_1.2" 1.0.0
371 (c++)"typeinfo for miral::ApplicationAuthorizer@MIRAL_1.0" 1.0.0
372 (c++)"typeinfo for miral::ApplicationAuthorizer1@MIRAL_1.2" 1.0.0
373 MIRAL_1.3@MIRAL_1.3 1.0.0
374 (c++)"miral::operator<(miral::Window const&, miral::Window const&)@MIRAL_1.0" 1.0.0
375 (c++)"miral::WindowManagerTools::create_workspace()@MIRAL_1.3" 1.0.0
376 (c++)"miral::WindowManagerTools::add_tree_to_workspace(miral::Window const&, std::shared_ptr<miral::Workspace> const&)@MIRAL_1.3" 1.0.0
377 (c++)"miral::WindowManagerTools::focus_prev_within_application()@MIRAL_1.3" 1.0.0
378 (c++)"miral::WindowManagerTools::remove_tree_from_workspace(miral::Window const&, std::shared_ptr<miral::Workspace> const&)@MIRAL_1.3" 1.0.0
379 (c++)"miral::WindowManagerTools::move_workspace_content_to_workspace(std::shared_ptr<miral::Workspace> const&, std::shared_ptr<miral::Workspace> const&)@MIRAL_1.3" 1.0.0
380 (c++)"miral::WorkspacePolicy::advise_adding_to_workspace(std::shared_ptr<miral::Workspace> const&, std::vector<miral::Window, std::allocator<miral::Window> > const&)@MIRAL_1.3" 1.0.0
381 (c++)"miral::WorkspacePolicy::advise_removing_from_workspace(std::shared_ptr<miral::Workspace> const&, std::vector<miral::Window, std::allocator<miral::Window> > const&)@MIRAL_1.3" 1.0.0
382 (c++)"miral::WindowManagerTools::for_each_window_in_workspace(std::shared_ptr<miral::Workspace> const&, std::function<void (miral::Window const&)> const&)@MIRAL_1.3" 1.0.0
383 (c++)"miral::WindowManagerTools::for_each_workspace_containing(miral::Window const&, std::function<void (std::shared_ptr<miral::Workspace> const&)> const&)@MIRAL_1.3" 1.0.0
384 (c++)"typeinfo for miral::WorkspacePolicy@MIRAL_1.3" 1.0.0
385 (c++)"vtable for miral::WorkspacePolicy@MIRAL_1.3" 1.0.0
386 MIRAL_1.3.1@MIRAL_1.3.1 1.0.0
387 (c++)"miral::SetWindowManagementPolicy::SetWindowManagementPolicy(std::function<std::unique_ptr<miral::WindowManagementPolicy, std::default_delete<miral::WindowManagementPolicy> > (miral::WindowManagerTools const&)> const&)@MIRAL_1.3.1" 1.0.0
388 (c++)"miral::SetWindowManagementPolicy::SetWindowManagementPolicy(std::function<std::unique_ptr<miral::WindowManagementPolicy, std::default_delete<miral::WindowManagementPolicy> > (miral::WindowManagerTools const&)> const&)@MIRAL_1.3.1" 1.0.0
389 (c++)"miral::SetWindowManagementPolicy::~SetWindowManagementPolicy()@MIRAL_1.3.1" 1.0.0
390 (c++)"miral::SetWindowManagementPolicy::~SetWindowManagementPolicy()@MIRAL_1.3.1" 1.0.0
391 (c++)"miral::SetWindowManagementPolicy::operator()(mir::Server&) const@MIRAL_1.3.1" 1.0.0
392 MIRAL_1.4.0@MIRAL_1.4.0 1.0.0
393 (c++)"miral::WindowManagerTools::end_drag_and_drop()@MIRAL_1.4.0" 1.0.0
394 (c++)"miral::WindowManagerTools::start_drag_and_drop(miral::WindowInfo&, std::vector<unsigned char, std::allocator<unsigned char> > const&)@MIRAL_1.4.0" 1.0.0
395 (c++)"typeinfo for miral::WindowManagementPolicyAddendum2@MIRAL_1.4.0" 1.0.0
396 MIRAL_1.5.0@MIRAL_1.5.0 1.0.0
397 (c++)"miral::pre_init(miral::CommandLineOption const&)@MIRAL_1.5.0" 1.0.0
398 (c++)"typeinfo for miral::WindowManagementPolicyAddendum3@MIRAL_1.5.0" 1.0.0
399 (c++)"miral::WindowManagerTools::active_output()@MIRAL_1.5.0" 1.0.0
0\ No newline at end of file400\ No newline at end of file
1401
=== added file 'debian/libmirclientcpp-dev.install'
--- debian/libmirclientcpp-dev.install 1970-01-01 00:00:00 +0000
+++ debian/libmirclientcpp-dev.install 2017-08-29 09:17:20 +0000
@@ -0,0 +1,2 @@
1usr/include/miral/mir/*/*
2usr/lib/*/pkgconfig/mirclientcpp.pc
03
=== added file 'debian/miral-examples.install'
--- debian/miral-examples.install 1970-01-01 00:00:00 +0000
+++ debian/miral-examples.install 2017-08-29 09:17:20 +0000
@@ -0,0 +1,9 @@
1usr/bin/miral-shell
2usr/bin/miral-run
3usr/bin/miral-kiosk
4usr/bin/miral-xrun
5usr/bin/miral-screencast
6usr/bin/miral-desktop
7usr/bin/miral-app
8usr/share/applications/miral-shell.desktop
9usr/share/icons/hicolor/scalable/apps/ubuntu-logo.svg
010
=== modified file 'examples/CMakeLists.txt'
--- examples/CMakeLists.txt 2017-07-14 11:29:56 +0000
+++ examples/CMakeLists.txt 2017-08-29 09:17:20 +0000
@@ -1,3 +1,6 @@
1add_subdirectory(miral-kiosk)
2add_subdirectory(miral-shell)
3
1set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -Wall -fno-strict-aliasing -Wextra")4set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -Wall -fno-strict-aliasing -Wextra")
25
3add_library(eglapp STATIC6add_library(eglapp STATIC
47
=== added directory 'examples/miral-kiosk'
=== added file 'examples/miral-kiosk/CMakeLists.txt'
--- examples/miral-kiosk/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ examples/miral-kiosk/CMakeLists.txt 2017-08-29 09:17:20 +0000
@@ -0,0 +1,12 @@
1include_directories(
2 ${PROJECT_SOURCE_DIR}/include/miral
3 ${PROJECT_SOURCE_DIR}/include/client
4)
5
6mir_add_wrapped_executable(miral-kiosk
7 kiosk_main.cpp
8 kiosk_window_manager.cpp kiosk_window_manager.h
9 sw_splash.cpp sw_splash.h
10)
11
12target_link_libraries(miral-kiosk miral)
013
=== added file 'examples/miral-kiosk/kiosk_main.cpp'
--- examples/miral-kiosk/kiosk_main.cpp 1970-01-01 00:00:00 +0000
+++ examples/miral-kiosk/kiosk_main.cpp 2017-08-29 09:17:20 +0000
@@ -0,0 +1,94 @@
1/*
2 * Copyright © 2016 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * under the terms of the GNU General Public License version 2 or 3 as as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Alan Griffiths <alan@octopull.co.uk>
17 */
18
19#include "kiosk_window_manager.h"
20
21#include <miral/runner.h>
22#include <miral/application_authorizer.h>
23#include <miral/command_line_option.h>
24#include <miral/keymap.h>
25#include <miral/set_window_management_policy.h>
26#include <miral/internal_client.h>
27
28#include <unistd.h>
29#include <atomic>
30
31namespace
32{
33struct KioskAuthorizer : miral::ApplicationAuthorizer
34{
35 KioskAuthorizer(SwSplash const& splash) : splash{splash}{}
36
37 virtual bool connection_is_allowed(miral::ApplicationCredentials const& creds) override
38 {
39 // Allow internal applications and (optionally) only ones that start "immediately"
40 // (For the sake of an example "immediately" means while the spash is running)
41 return getpid() == creds.pid() || !startup_only || splash.session().lock();
42 }
43
44 virtual bool configure_display_is_allowed(miral::ApplicationCredentials const& /*creds*/) override
45 {
46 return false;
47 }
48
49 virtual bool set_base_display_configuration_is_allowed(miral::ApplicationCredentials const& /*creds*/) override
50 {
51 return false;
52 }
53
54 virtual bool screencast_is_allowed(miral::ApplicationCredentials const& /*creds*/) override
55 {
56 return true;
57 }
58
59 virtual bool prompt_session_is_allowed(miral::ApplicationCredentials const& /*creds*/) override
60 {
61 return false;
62 }
63
64 static std::atomic<bool> startup_only;
65
66 SwSplash splash;
67};
68
69std::atomic<bool> KioskAuthorizer::startup_only{false};
70}
71
72int main(int argc, char const* argv[])
73{
74 using namespace miral;
75
76 SwSplash splash;
77
78 CommandLineOption startup_only{
79 [&](bool startup_only) {KioskAuthorizer::startup_only = startup_only; },
80 "kiosk-startup-apps-only",
81 "Only allow applications to connect during startup",
82 KioskAuthorizer::startup_only};
83
84 return MirRunner{argc, argv}.run_with(
85 {
86 CommandLineOption{[&](std::string const& ) { },
87 "desktop_file_hint", "Ignored for Unity8 compatability", "miral-shell.desktop"},
88 set_window_management_policy<KioskWindowManagerPolicy>(splash),
89 SetApplicationAuthorizer<KioskAuthorizer>{splash},
90 Keymap{},
91 startup_only,
92 StartupInternalClient{"Intro", splash}
93 });
94}
095
=== added file 'examples/miral-kiosk/kiosk_window_manager.cpp'
--- examples/miral-kiosk/kiosk_window_manager.cpp 1970-01-01 00:00:00 +0000
+++ examples/miral-kiosk/kiosk_window_manager.cpp 2017-08-29 09:17:20 +0000
@@ -0,0 +1,148 @@
1/*
2 * Copyright © 2016 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 or 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored By: Alan Griffiths <alan@octopull.co.uk>
17 */
18
19#include "kiosk_window_manager.h"
20
21#include <miral/application_info.h>
22#include <miral/window_info.h>
23#include <miral/window_manager_tools.h>
24
25#include <linux/input.h>
26
27namespace ms = mir::scene;
28using namespace miral;
29
30KioskWindowManagerPolicy::KioskWindowManagerPolicy(WindowManagerTools const& tools, SwSplash const& splash) :
31 CanonicalWindowManagerPolicy{tools},
32 splash{splash}
33{
34}
35
36bool KioskWindowManagerPolicy::handle_keyboard_event(MirKeyboardEvent const* event)
37{
38 auto const action = mir_keyboard_event_action(event);
39 auto const scan_code = mir_keyboard_event_scan_code(event);
40 auto const modifiers = mir_keyboard_event_modifiers(event) & modifier_mask;
41
42 if (action == mir_keyboard_action_down &&
43 modifiers == mir_input_event_modifier_alt &&
44 scan_code == KEY_TAB)
45 {
46 tools.focus_next_application();
47
48 return true;
49 }
50 else if (action == mir_keyboard_action_down &&
51 modifiers == mir_input_event_modifier_alt &&
52 scan_code == KEY_GRAVE)
53 {
54 tools.focus_next_within_application();
55
56 return true;
57 }
58 else if (action == mir_keyboard_action_down &&
59 modifiers == (mir_input_event_modifier_alt | mir_input_event_modifier_shift) &&
60 scan_code == KEY_GRAVE)
61 {
62 tools.focus_prev_within_application();
63
64 return true;
65 }
66 else if (action == mir_keyboard_action_down && scan_code == KEY_F4)
67 {
68 switch (modifiers & modifier_mask)
69 {
70 case mir_input_event_modifier_alt:
71 tools.ask_client_to_close(tools.active_window());;
72 return true;
73
74 default:
75 break;
76 }
77 }
78
79 return false;
80}
81
82bool KioskWindowManagerPolicy::handle_touch_event(MirTouchEvent const* event)
83{
84 auto const count = mir_touch_event_point_count(event);
85
86 long total_x = 0;
87 long total_y = 0;
88
89 for (auto i = 0U; i != count; ++i)
90 {
91 total_x += mir_touch_event_axis_value(event, i, mir_touch_axis_x);
92 total_y += mir_touch_event_axis_value(event, i, mir_touch_axis_y);
93 }
94
95 Point const cursor{total_x/count, total_y/count};
96
97 tools.select_active_window(tools.window_at(cursor));
98
99 return false;
100}
101
102bool KioskWindowManagerPolicy::handle_pointer_event(MirPointerEvent const* event)
103{
104 auto const action = mir_pointer_event_action(event);
105
106 Point const cursor{
107 mir_pointer_event_axis_value(event, mir_pointer_axis_x),
108 mir_pointer_event_axis_value(event, mir_pointer_axis_y)};
109
110 if (action == mir_pointer_action_button_down)
111 {
112 tools.select_active_window(tools.window_at(cursor));
113 }
114
115 return false;
116}
117
118void KioskWindowManagerPolicy::advise_focus_gained(WindowInfo const& info)
119{
120 CanonicalWindowManagerPolicy::advise_focus_gained(info);
121
122 if (auto session = splash.session().lock())
123 {
124 auto const& app_info = tools.info_for(session);
125
126 for (auto const& s : app_info.windows())
127 tools.raise_tree(s);
128 }
129}
130
131void KioskWindowManagerPolicy::advise_new_window(WindowInfo const& window_info)
132{
133 // We do this here, not in place_new_window() so that clients get a resize event.
134 // This shouldn't be necessary, but works better with the gtk-mir backend.
135 if (window_info.type() == mir_window_type_normal &&
136 !window_info.parent() &&
137 window_info.state() == mir_window_state_restored)
138 {
139 WindowSpecification specification;
140
141 specification.state() = mir_window_state_maximized;
142
143 tools.place_and_size_for_state(specification, window_info);
144 tools.modify_window(window_info.window(), specification);
145 }
146
147 CanonicalWindowManagerPolicy::advise_new_window(window_info);
148}
0149
=== added file 'examples/miral-kiosk/kiosk_window_manager.h'
--- examples/miral-kiosk/kiosk_window_manager.h 1970-01-01 00:00:00 +0000
+++ examples/miral-kiosk/kiosk_window_manager.h 2017-08-29 09:17:20 +0000
@@ -0,0 +1,52 @@
1/*
2 * Copyright © 2016 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 or 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored By: Alan Griffiths <alan@octopull.co.uk>
17 */
18
19#ifndef MIRAL_KIOSK_WINDOW_MANAGER_H
20#define MIRAL_KIOSK_WINDOW_MANAGER_H
21
22#include "sw_splash.h"
23
24#include <miral/canonical_window_manager.h>
25
26using namespace mir::geometry;
27
28class KioskWindowManagerPolicy : public miral::CanonicalWindowManagerPolicy
29{
30public:
31 KioskWindowManagerPolicy(miral::WindowManagerTools const& tools, SwSplash const&);
32
33 void advise_focus_gained(miral::WindowInfo const& info) override;
34
35 virtual void advise_new_window(miral::WindowInfo const& window_info) override;
36
37 bool handle_keyboard_event(MirKeyboardEvent const* event) override;
38 bool handle_touch_event(MirTouchEvent const* event) override;
39 bool handle_pointer_event(MirPointerEvent const* event) override;
40
41private:
42 static const int modifier_mask =
43 mir_input_event_modifier_alt |
44 mir_input_event_modifier_shift |
45 mir_input_event_modifier_sym |
46 mir_input_event_modifier_ctrl |
47 mir_input_event_modifier_meta;
48
49 SwSplash const splash;
50};
51
52#endif /* MIRAL_KIOSK_WINDOW_MANAGER_H */
053
=== added file 'examples/miral-kiosk/sw_splash.cpp'
--- examples/miral-kiosk/sw_splash.cpp 1970-01-01 00:00:00 +0000
+++ examples/miral-kiosk/sw_splash.cpp 2017-08-29 09:17:20 +0000
@@ -0,0 +1,173 @@
1/*
2 * Copyright © 2016 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 or 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Alan Griffiths <alan@octopull.co.uk>
17 */
18
19#include "sw_splash.h"
20
21#include <mir/client/display_config.h>
22#include <mir/client/surface.h>
23#include <mir/client/window.h>
24#include <mir/client/window_spec.h>
25
26#include <mir_toolkit/mir_buffer_stream.h>
27
28#include <chrono>
29#include <cstring>
30#include <thread>
31#include <mutex>
32
33namespace
34{
35MirPixelFormat find_8888_format(MirConnection* connection)
36{
37 unsigned int const num_formats = 32;
38 MirPixelFormat pixel_formats[num_formats];
39 unsigned int valid_formats;
40 mir_connection_get_available_surface_formats(connection, pixel_formats, num_formats, &valid_formats);
41
42 for (unsigned int i = 0; i < num_formats; ++i)
43 {
44 MirPixelFormat cur_pf = pixel_formats[i];
45 if (cur_pf == mir_pixel_format_abgr_8888 ||
46 cur_pf == mir_pixel_format_argb_8888)
47 {
48 return cur_pf;
49 }
50 }
51
52 for (unsigned int i = 0; i < num_formats; ++i)
53 {
54 MirPixelFormat cur_pf = pixel_formats[i];
55 if (cur_pf == mir_pixel_format_xbgr_8888 ||
56 cur_pf == mir_pixel_format_xrgb_8888)
57 {
58 return cur_pf;
59 }
60 }
61
62 return *pixel_formats;
63}
64
65auto create_window(MirConnection* connection, mir::client::Surface const& surface) -> mir::client::Window
66{
67 int id = 0;
68 int width = 0;
69 int height = 0;
70
71 mir::client::DisplayConfig{connection}.for_each_output([&](MirOutput const* output)
72 {
73 if (mir_output_get_connection_state(output) == mir_output_connection_state_connected &&
74 mir_output_is_enabled(output))
75 {
76 id = mir_output_get_id(output);
77
78 MirOutputMode const* mode = mir_output_get_current_mode(output);
79 width = mir_output_mode_get_width(mode);
80 height = mir_output_mode_get_height(mode);
81 }
82 });
83
84 return mir::client::WindowSpec::for_normal_window(connection, width, height)
85 .set_name("splash")
86 .set_fullscreen_on_output(id)
87 .add_surface(surface, width, height, 0, 0)
88 .create_window();
89}
90
91void render_pattern(MirGraphicsRegion *region, uint8_t pattern[])
92{
93 char *row = region->vaddr;
94
95 for (int j = 0; j < region->height; j++)
96 {
97 uint32_t *pixel = (uint32_t*)row;
98
99 for (int i = 0; i < region->width; i++)
100 memcpy(pixel+i, pattern, sizeof pixel[i]);
101
102 row += region->stride;
103 }
104}
105}
106
107struct SwSplash::Self
108{
109 std::mutex mutex;
110 std::weak_ptr<mir::scene::Session> session;
111};
112
113SwSplash::SwSplash() : self{std::make_shared<Self>()} {}
114
115SwSplash::~SwSplash() = default;
116
117void SwSplash::operator()(std::weak_ptr<mir::scene::Session> const& session)
118{
119 std::lock_guard<decltype(self->mutex)> lock{self->mutex};
120 self->session = session;
121}
122
123auto SwSplash::session() const -> std::weak_ptr<mir::scene::Session>
124{
125 std::lock_guard<decltype(self->mutex)> lock{self->mutex};
126 return self->session;
127}
128
129void SwSplash::operator()(MirConnection* connection)
130{
131 MirPixelFormat pixel_format = find_8888_format(connection);
132
133 uint8_t pattern[4] = { 0x14, 0x48, 0xDD, 0xFF };
134
135 switch(pixel_format)
136 {
137 case mir_pixel_format_abgr_8888:
138 case mir_pixel_format_xbgr_8888:
139 std::swap(pattern[2],pattern[0]);
140 break;
141
142 case mir_pixel_format_argb_8888:
143 case mir_pixel_format_xrgb_8888:
144 break;
145
146 default:
147 return;
148 };
149
150
151 mir::client::Surface surface{mir_connection_create_render_surface_sync(connection, 42, 42)};
152 MirBufferStream* buffer_stream = mir_render_surface_get_buffer_stream(surface, 42, 42, pixel_format);
153
154 auto const window = create_window(connection, surface);
155
156 MirGraphicsRegion graphics_region;
157
158 auto const time_limit = std::chrono::steady_clock::now() + std::chrono::seconds(2);
159
160 do
161 {
162 mir_buffer_stream_get_graphics_region(buffer_stream, &graphics_region);
163
164 render_pattern(&graphics_region, pattern);
165 mir_buffer_stream_swap_buffers_sync(buffer_stream);
166
167 for (auto& x : pattern)
168 x = 3*x/4;
169
170 std::this_thread::sleep_for(std::chrono::milliseconds(200));
171 }
172 while (std::chrono::steady_clock::now() < time_limit);
173}
0174
=== added file 'examples/miral-kiosk/sw_splash.h'
--- examples/miral-kiosk/sw_splash.h 1970-01-01 00:00:00 +0000
+++ examples/miral-kiosk/sw_splash.h 2017-08-29 09:17:20 +0000
@@ -0,0 +1,44 @@
1/*
2 * Copyright © 2016 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 or 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Alan Griffiths <alan@octopull.co.uk>
17 */
18
19#ifndef MIRAL_SHELL_SW_SPLASH_H
20#define MIRAL_SHELL_SW_SPLASH_H
21
22#include <mir_toolkit/client_types.h>
23
24#include <memory>
25
26namespace mir { class Server; namespace scene { class Session; }}
27
28// A very simple s/w rendered splash animation
29class SwSplash
30{
31public:
32 SwSplash();
33 ~SwSplash();
34
35 void operator()(MirConnection* connection);
36 void operator()(std::weak_ptr<mir::scene::Session> const& session);
37 auto session() const -> std::weak_ptr<mir::scene::Session>;
38
39private:
40 struct Self;
41 std::shared_ptr<Self> const self;
42};
43
44#endif //MIRAL_SHELL_SW_SPLASH_H
045
=== added directory 'examples/miral-shell'
=== added file 'examples/miral-shell/CMakeLists.txt'
--- examples/miral-shell/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ examples/miral-shell/CMakeLists.txt 2017-08-29 09:17:20 +0000
@@ -0,0 +1,65 @@
1include_directories(
2 ${PROJECT_SOURCE_DIR}/include/miral
3 ${PROJECT_SOURCE_DIR}/include/client
4)
5
6add_subdirectory(spinner)
7add_subdirectory(desktop)
8
9add_custom_target(miral-run ALL
10 cp ${CMAKE_CURRENT_SOURCE_DIR}/miral-run.sh ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/miral-run
11)
12
13install(PROGRAMS ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/miral-run
14 DESTINATION ${CMAKE_INSTALL_PREFIX}/bin
15)
16
17add_custom_target(miral-xrun ALL
18 cp ${CMAKE_CURRENT_SOURCE_DIR}/miral-xrun.sh ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/miral-xrun
19)
20
21install(PROGRAMS ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/miral-xrun
22 DESTINATION ${CMAKE_INSTALL_PREFIX}/bin
23)
24
25add_custom_target(miral-screencast ALL
26 cp ${CMAKE_CURRENT_SOURCE_DIR}/miral-screencast.sh ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/miral-screencast
27)
28
29install(PROGRAMS ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/miral-screencast
30 DESTINATION ${CMAKE_INSTALL_PREFIX}/bin
31)
32
33add_custom_target(miral-desktop ALL
34 cp ${CMAKE_CURRENT_SOURCE_DIR}/miral-desktop.sh ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/miral-desktop
35)
36
37install(PROGRAMS ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/miral-desktop
38 DESTINATION ${CMAKE_INSTALL_PREFIX}/bin
39)
40
41add_custom_target(miral-app ALL
42 cp ${CMAKE_CURRENT_SOURCE_DIR}/miral-app.sh ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/miral-app
43)
44
45install(PROGRAMS ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/miral-app
46 DESTINATION ${CMAKE_INSTALL_PREFIX}/bin
47)
48
49mir_add_wrapped_executable(miral-shell
50 shell_main.cpp
51 tiling_window_manager.cpp tiling_window_manager.h
52 floating_window_manager.cpp floating_window_manager.h
53 decoration_provider.cpp decoration_provider.h
54 titlebar_config.cpp titlebar_config.h
55)
56
57pkg_check_modules(FREETYPE freetype2 REQUIRED)
58target_include_directories(miral-shell PRIVATE ${FREETYPE_INCLUDE_DIRS})
59target_compile_definitions(miral-shell PRIVATE -DTYPO_SUPPORTS_FREETYPE)
60target_link_libraries(miral-shell
61 miral-spinner
62 miral
63 ${FREETYPE_LIBRARIES}
64)
65
066
=== added file 'examples/miral-shell/decoration_provider.cpp'
--- examples/miral-shell/decoration_provider.cpp 1970-01-01 00:00:00 +0000
+++ examples/miral-shell/decoration_provider.cpp 2017-08-29 09:17:20 +0000
@@ -0,0 +1,666 @@
1/*
2 * Copyright © 2016-2017 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 or 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Alan Griffiths <alan@octopull.co.uk>
17 */
18
19#include "decoration_provider.h"
20#include "titlebar_config.h"
21
22#include <mir/client/display_config.h>
23#include <mir/client/window_spec.h>
24
25#include <mir_toolkit/mir_buffer_stream.h>
26
27#include <ft2build.h>
28#include FT_FREETYPE_H
29
30#include <locale>
31#include <codecvt>
32#include <string>
33#include <cstring>
34#include <sstream>
35
36#include <iostream>
37
38namespace
39{
40int const title_bar_height = 12;
41char const* const wallpaper_name = "wallpaper";
42
43void null_window_callback(MirWindow*, void*) {}
44
45struct preferred_codecvt : std::codecvt_byname<wchar_t, char, std::mbstate_t>
46{
47 preferred_codecvt() : std::codecvt_byname<wchar_t, char, std::mbstate_t>("") {}
48 ~preferred_codecvt() = default;
49};
50
51struct Printer
52{
53 Printer();
54 ~Printer();
55 Printer(Printer const&) = delete;
56 Printer& operator=(Printer const&) = delete;
57
58 void print(MirGraphicsRegion const& region, std::string const& title, int const intensity);
59 void printhelp(MirGraphicsRegion const& region);
60
61private:
62 std::wstring_convert<preferred_codecvt> converter;
63
64 bool working = false;
65 FT_Library lib;
66 FT_Face face;
67};
68
69void paint_surface(MirBufferStream* buffer_stream, std::string const& title, int const intensity)
70{
71 // TODO sometimes buffer_stream is nullptr - find out why (and fix).
72 // (Only observed when creating a lot of clients at once)
73 if (!buffer_stream)
74 return;
75
76 MirGraphicsRegion region;
77 mir_buffer_stream_get_graphics_region(buffer_stream, &region);
78
79 char* row = region.vaddr;
80
81 for (int j = 0; j != region.height; ++j)
82 {
83 memset(row, intensity, 4*region.width);
84 row += region.stride;
85 }
86
87 static Printer printer;
88 printer.print(region, title, intensity);
89
90 mir_buffer_stream_swap_buffers_sync(buffer_stream);
91}
92
93Printer::Printer()
94{
95 if (FT_Init_FreeType(&lib))
96 return;
97
98 if (FT_New_Face(lib, titlebar::font_file().c_str(), 0, &face))
99 {
100 std::cerr << "WARNING: failed to load titlebar font: \"" << titlebar::font_file() << "\"\n";
101 FT_Done_FreeType(lib);
102 return;
103 }
104
105 FT_Set_Pixel_Sizes(face, 0, 10);
106 working = true;
107}
108
109Printer::~Printer()
110{
111 if (working)
112 {
113 FT_Done_Face(face);
114 FT_Done_FreeType(lib);
115 }
116}
117
118void Printer::print(MirGraphicsRegion const& region, std::string const& title_, int const intensity)
119try
120{
121 if (!working)
122 return;
123
124 auto title = converter.from_bytes(title_);
125
126 int base_x = 2;
127 int base_y = region.height-2;
128
129 for (auto const& ch : title)
130 {
131 FT_Load_Glyph(face, FT_Get_Char_Index(face, ch), FT_LOAD_DEFAULT);
132 auto const glyph = face->glyph;
133 FT_Render_Glyph(glyph, FT_RENDER_MODE_NORMAL);
134
135 auto const& bitmap = glyph->bitmap;
136 auto const x = base_x + glyph->bitmap_left;
137
138 if (static_cast<int>(x + bitmap.width) <= region.width)
139 {
140 unsigned char* src = bitmap.buffer;
141
142 auto const y = base_y - glyph->bitmap_top;
143 char* dest = region.vaddr + y*region.stride + 4*x;
144
145 for (auto row = 0u; row != std::min(bitmap.rows, glyph->bitmap_top+2u); ++row)
146 {
147 for (auto col = 0u; col != bitmap.width; ++col)
148 memset(dest+ 4*col, (intensity*(0xff^src[col]))/0xff, 4);
149
150 src += bitmap.pitch;
151 dest += region.stride;
152 }
153 }
154
155 base_x += glyph->advance.x >> 6;
156 base_y += glyph->advance.y >> 6;
157 }
158}
159catch (...)
160{
161 std::cerr << "WARNING: failed render title: \"" << title_ << "\"\n";
162}
163
164void Printer::printhelp(MirGraphicsRegion const& region)
165{
166 if (!working)
167 return;
168
169 static char const* const helptext[] =
170 {
171 "Welcome to miral-shell",
172 "",
173 "Keyboard shortcuts:",
174 "",
175 " o Switch apps: Alt-Tab, tap or click on the corresponding window",
176 " o Next (previous) app window: Alt-` (Alt-Shift-`)",
177 "",
178 " o Move window: Alt-leftmousebutton drag (three finger drag)",
179 " o Resize window: Alt-middle_button drag (three finger pinch)",
180 "",
181 " o Maximize/restore current window (to display size). : Alt-F11",
182 " o Maximize/restore current window (to display height): Shift-F11",
183 " o Maximize/restore current window (to display width) : Ctrl-F11",
184 "",
185 " o Switch workspace: Meta-Alt-[F1|F2|F3|F4]",
186 " o Switch workspace taking active window: Meta-Ctrl-[F1|F2|F3|F4]",
187 "",
188 " o To exit: Ctrl-Alt-BkSp",
189 };
190
191 int help_width = 0;
192 unsigned int help_height = 0;
193 unsigned int line_height = 0;
194
195 for (auto const* rawline : helptext)
196 {
197 int line_width = 0;
198
199 auto const line = converter.from_bytes(rawline);
200
201 auto const fwidth = std::min(region.width / 60, 20);
202
203 FT_Set_Pixel_Sizes(face, fwidth, 0);
204
205 for (auto const& ch : line)
206 {
207 FT_Load_Glyph(face, FT_Get_Char_Index(face, ch), FT_LOAD_DEFAULT);
208 auto const glyph = face->glyph;
209 FT_Render_Glyph(glyph, FT_RENDER_MODE_NORMAL);
210
211 line_width += glyph->advance.x >> 6;
212 line_height = std::max(line_height, glyph->bitmap.rows + glyph->bitmap.rows/2);
213 }
214
215 if (help_width < line_width) help_width = line_width;
216 help_height += line_height;
217 }
218
219 int base_y = (region.height - help_height)/2;
220
221 for (auto const* rawline : helptext)
222 {
223 int base_x = (region.width - help_width)/2;
224
225 auto const line = converter.from_bytes(rawline);
226
227 for (auto const& ch : line)
228 {
229 FT_Load_Glyph(face, FT_Get_Char_Index(face, ch), FT_LOAD_DEFAULT);
230 auto const glyph = face->glyph;
231 FT_Render_Glyph(glyph, FT_RENDER_MODE_NORMAL);
232
233 auto const& bitmap = glyph->bitmap;
234 auto const x = base_x + glyph->bitmap_left;
235
236 if (static_cast<int>(x + bitmap.width) <= region.width)
237 {
238 unsigned char* src = bitmap.buffer;
239
240 auto const y = base_y - glyph->bitmap_top;
241 char* dest = region.vaddr + y * region.stride + 4 * x;
242
243 for (auto row = 0u; row != bitmap.rows; ++row)
244 {
245 for (auto col = 0u; col != 4 * bitmap.width; ++col)
246 dest[col] |= src[col / 4]/2;
247
248 src += bitmap.pitch;
249 dest += region.stride;
250
251 if (dest > region.vaddr + region.height * region.stride)
252 break;
253 }
254 }
255
256 base_x += glyph->advance.x >> 6;
257 }
258 base_y += line_height;
259 }
260}
261
262void render_background(MirBufferStream* buffer_stream, MirGraphicsRegion& graphics_region)
263{
264 static uint8_t const pattern[4] = {0x00, 0x00, 0x00, 0x00 };
265
266 char* row = (&graphics_region)->vaddr;
267
268 for (int j = 0; j < (&graphics_region)->height; j++)
269 {
270 uint32_t* pixel = (uint32_t*)row;
271
272 for (int i = 0; i < (&graphics_region)->width; i++)
273 memcpy(pixel + i, pattern, sizeof pixel[i]);
274
275 row += (&graphics_region)->stride;
276 }
277
278 static Printer printer;
279 printer.printhelp(*&graphics_region);
280
281 mir_buffer_stream_swap_buffers_sync(buffer_stream);
282}
283}
284
285using namespace mir::client;
286using namespace mir::geometry;
287
288DecorationProvider::DecorationProvider(miral::WindowManagerTools const& tools) : tools{tools}
289{
290
291}
292
293DecorationProvider::~DecorationProvider()
294{
295}
296
297void DecorationProvider::stop()
298{
299 enqueue_work([this]
300 {
301 std::lock_guard<decltype(mutex)> lock{mutex};
302 window_to_titlebar.clear();
303 });
304
305 enqueue_work([this]
306 {
307 if (connection)
308 {
309 wallpaper.erase(begin(wallpaper), end(wallpaper));
310 }
311 connection.reset();
312 });
313 stop_work();
314}
315
316void DecorationProvider::operator()(Connection connection)
317{
318 this->connection = connection;
319
320 DisplayConfig const display_conf{this->connection};
321
322 display_conf.for_each_output([this](MirOutput const* output)
323 {
324 if (!mir_output_is_enabled(output))
325 return;
326
327 auto const mode = mir_output_get_current_mode(output);
328 auto const output_id = mir_output_get_id(output);
329 auto const width = mir_output_mode_get_width(mode);
330 auto const height = mir_output_mode_get_height(mode);
331
332 Surface surface{mir_connection_create_render_surface_sync(DecorationProvider::connection, width, height)};
333
334 auto const buffer_stream =
335 mir_render_surface_get_buffer_stream(surface, width, height, mir_pixel_format_xrgb_8888);
336
337 auto window = WindowSpec::for_gloss(DecorationProvider::connection, width, height)
338 .set_fullscreen_on_output(output_id)
339 .set_event_handler(&handle_event_for_background, this)
340 .add_surface(surface, width, height, 0, 0)
341 .set_name(wallpaper_name).create_window();
342
343 wallpaper.push_back(Wallpaper{surface, window, buffer_stream});
344
345 MirGraphicsRegion graphics_region;
346 mir_buffer_stream_get_graphics_region(buffer_stream, &graphics_region);
347 render_background(buffer_stream, graphics_region);
348 });
349
350 start_work();
351}
352
353void DecorationProvider::operator()(std::weak_ptr<mir::scene::Session> const& session)
354{
355 std::lock_guard<decltype(mutex)> lock{mutex};
356 this->weak_session = session;
357}
358
359auto DecorationProvider::session() const -> std::shared_ptr<mir::scene::Session>
360{
361 std::lock_guard<decltype(mutex)> lock{mutex};
362 return weak_session.lock();
363}
364
365void DecorationProvider::handle_event(MirWindow* window, MirEvent const* ev, void* context_)
366{
367 auto* const context = (Data*)context_;
368
369 switch (mir_event_get_type(ev))
370 {
371 case mir_event_type_resize:
372 {
373 MirResizeEvent const* resize = mir_event_get_resize_event(ev);
374 int const new_width = mir_resize_event_get_width(resize);
375 int const new_height = mir_resize_event_get_height(resize);
376 mir_render_surface_set_size(context->surface, new_width, new_height);
377 WindowSpec::for_changes(context->connection)
378 .add_surface(context->surface, new_width, new_height, 0, 0)
379 .apply_to(window);
380 break;
381 }
382
383 default:
384 break;
385 }
386}
387
388void DecorationProvider::create_titlebar_for(miral::Window const& window)
389{
390 if (is_decoration(window)) return;
391
392 enqueue_work([this, window]
393 {
394 auto const width = window.size().width.as_int();
395 std::ostringstream buffer;
396 buffer << std::shared_ptr<mir::scene::Surface>(window).get();
397
398 Surface surface{mir_connection_create_render_surface_sync(this->connection, width, title_bar_height)};
399
400 std::lock_guard<decltype(mutex)> lock{mutex};
401
402 auto const data = &window_to_titlebar[window];
403 data->connection = connection;
404 data->surface = surface;
405 data->stream = mir_render_surface_get_buffer_stream(surface, width, title_bar_height, mir_pixel_format_xrgb_8888);
406 windows_awaiting_titlebar[buffer.str()] = window;
407
408 WindowSpec::for_gloss(connection, width, title_bar_height)
409 .add_surface(surface, width, title_bar_height, 0, 0)
410 .set_name(buffer.str().c_str())
411 .set_event_handler(&handle_event, data)
412 .create_window(insert, data);
413 });
414}
415
416void DecorationProvider::paint_titlebar_for(miral::WindowInfo const& info, int intensity)
417{
418 if (auto data = find_titlebar_data(info.window()))
419 {
420 data->intensity = intensity;
421
422 auto const title = info.name();
423
424 enqueue_work([this, stream=data->stream, title, intensity]{ paint_surface(stream, title, intensity); });
425 }
426}
427
428void DecorationProvider::destroy_titlebar_for(miral::Window const& window)
429{
430 if (auto data = find_titlebar_data(window))
431 {
432 if (auto surface = data->titlebar.exchange(nullptr))
433 {
434 enqueue_work([surface]
435 {
436 mir_window_release(surface, &null_window_callback, nullptr);
437 });
438 }
439
440 if (data->titlebar.load())
441 {
442 enqueue_work([this, window]
443 {
444 std::lock_guard<decltype(mutex)> lock{mutex};
445 window_to_titlebar.erase(window);
446 });
447 }
448 else
449 {
450 data->on_create = [this, window](MirWindow*)
451 {
452 enqueue_work([this, window]
453 {
454 std::lock_guard<decltype(mutex)> lock{mutex};
455 window_to_titlebar.erase(window);
456 });
457 };
458 }
459 }
460}
461
462void DecorationProvider::resize_titlebar_for(miral::WindowInfo const& window_info, Size const& size)
463{
464 auto const window = window_info.window();
465
466 if (window.size().width == size.width)
467 return;
468
469 if (auto titlebar_window = find_titlebar_window(window))
470 {
471 titlebar_window.resize({size.width, title_bar_height});
472
473 repaint_titlebar_for(window_info);
474 }
475}
476
477void DecorationProvider::place_new_decoration(miral::WindowSpecification& window_spec)
478{
479 auto const name = window_spec.name().value();
480 if (name == wallpaper_name) return;
481
482 std::lock_guard<decltype(mutex)> lock{mutex};
483
484 auto const scene_surface = windows_awaiting_titlebar[name].lock();
485 windows_awaiting_titlebar.erase(name);
486
487 auto& parent_info = tools.info_for(scene_surface);
488 auto const parent_window = parent_info.window();
489
490 window_spec.parent() = scene_surface;
491 window_spec.size() = Size{parent_window.size().width, Height{title_bar_height}};
492 window_spec.top_left() = parent_window.top_left() - Displacement{0, title_bar_height};
493}
494
495void DecorationProvider::advise_new_titlebar(miral::WindowInfo const& window_info)
496{
497 if (window_info.name() == wallpaper_name) return;
498
499 {
500 std::lock_guard<decltype(mutex)> lock{mutex};
501
502 window_to_titlebar[window_info.parent()].window = window_info.window();
503 }
504
505 tools.raise_tree(window_info.parent());
506}
507
508void DecorationProvider::advise_state_change(miral::WindowInfo const& window_info, MirWindowState state)
509{
510 if (auto titlebar = find_titlebar_window(window_info.window()))
511 {
512 miral::WindowSpecification modifications;
513 switch (state)
514 {
515 case mir_window_state_hidden:
516 case mir_window_state_minimized:
517 case mir_window_state_fullscreen:
518 modifications.state() = mir_window_state_hidden;
519 break;
520
521 default:
522 modifications.state() = mir_window_state_restored;
523 break;
524 }
525
526 tools.modify_window(titlebar, modifications);
527 repaint_titlebar_for(window_info);
528 }
529}
530
531void DecorationProvider::repaint_titlebar_for(miral::WindowInfo const& window_info)
532{
533 if (auto data = find_titlebar_data(window_info.window()))
534 {
535 auto const title = window_info.name();
536
537 enqueue_work([this, stream=data->stream, title, intensity=data->intensity.load()]
538 { paint_surface(stream, title, intensity); });
539 }
540}
541
542DecorationProvider::Data::~Data()
543{
544 if (auto surface = titlebar.exchange(nullptr))
545 mir_window_release(surface, &null_window_callback, nullptr);
546}
547
548void DecorationProvider::insert(MirWindow* surface, Data* data)
549{
550 data->on_create(surface);
551 data->titlebar = surface;
552}
553
554DecorationProvider::Data* DecorationProvider::find_titlebar_data(miral::Window const& window)
555{
556 std::lock_guard<decltype(mutex)> lock{mutex};
557
558 auto const find = window_to_titlebar.find(window);
559
560 return (find != window_to_titlebar.end()) ? &find->second : nullptr;
561}
562
563miral::Window DecorationProvider::find_titlebar_window(miral::Window const& window) const
564{
565 std::lock_guard<decltype(mutex)> lock{mutex};
566
567 auto const find = window_to_titlebar.find(window);
568
569 return (find != window_to_titlebar.end()) ? find->second.window : miral::Window{};
570}
571
572bool DecorationProvider::is_decoration(miral::Window const& window) const
573{
574 return window.application() == session();
575}
576
577bool DecorationProvider::is_titlebar(miral::WindowInfo const& window_info) const
578{
579 return window_info.window().application() == session() && window_info.name() != wallpaper_name;
580}
581
582void DecorationProvider::handle_event_for_background(MirWindow* window, MirEvent const* event, void* context)
583{
584 static_cast<DecorationProvider*>(context)->handle_event_for_background(window, event);
585}
586
587void DecorationProvider::handle_event_for_background(MirWindow* window, MirEvent const* ev)
588{
589 switch (mir_event_get_type(ev))
590 {
591 case mir_event_type_resize:
592 {
593 MirResizeEvent const* resize = mir_event_get_resize_event(ev);
594 int const new_width = mir_resize_event_get_width(resize);
595 int const new_height = mir_resize_event_get_height(resize);
596
597 enqueue_work([window, new_width, new_height, this]()
598 {
599 auto found = find_if(begin(wallpaper), end(wallpaper), [&](Wallpaper const& w) { return w.window == window;});
600 if (found == end(wallpaper)) return;
601
602 mir_buffer_stream_set_size(found->stream, new_width, new_height);
603 mir_render_surface_set_size(found->surface, new_width, new_height);
604
605 WindowSpec::for_changes(connection)
606 .add_surface(found->surface, new_width, new_height, 0, 0)
607 .apply_to(window);
608
609 MirGraphicsRegion graphics_region;
610
611 // We expect a buffer of the right size so we shouldn't need to limit repaints
612 // but we also to avoid an infinite loop.
613 int repaint_limit = 3;
614
615 do
616 {
617 mir_buffer_stream_get_graphics_region(found->stream, &graphics_region);
618 render_background(found->stream, graphics_region);
619 }
620 while ((new_width != graphics_region.width || new_height != graphics_region.height)
621 && --repaint_limit != 0);
622 });
623 break;
624 }
625
626 default:
627 break;
628 }
629}
630
631Worker::~Worker()
632{
633}
634
635void Worker::do_work()
636{
637 while (!work_done)
638 {
639 WorkQueue::value_type work;
640 {
641 std::unique_lock<decltype(work_mutex)> lock{work_mutex};
642 work_cv.wait(lock, [this] { return !work_queue.empty(); });
643 work = work_queue.front();
644 work_queue.pop();
645 }
646
647 work();
648 }
649}
650
651void Worker::enqueue_work(std::function<void()> const& functor)
652{
653 std::lock_guard<decltype(work_mutex)> lock{work_mutex};
654 work_queue.push(functor);
655 work_cv.notify_one();
656}
657
658void Worker::start_work()
659{
660 do_work();
661}
662
663void Worker::stop_work()
664{
665 enqueue_work([this] { work_done = true; });
666}
0667
=== added file 'examples/miral-shell/decoration_provider.h'
--- examples/miral-shell/decoration_provider.h 1970-01-01 00:00:00 +0000
+++ examples/miral-shell/decoration_provider.h 2017-08-29 09:17:20 +0000
@@ -0,0 +1,119 @@
1/*
2 * Copyright © 2016-2017 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 or 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Alan Griffiths <alan@octopull.co.uk>
17 */
18
19#ifndef MIRAL_SHELL_DECORATION_PROVIDER_H
20#define MIRAL_SHELL_DECORATION_PROVIDER_H
21
22
23#include <miral/window_manager_tools.h>
24
25#include <mir/client/connection.h>
26#include <mir/client/surface.h>
27#include <mir/client/window.h>
28
29#include <mir/geometry/rectangle.h>
30#include <mir_toolkit/client_types.h>
31
32#include <atomic>
33#include <map>
34#include <mutex>
35#include <condition_variable>
36#include <queue>
37
38class Worker
39{
40public:
41 ~Worker();
42
43 void start_work();
44 void enqueue_work(std::function<void()> const& functor);
45 void stop_work();
46
47private:
48 using WorkQueue = std::queue<std::function<void()>>;
49
50 std::mutex mutable work_mutex;
51 std::condition_variable work_cv;
52 WorkQueue work_queue;
53 bool work_done = false;
54
55 void do_work();
56};
57
58class DecorationProvider : Worker
59{
60public:
61 DecorationProvider(miral::WindowManagerTools const& tools);
62 ~DecorationProvider();
63
64 void operator()(mir::client::Connection connection);
65 void operator()(std::weak_ptr<mir::scene::Session> const& session);
66
67 auto session() const -> std::shared_ptr<mir::scene::Session>;
68
69 void create_titlebar_for(miral::Window const& window);
70 void place_new_decoration(miral::WindowSpecification& window_spec);
71 void paint_titlebar_for(miral::WindowInfo const& window, int intensity);
72 void destroy_titlebar_for(miral::Window const& window);
73 void resize_titlebar_for(miral::WindowInfo const& window_info, mir::geometry::Size const& size);
74 void advise_new_titlebar(miral::WindowInfo const& window_info);
75 void advise_state_change(miral::WindowInfo const& window_info, MirWindowState state);
76
77 void stop();
78
79 bool is_decoration(miral::Window const& window) const;
80 bool is_titlebar(miral::WindowInfo const& window_info) const;
81
82private:
83 struct Data
84 {
85 MirConnection* connection{nullptr};
86 mir::client::Surface surface;
87 MirBufferStream* stream{nullptr};
88 std::atomic<MirWindow*> titlebar{nullptr};
89 std::atomic<int> intensity{0xff};
90 std::function<void(MirWindow* surface)> on_create{[](MirWindow*){}};
91 miral::Window window;
92
93 ~Data();
94 };
95
96 using SurfaceMap = std::map<std::weak_ptr<mir::scene::Surface>, Data, std::owner_less<std::weak_ptr<mir::scene::Surface>>>;
97 using TitleMap = std::map<std::string, std::weak_ptr<mir::scene::Surface>>;
98
99 miral::WindowManagerTools tools;
100 std::mutex mutable mutex;
101 mir::client::Connection connection;
102 struct Wallpaper { mir::client::Surface surface; mir::client::Window window; MirBufferStream* stream; };
103 std::vector<Wallpaper> wallpaper;
104 std::weak_ptr<mir::scene::Session> weak_session;
105
106 SurfaceMap window_to_titlebar;
107 TitleMap windows_awaiting_titlebar;
108
109 static void insert(MirWindow* surface, Data* data);
110 Data* find_titlebar_data(miral::Window const& window);
111 miral::Window find_titlebar_window(miral::Window const& window) const;
112 void repaint_titlebar_for(miral::WindowInfo const& window_info);
113 static void handle_event(MirWindow* window, MirEvent const* ev, void* context_);
114 static void handle_event_for_background(MirWindow* window, MirEvent const* event, void* context_);
115 void handle_event_for_background(MirWindow* window, MirEvent const* ev);
116};
117
118
119#endif //MIRAL_SHELL_DECORATION_PROVIDER_H
0120
=== added directory 'examples/miral-shell/desktop'
=== added file 'examples/miral-shell/desktop/CMakeLists.txt'
--- examples/miral-shell/desktop/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ examples/miral-shell/desktop/CMakeLists.txt 2017-08-29 09:17:20 +0000
@@ -0,0 +1,12 @@
1set(ICON_NAME ubuntu-logo)
2set(PROGRAM_NAME miral-app)
3
4configure_file(miral-shell.desktop.in ${CMAKE_CURRENT_BINARY_DIR}/miral-shell.desktop @ONLY)
5
6install(FILES ${CMAKE_CURRENT_BINARY_DIR}/miral-shell.desktop
7 DESTINATION ${CMAKE_INSTALL_PREFIX}/share/applications
8)
9
10install(FILES ${ICON_NAME}.svg
11 DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/scalable/apps
12)
013
=== added file 'examples/miral-shell/desktop/miral-shell.desktop.in'
--- examples/miral-shell/desktop/miral-shell.desktop.in 1970-01-01 00:00:00 +0000
+++ examples/miral-shell/desktop/miral-shell.desktop.in 2017-08-29 09:17:20 +0000
@@ -0,0 +1,18 @@
1[Desktop Entry]
2Version=1.0
3Name=Miral Shell
4GenericName=Mir Shell
5Comment=A Mir Shell
6Keywords=Mir;Server;Shell
7Type=Application
8Icon=@ICON_NAME@
9Exec=@PROGRAM_NAME@
10Terminal=false
11Categories=Utility
12#MimeType=
13X-Ubuntu-Touch=true
14X-Ubuntu-Gettext-Domain=miral-shell
15X-Ubuntu-Single-Instance=true
16X-Ubuntu-Default-Department-ID=miral-shell
17#X-Screenshot=
18X-Ubuntu-Splash-Color=#FFFFFF
019
=== added file 'examples/miral-shell/desktop/ubuntu-logo.svg'
--- examples/miral-shell/desktop/ubuntu-logo.svg 1970-01-01 00:00:00 +0000
+++ examples/miral-shell/desktop/ubuntu-logo.svg 2017-08-29 09:17:20 +0000
@@ -0,0 +1,27 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!-- Generator: Adobe Illustrator 14.0.0, SVG Export Plug-In -->
3<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
4 <!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">
5]>
6<svg version="1.1"
7 xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
8 x="0px" y="0px" width="285px" height="285px" viewBox="-0.866 -0.866 285 285" enable-background="new -0.866 -0.866 285 285"
9 xml:space="preserve">
10<defs>
11</defs>
12<path fill="#DD4814" d="M283.465,141.734c0,78.273-63.457,141.73-141.734,141.73S0,220.008,0,141.734C0,63.455,63.453,0,141.73,0
13 S283.465,63.455,283.465,141.734z"/>
14<path fill="#FFFFFF" d="M45.356,122.812c-10.453,0-18.923,8.47-18.923,18.923c0,10.449,8.47,18.92,18.923,18.92
15 c10.449,0,18.92-8.471,18.92-18.92C64.276,131.281,55.806,122.812,45.356,122.812z M180.463,208.814
16 c-9.051,5.225-12.149,16.793-6.926,25.84c5.226,9.051,16.793,12.151,25.844,6.926c9.048-5.224,12.148-16.792,6.923-25.842
17 C201.08,206.691,189.511,203.59,180.463,208.814z M86.458,141.732c0-18.701,9.293-35.219,23.504-45.221L96.128,73.338
18 c-16.56,11.064-28.878,27.978-33.995,47.788c5.977,4.872,9.796,12.291,9.796,20.608c0,8.315-3.819,15.734-9.797,20.605
19 c5.116,19.812,17.435,36.726,33.995,47.789l13.835-23.175C95.751,176.953,86.458,160.436,86.458,141.732z M141.733,86.457
20 c28.877,0,52.564,22.141,55.047,50.373l26.968-0.394c-1.327-20.844-10.432-39.562-24.425-53.319
21 c-7.194,2.718-15.505,2.306-22.688-1.842c-7.192-4.152-11.705-11.156-12.941-18.757c-6.992-1.935-14.351-2.99-21.96-2.99
22 c-13.086,0-25.449,3.072-36.431,8.512l13.146,23.56C125.526,88.307,133.412,86.457,141.733,86.457z M141.733,197.008
23 c-8.322,0-16.207-1.85-23.285-5.143L105.3,215.427c10.983,5.438,23.347,8.511,36.433,8.511c7.609,0,14.968-1.055,21.961-2.99
24 c1.236-7.601,5.75-14.605,12.943-18.76c7.183-4.146,15.494-4.558,22.688-1.839c13.992-13.758,23.097-32.476,24.422-53.32
25 l-26.968-0.394C194.298,174.871,170.61,197.008,141.733,197.008z M180.46,74.649c9.05,5.227,20.619,2.126,25.842-6.921
26 c5.226-9.051,2.128-20.619-6.923-25.845c-9.049-5.224-20.617-2.124-25.843,6.927C168.312,57.857,171.412,69.426,180.46,74.649z"/>
27</svg>
028
=== added file 'examples/miral-shell/floating_window_manager.cpp'
--- examples/miral-shell/floating_window_manager.cpp 1970-01-01 00:00:00 +0000
+++ examples/miral-shell/floating_window_manager.cpp 2017-08-29 09:17:20 +0000
@@ -0,0 +1,801 @@
1/*
2 * Copyright © 2016-2017 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 or 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Alan Griffiths <alan@octopull.co.uk>
17 */
18
19#include "floating_window_manager.h"
20#include "decoration_provider.h"
21
22#include <miral/application_info.h>
23#include <miral/internal_client.h>
24#include <miral/window_info.h>
25#include <miral/window_manager_tools.h>
26
27#include <linux/input.h>
28#include <csignal>
29
30using namespace miral;
31
32namespace
33{
34DeltaY const title_bar_height{12};
35
36struct PolicyData
37{
38 bool in_hidden_workspace{false};
39
40 MirWindowState old_state;
41};
42
43inline PolicyData& policy_data_for(WindowInfo const& info)
44{
45 return *std::static_pointer_cast<PolicyData>(info.userdata());
46}
47}
48
49FloatingWindowManagerPolicy::FloatingWindowManagerPolicy(
50 WindowManagerTools const& tools,
51 SpinnerSplash const& spinner,
52 miral::InternalClientLauncher const& launcher,
53 std::function<void()>& shutdown_hook) :
54 CanonicalWindowManagerPolicy(tools),
55 spinner{spinner},
56 decoration_provider{std::make_unique<DecorationProvider>(tools)}
57{
58 launcher.launch("decorations", *decoration_provider);
59 shutdown_hook = [this] { decoration_provider->stop(); };
60
61 for (auto key : {KEY_F1, KEY_F2, KEY_F3, KEY_F4})
62 key_to_workspace[key] = this->tools.create_workspace();
63
64 active_workspace = key_to_workspace[KEY_F1];
65}
66
67FloatingWindowManagerPolicy::~FloatingWindowManagerPolicy() = default;
68
69bool FloatingWindowManagerPolicy::handle_pointer_event(MirPointerEvent const* event)
70{
71 auto const action = mir_pointer_event_action(event);
72 auto const modifiers = mir_pointer_event_modifiers(event) & modifier_mask;
73 Point const cursor{
74 mir_pointer_event_axis_value(event, mir_pointer_axis_x),
75 mir_pointer_event_axis_value(event, mir_pointer_axis_y)};
76
77 bool consumes_event = false;
78 bool is_resize_event = false;
79
80 if (action == mir_pointer_action_button_down)
81 {
82 if (auto const window = tools.window_at(cursor))
83 tools.select_active_window(window);
84 }
85 else if (action == mir_pointer_action_motion &&
86 modifiers == mir_input_event_modifier_alt)
87 {
88 if (mir_pointer_event_button_state(event, mir_pointer_button_primary))
89 {
90 if (auto const target = tools.window_at(old_cursor))
91 {
92 if (tools.select_active_window(target) == target)
93 tools.drag_active_window(cursor - old_cursor);
94 }
95 consumes_event = true;
96 }
97
98 if (mir_pointer_event_button_state(event, mir_pointer_button_tertiary))
99 {
100 { // Workaround for lp:1627697
101 auto now = std::chrono::steady_clock::now();
102 if (resizing && now < last_resize+std::chrono::milliseconds(20))
103 return true;
104
105 last_resize = now;
106 }
107
108 if (!resizing)
109 tools.select_active_window(tools.window_at(old_cursor));
110 is_resize_event = resize(tools.active_window(), cursor, old_cursor);
111 consumes_event = true;
112 }
113 }
114
115 if (!consumes_event && action == mir_pointer_action_motion && !modifiers)
116 {
117 if (mir_pointer_event_button_state(event, mir_pointer_button_primary))
118 {
119 if (auto const possible_titlebar = tools.window_at(old_cursor))
120 {
121 auto const& info = tools.info_for(possible_titlebar);
122 if (decoration_provider->is_titlebar(info))
123 {
124 if (tools.select_active_window(info.parent()) == info.parent())
125 tools.drag_active_window(cursor - old_cursor);
126 consumes_event = true;
127 }
128 }
129 }
130 }
131
132 if (resizing && !is_resize_event)
133 end_resize();
134
135 resizing = is_resize_event;
136 old_cursor = cursor;
137 return consumes_event;
138}
139
140void FloatingWindowManagerPolicy::end_resize()
141{
142 if (!resizing && !pinching)
143 return;
144
145 if (auto window = tools.active_window())
146 {
147 auto& window_info = tools.info_for(window);
148
149 auto new_size = window.size();
150 auto new_pos = window.top_left();
151 window_info.constrain_resize(new_pos, new_size);
152
153 WindowSpecification modifications;
154 modifications.top_left() = new_pos;
155 modifications.size() = new_size;
156 tools.modify_window(window_info, modifications);
157 }
158
159 resizing = false;
160 pinching = false;
161}
162
163bool FloatingWindowManagerPolicy::handle_touch_event(MirTouchEvent const* event)
164{
165 auto const count = mir_touch_event_point_count(event);
166
167 long total_x = 0;
168 long total_y = 0;
169
170 for (auto i = 0U; i != count; ++i)
171 {
172 total_x += mir_touch_event_axis_value(event, i, mir_touch_axis_x);
173 total_y += mir_touch_event_axis_value(event, i, mir_touch_axis_y);
174 }
175
176 Point cursor{total_x/count, total_y/count};
177
178 bool is_drag = true;
179 for (auto i = 0U; i != count; ++i)
180 {
181 switch (mir_touch_event_action(event, i))
182 {
183 case mir_touch_action_up:
184 return false;
185
186 case mir_touch_action_down:
187 is_drag = false;
188 continue;
189
190 default:
191 continue;
192 }
193 }
194
195 int touch_pinch_top = std::numeric_limits<int>::max();
196 int touch_pinch_left = std::numeric_limits<int>::max();
197 int touch_pinch_width = 0;
198 int touch_pinch_height = 0;
199
200 for (auto i = 0U; i != count; ++i)
201 {
202 for (auto j = 0U; j != i; ++j)
203 {
204 int dx = mir_touch_event_axis_value(event, i, mir_touch_axis_x) -
205 mir_touch_event_axis_value(event, j, mir_touch_axis_x);
206
207 int dy = mir_touch_event_axis_value(event, i, mir_touch_axis_y) -
208 mir_touch_event_axis_value(event, j, mir_touch_axis_y);
209
210 if (touch_pinch_width < dx)
211 touch_pinch_width = dx;
212
213 if (touch_pinch_height < dy)
214 touch_pinch_height = dy;
215 }
216
217 int const x = mir_touch_event_axis_value(event, i, mir_touch_axis_x);
218
219 int const y = mir_touch_event_axis_value(event, i, mir_touch_axis_y);
220
221 if (touch_pinch_top > y)
222 touch_pinch_top = y;
223
224 if (touch_pinch_left > x)
225 touch_pinch_left = x;
226 }
227
228 bool consumes_event = false;
229 if (is_drag)
230 {
231 if (count == 3)
232 {
233 if (auto window = tools.active_window())
234 {
235 auto const old_size = window.size();
236 auto const delta_width = DeltaX{touch_pinch_width - old_touch_pinch_width};
237 auto const delta_height = DeltaY{touch_pinch_height - old_touch_pinch_height};
238
239 auto new_width = std::max(old_size.width + delta_width, Width{5});
240 auto new_height = std::max(old_size.height + delta_height, Height{5});
241 Displacement movement{
242 DeltaX{touch_pinch_left - old_touch_pinch_left},
243 DeltaY{touch_pinch_top - old_touch_pinch_top}};
244
245 auto& window_info = tools.info_for(window);
246 keep_window_within_constraints(window_info, movement, new_width, new_height);
247
248 auto new_pos = window.top_left() + movement;
249 Size new_size{new_width, new_height};
250
251 { // Workaround for lp:1627697
252 auto now = std::chrono::steady_clock::now();
253 if (pinching && now < last_resize+std::chrono::milliseconds(20))
254 return true;
255
256 last_resize = now;
257 }
258
259 WindowSpecification modifications;
260 modifications.top_left() = new_pos;
261 modifications.size() = new_size;
262 tools.modify_window(window_info, modifications);
263 pinching = true;
264 }
265 consumes_event = true;
266 }
267 }
268 else
269 {
270 if (auto const& window = tools.window_at(cursor))
271 tools.select_active_window(window);
272 }
273
274 if (!consumes_event && pinching)
275 end_resize();
276
277 old_cursor = cursor;
278 old_touch_pinch_top = touch_pinch_top;
279 old_touch_pinch_left = touch_pinch_left;
280 old_touch_pinch_width = touch_pinch_width;
281 old_touch_pinch_height = touch_pinch_height;
282 return consumes_event;
283}
284
285void FloatingWindowManagerPolicy::advise_new_window(WindowInfo const& window_info)
286{
287 CanonicalWindowManagerPolicy::advise_new_window(window_info);
288
289 auto const parent = window_info.parent();
290
291 if (decoration_provider->is_titlebar(window_info))
292 {
293 decoration_provider->advise_new_titlebar(window_info);
294
295 if (tools.active_window() == parent)
296 decoration_provider->paint_titlebar_for(tools.info_for(parent), 0xFF);
297 else
298 decoration_provider->paint_titlebar_for(tools.info_for(parent), 0x3F);
299 }
300
301 if (!parent)
302 tools.add_tree_to_workspace(window_info.window(), active_workspace);
303 else
304 {
305 if (policy_data_for(tools.info_for(parent)).in_hidden_workspace)
306 apply_workspace_hidden_to(window_info.window());
307 }
308}
309
310void FloatingWindowManagerPolicy::handle_window_ready(WindowInfo& window_info)
311{
312 if (window_info.window().application() != spinner.session() && window_info.needs_titlebar(window_info.type()))
313 decoration_provider->create_titlebar_for(window_info.window());
314
315 CanonicalWindowManagerPolicy::handle_window_ready(window_info);
316 keep_spinner_on_top();
317}
318
319void FloatingWindowManagerPolicy::advise_focus_lost(WindowInfo const& info)
320{
321 CanonicalWindowManagerPolicy::advise_focus_lost(info);
322
323 decoration_provider->paint_titlebar_for(info, 0x3F);
324}
325
326void FloatingWindowManagerPolicy::advise_focus_gained(WindowInfo const& info)
327{
328 CanonicalWindowManagerPolicy::advise_focus_gained(info);
329
330 decoration_provider->paint_titlebar_for(info, 0xFF);
331 keep_spinner_on_top();
332}
333
334void FloatingWindowManagerPolicy::keep_spinner_on_top()
335{
336 // Frig to force the spinner to the top
337 if (auto const spinner_session = spinner.session())
338 {
339 auto const& spinner_info = tools.info_for(spinner_session);
340
341 for (auto const& window : spinner_info.windows())
342 tools.raise_tree(window);
343 }
344}
345
346void FloatingWindowManagerPolicy::advise_state_change(WindowInfo const& window_info, MirWindowState state)
347{
348 CanonicalWindowManagerPolicy::advise_state_change(window_info, state);
349
350 decoration_provider->advise_state_change(window_info, state);
351}
352
353void FloatingWindowManagerPolicy::advise_resize(WindowInfo const& window_info, Size const& new_size)
354{
355 CanonicalWindowManagerPolicy::advise_resize(window_info, new_size);
356
357 decoration_provider->resize_titlebar_for(window_info, new_size);
358}
359
360void FloatingWindowManagerPolicy::advise_delete_window(WindowInfo const& window_info)
361{
362 CanonicalWindowManagerPolicy::advise_delete_window(window_info);
363
364 decoration_provider->destroy_titlebar_for(window_info.window());
365}
366
367bool FloatingWindowManagerPolicy::handle_keyboard_event(MirKeyboardEvent const* event)
368{
369 auto const action = mir_keyboard_event_action(event);
370 auto const scan_code = mir_keyboard_event_scan_code(event);
371 auto const modifiers = mir_keyboard_event_modifiers(event) & modifier_mask;
372
373 // Switch workspaces
374 if (action == mir_keyboard_action_down &&
375 modifiers == (mir_input_event_modifier_alt | mir_input_event_modifier_meta))
376 {
377 auto const found = key_to_workspace.find(scan_code);
378
379 if (found != key_to_workspace.end())
380 {
381 switch_workspace_to(found->second);
382 return true;
383 }
384 }
385
386 // Switch workspace taking the active window
387 if (action == mir_keyboard_action_down &&
388 modifiers == (mir_input_event_modifier_ctrl | mir_input_event_modifier_meta))
389 {
390 auto const found = key_to_workspace.find(scan_code);
391
392 if (found != key_to_workspace.end())
393 {
394 switch_workspace_to(found->second, tools.active_window());
395 return true;
396 }
397 }
398
399 if (action != mir_keyboard_action_repeat)
400 end_resize();
401
402 if (action == mir_keyboard_action_down && scan_code == KEY_F11)
403 {
404 switch (modifiers)
405 {
406 case mir_input_event_modifier_alt:
407 toggle(mir_window_state_maximized);
408 return true;
409
410 case mir_input_event_modifier_shift:
411 toggle(mir_window_state_vertmaximized);
412 return true;
413
414 case mir_input_event_modifier_ctrl:
415 toggle(mir_window_state_horizmaximized);
416 return true;
417
418 case mir_input_event_modifier_meta:
419 toggle(mir_window_state_fullscreen);
420 return true;
421
422 default:
423 break;
424 }
425 }
426 else if (action == mir_keyboard_action_down && scan_code == KEY_F4)
427 {
428 switch (modifiers)
429 {
430 case mir_input_event_modifier_alt|mir_input_event_modifier_shift:
431 if (auto const& window = tools.active_window())
432 kill(window.application(), SIGTERM);
433 return true;
434
435 case mir_input_event_modifier_alt:
436 tools.ask_client_to_close(tools.active_window());;
437 return true;
438
439 default:
440 break;
441 }
442 }
443 else if (action == mir_keyboard_action_down &&
444 modifiers == mir_input_event_modifier_alt &&
445 scan_code == KEY_TAB)
446 {
447 tools.focus_next_application();
448
449 return true;
450 }
451 else if (action == mir_keyboard_action_down &&
452 modifiers == mir_input_event_modifier_alt &&
453 scan_code == KEY_GRAVE)
454 {
455 tools.focus_next_within_application();
456
457 return true;
458 }
459 else if (action == mir_keyboard_action_down &&
460 modifiers == (mir_input_event_modifier_alt | mir_input_event_modifier_shift) &&
461 scan_code == KEY_GRAVE)
462 {
463 tools.focus_prev_within_application();
464
465 return true;
466 }
467 else if (action == mir_keyboard_action_down &&
468 modifiers == (mir_input_event_modifier_ctrl|mir_input_event_modifier_meta))
469 {
470 if (auto active_window = tools.active_window())
471 {
472 auto active_output = tools.active_output();
473 auto& window_info = tools.info_for(active_window);
474 WindowSpecification modifications;
475
476 switch (scan_code)
477 {
478 case KEY_LEFT:
479 modifications.state() = mir_window_state_vertmaximized;
480 tools.place_and_size_for_state(modifications, window_info);
481 modifications.top_left() = active_output.top_left + title_bar_height;
482 break;
483
484 case KEY_RIGHT:
485 modifications.state() = mir_window_state_vertmaximized;
486 tools.place_and_size_for_state(modifications, window_info);
487 modifications.top_left() = active_output.top_right() -
488 as_displacement({active_window.size().width, 0}) + title_bar_height;
489 break;
490
491 case KEY_UP:
492 modifications.state() = mir_window_state_horizmaximized;
493 tools.place_and_size_for_state(modifications, window_info);
494
495 modifications.top_left() = active_output.top_left + title_bar_height;
496 break;
497
498 case KEY_DOWN:
499 modifications.state() = mir_window_state_horizmaximized;
500 tools.place_and_size_for_state(modifications, window_info);
501
502 modifications.top_left() = active_output.bottom_right() - as_displacement(
503 modifications.size().is_set() ? modifications.size().value() : active_window.size());
504 break;
505
506 default:
507 return false;
508 }
509
510 tools.modify_window(window_info, modifications);
511 return true;
512 }
513 }
514
515 return false;
516}
517
518void FloatingWindowManagerPolicy::toggle(MirWindowState state)
519{
520 if (auto const window = tools.active_window())
521 {
522 auto& info = tools.info_for(window);
523
524 WindowSpecification modifications;
525
526 modifications.state() = (info.state() == state) ? mir_window_state_restored : state;
527 tools.place_and_size_for_state(modifications, info);
528 tools.modify_window(info, modifications);
529 }
530}
531
532bool FloatingWindowManagerPolicy::resize(Window const& window, Point cursor, Point old_cursor)
533{
534 if (!window)
535 return false;
536
537 auto& window_info = tools.info_for(window);
538
539 auto const top_left = window.top_left();
540 Rectangle const old_pos{top_left, window.size()};
541
542 if (!resizing)
543 {
544 auto anchor = old_pos.bottom_right();
545
546 for (auto const& corner : {
547 old_pos.top_right(),
548 old_pos.bottom_left(),
549 top_left})
550 {
551 if ((old_cursor - anchor).length_squared() <
552 (old_cursor - corner).length_squared())
553 {
554 anchor = corner;
555 }
556 }
557
558 left_resize = anchor.x != top_left.x;
559 top_resize = anchor.y != top_left.y;
560 }
561
562 int const x_sign = left_resize? -1 : 1;
563 int const y_sign = top_resize? -1 : 1;
564
565 auto movement = cursor-old_cursor;
566
567 auto new_width = old_pos.size.width + x_sign * movement.dx;
568 auto new_height = old_pos.size.height + y_sign * movement.dy;
569
570 keep_window_within_constraints(window_info, movement, new_width, new_height);
571
572 Size new_size{new_width, new_height};
573 Point new_pos = top_left + left_resize*movement.dx + top_resize*movement.dy;
574
575 WindowSpecification modifications;
576 modifications.top_left() = new_pos;
577 modifications.size() = new_size;
578 tools.modify_window(window, modifications);
579
580 return true;
581}
582
583void FloatingWindowManagerPolicy::keep_window_within_constraints(
584 WindowInfo const& window_info, Displacement& movement, Width& new_width, Height& new_height) const
585{
586 switch (window_info.state())
587 {
588 case mir_window_state_maximized:
589 case mir_window_state_fullscreen:
590 new_width = window_info.window().size().width;
591 new_height = window_info.window().size().height;
592 movement = {0, 0};
593 break;
594
595 case mir_window_state_vertmaximized:
596 new_height = window_info.window().size().height;
597 movement.dy = DeltaY{0};
598 break;
599
600 case mir_window_state_horizmaximized:
601 new_width = window_info.window().size().width;
602 movement.dx - DeltaX{0};
603 break;
604
605 default:;
606 }
607
608 auto const min_width = std::max(window_info.min_width(), Width{5});
609 auto const min_height = std::max(window_info.min_height(), Height{5});
610
611 if (new_width < min_width)
612 {
613 new_width = min_width;
614 if (movement.dx > DeltaX{0})
615 movement.dx = DeltaX{0};
616 }
617
618 if (new_height < min_height)
619 {
620 new_height = min_height;
621 if (movement.dy > DeltaY{0})
622 movement.dy = DeltaY{0};
623 }
624
625 auto const max_width = window_info.max_width();
626 auto const max_height = window_info.max_height();
627
628 if (new_width > max_width)
629 {
630 new_width = max_width;
631 if (movement.dx < DeltaX{0})
632 movement.dx = DeltaX{0};
633 }
634
635 if (new_height > max_height)
636 {
637 new_height = max_height;
638 if (movement.dy < DeltaY{0})
639 movement.dy = DeltaY{0};
640 }
641}
642
643WindowSpecification FloatingWindowManagerPolicy::place_new_window(
644 ApplicationInfo const& app_info, WindowSpecification const& request_parameters)
645{
646 auto parameters = CanonicalWindowManagerPolicy::place_new_window(app_info, request_parameters);
647
648 bool const needs_titlebar = WindowInfo::needs_titlebar(parameters.type().value());
649
650 if (parameters.state().value() != mir_window_state_fullscreen && needs_titlebar)
651 parameters.top_left() = Point{parameters.top_left().value().x, parameters.top_left().value().y + title_bar_height};
652
653 if (app_info.application() == decoration_provider->session())
654 decoration_provider->place_new_decoration(parameters);
655
656 parameters.userdata() = std::make_shared<PolicyData>();
657 return parameters;
658}
659
660void FloatingWindowManagerPolicy::advise_adding_to_workspace(
661 std::shared_ptr<Workspace> const& workspace, std::vector<Window> const& windows)
662{
663 if (windows.empty())
664 return;
665
666 for (auto const& window : windows)
667 {
668 if (workspace == active_workspace)
669 {
670 apply_workspace_visible_to(window);
671 }
672 else
673 {
674 apply_workspace_hidden_to(window);
675 }
676 }
677}
678
679auto FloatingWindowManagerPolicy::confirm_placement_on_display(
680 miral::WindowInfo const& /*window_info*/, MirWindowState new_state, Rectangle const& new_placement) -> Rectangle
681{
682 switch (new_state)
683 {
684 default:
685 return new_placement;
686
687 case mir_window_state_maximized:
688 case mir_window_state_vertmaximized:
689 auto result = new_placement;
690
691 result.top_left.y = result.top_left.y + title_bar_height;
692 result.size.height = result.size.height - title_bar_height;
693 return result;
694 }
695}
696
697void FloatingWindowManagerPolicy::switch_workspace_to(
698 std::shared_ptr<Workspace> const& workspace,
699 Window const& window)
700{
701 if (workspace == active_workspace)
702 return;
703
704 auto const old_active = active_workspace;
705 active_workspace = workspace;
706
707 auto const old_active_window = tools.active_window();
708
709 if (!old_active_window)
710 {
711 // If there's no active window, the first shown grabs focus: get the right one
712 if (auto const ww = workspace_to_active[workspace])
713 {
714 tools.for_each_workspace_containing(ww, [&](std::shared_ptr<miral::Workspace> const& ws)
715 {
716 if (ws == workspace)
717 {
718 apply_workspace_visible_to(ww);
719 }
720 });
721 }
722 }
723
724 tools.remove_tree_from_workspace(window, old_active);
725 tools.add_tree_to_workspace(window, active_workspace);
726
727 tools.for_each_window_in_workspace(active_workspace, [&](Window const& window)
728 {
729 if (decoration_provider->is_decoration(window))
730 return; // decorations are taken care of automatically
731
732 apply_workspace_visible_to(window);
733 });
734
735 bool hide_old_active = false;
736 tools.for_each_window_in_workspace(old_active, [&](Window const& window)
737 {
738 if (decoration_provider->is_decoration(window))
739 return; // decorations are taken care of automatically
740
741 if (window == old_active_window)
742 {
743 // If we hide the active window focus will shift: do that last
744 hide_old_active = true;
745 return;
746 }
747
748 apply_workspace_hidden_to(window);
749 });
750
751 if (hide_old_active)
752 {
753 apply_workspace_hidden_to(old_active_window);
754
755 // Remember the old active_window when we switch away
756 workspace_to_active[old_active] = old_active_window;
757 }
758}
759
760void FloatingWindowManagerPolicy::apply_workspace_hidden_to(Window const& window)
761{
762 auto const& window_info = tools.info_for(window);
763 auto& pdata = policy_data_for(window_info);
764 if (!pdata.in_hidden_workspace)
765 {
766 pdata.in_hidden_workspace = true;
767 pdata.old_state = window_info.state();
768
769 WindowSpecification modifications;
770 modifications.state() = mir_window_state_hidden;
771 tools.place_and_size_for_state(modifications, window_info);
772 tools.modify_window(window_info.window(), modifications);
773 }
774}
775
776void FloatingWindowManagerPolicy::apply_workspace_visible_to(Window const& window)
777{
778 auto const& window_info = tools.info_for(window);
779 auto& pdata = policy_data_for(window_info);
780 if (pdata.in_hidden_workspace)
781 {
782 pdata.in_hidden_workspace = false;
783 WindowSpecification modifications;
784 modifications.state() = pdata.old_state;
785 tools.place_and_size_for_state(modifications, window_info);
786 tools.modify_window(window_info.window(), modifications);
787 }
788}
789
790void FloatingWindowManagerPolicy::handle_modify_window(WindowInfo& window_info, WindowSpecification const& modifications)
791{
792 auto mods = modifications;
793
794 auto& pdata = policy_data_for(window_info);
795
796 if (pdata.in_hidden_workspace && mods.state().is_set())
797 pdata.old_state = mods.state().consume();
798
799 CanonicalWindowManagerPolicy::handle_modify_window(window_info, mods);
800}
801
0802
=== added file 'examples/miral-shell/floating_window_manager.h'
--- examples/miral-shell/floating_window_manager.h 1970-01-01 00:00:00 +0000
+++ examples/miral-shell/floating_window_manager.h 2017-08-29 09:17:20 +0000
@@ -0,0 +1,146 @@
1/*
2 * Copyright © 2016-2017 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 or 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty ofb
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Alan Griffiths <alan@octopull.co.uk>
17 */
18
19#ifndef MIRAL_SHELL_FLOATING_WINDOW_MANAGER_H
20#define MIRAL_SHELL_FLOATING_WINDOW_MANAGER_H
21
22#include <miral/canonical_window_manager.h>
23#include <miral/window_management_policy_addendum3.h>
24#include <miral/workspace_policy.h>
25
26
27#include "spinner/splash.h"
28
29#include <chrono>
30#include <map>
31
32namespace miral { class InternalClientLauncher; }
33
34using namespace mir::geometry;
35
36class DecorationProvider;
37
38class FloatingWindowManagerPolicy : public miral::CanonicalWindowManagerPolicy,
39 public miral::WorkspacePolicy, public miral::WindowManagementPolicyAddendum3
40{
41public:
42 FloatingWindowManagerPolicy(
43 miral::WindowManagerTools const& tools,
44 SpinnerSplash const& spinner,
45 miral::InternalClientLauncher const& launcher,
46 std::function<void()>& shutdown_hook);
47 ~FloatingWindowManagerPolicy();
48
49 virtual miral::WindowSpecification place_new_window(
50 miral::ApplicationInfo const& app_info, miral::WindowSpecification const& request_parameters) override;
51
52 /** @name example event handling:
53 * o Switch apps: Alt+Tab, tap or click on the corresponding window
54 * o Switch window: Alt+`, tap or click on the corresponding window
55 * o Move window: Alt-leftmousebutton drag (three finger drag)
56 * o Resize window: Alt-middle_button drag (three finger pinch)
57 * o Maximize/restore current window (to display size): Alt-F11
58 * o Maximize/restore current window (to display height): Shift-F11
59 * o Maximize/restore current window (to display width): Ctrl-F11
60 * o Switch workspace . . . . . . . . . . : Meta-Alt-[F1|F2|F3|F4]
61 * o Switch workspace taking active window: Meta-Ctrl-[F1|F2|F3|F4]
62 * @{ */
63 bool handle_pointer_event(MirPointerEvent const* event) override;
64 bool handle_touch_event(MirTouchEvent const* event) override;
65 bool handle_keyboard_event(MirKeyboardEvent const* event) override;
66 /** @} */
67
68 /** @name track events that affect titlebar
69 * @{ */
70 void advise_new_window(miral::WindowInfo const& window_info) override;
71 void handle_window_ready(miral::WindowInfo& window_info) override;
72 void advise_focus_lost(miral::WindowInfo const& info) override;
73 void advise_focus_gained(miral::WindowInfo const& info) override;
74 void advise_state_change(miral::WindowInfo const& window_info, MirWindowState state) override;
75 void advise_resize(miral::WindowInfo const& window_info, Size const& new_size) override;
76 void advise_delete_window(miral::WindowInfo const& window_info) override;
77
78 void handle_modify_window(miral::WindowInfo& window_info, miral::WindowSpecification const& modifications) override;
79 /** @} */
80
81protected:
82 static const int modifier_mask =
83 mir_input_event_modifier_alt |
84 mir_input_event_modifier_shift |
85 mir_input_event_modifier_sym |
86 mir_input_event_modifier_ctrl |
87 mir_input_event_modifier_meta;
88
89private:
90 void toggle(MirWindowState state);
91
92 bool resize(miral::Window const& window, Point cursor, Point old_cursor);
93
94 Point old_cursor{};
95
96 bool resizing = false;
97 bool left_resize = false;
98 bool top_resize = false;
99
100 int old_touch_pinch_top = 0;
101 int old_touch_pinch_left = 0;
102 int old_touch_pinch_width = 0;
103 int old_touch_pinch_height = 0;
104 bool pinching = false;
105
106 SpinnerSplash const spinner;
107
108 std::unique_ptr<DecorationProvider> const decoration_provider;
109
110 void end_resize();
111
112 void keep_window_within_constraints(
113 miral::WindowInfo const& window_info,
114 Displacement& movement,
115 Width& new_width,
116 Height& new_height) const;
117
118 // Workaround for lp:1627697
119 std::chrono::steady_clock::time_point last_resize;
120
121 void advise_adding_to_workspace(
122 std::shared_ptr<miral::Workspace> const& workspace,
123 std::vector<miral::Window> const& windows) override;
124
125 auto confirm_placement_on_display(
126 miral::WindowInfo const& window_info,
127 MirWindowState new_state,
128 Rectangle const& new_placement) -> Rectangle override;
129
130 // Switch workspace, taking window (if not null)
131 void switch_workspace_to(
132 std::shared_ptr<miral::Workspace> const& workspace,
133 miral::Window const& window = miral::Window{});
134
135 std::shared_ptr<miral::Workspace> active_workspace;
136 std::map<int, std::shared_ptr<miral::Workspace>> key_to_workspace;
137 std::map<std::shared_ptr<miral::Workspace>, miral::Window> workspace_to_active;
138
139 void apply_workspace_visible_to(miral::Window const& window);
140
141 void apply_workspace_hidden_to(miral::Window const& window);
142
143 void keep_spinner_on_top();
144};
145
146#endif //MIRAL_SHELL_FLOATING_WINDOW_MANAGER_H
0147
=== added file 'examples/miral-shell/miral-app.sh'
--- examples/miral-shell/miral-app.sh 1970-01-01 00:00:00 +0000
+++ examples/miral-shell/miral-app.sh 2017-08-29 09:17:20 +0000
@@ -0,0 +1,51 @@
1#! /bin/bash
2
3miral_server=miral-shell
4launcher='gnome-terminal --app-id com.canonical.miral.Terminal'
5hostsocket=
6bindir=$(dirname $0)
7
8if [ -n "${MIR_SOCKET}" ]
9then
10 if [ ! -e "${MIR_SOCKET}" ]
11 then
12 echo "Error: Host endpoint '${MIR_SOCKET}' does not exists"; exit 1
13 fi
14 hostsocket='--host-socket ${MIR_SOCKET}'
15fi
16
17socket=${XDG_RUNTIME_DIR}/miral_socket
18
19while [ $# -gt 0 ]
20do
21 if [ "$1" == "--help" -o "$1" == "-h" ]
22 then
23 echo "$(basename $0) - Handy launch script for a hosted miral \"desktop session\""
24 echo "Usage: $(basename $0) [options] [shell options]"
25 echo "Options are:"
26 echo " -kiosk use miral-kiosk instead of ${miral_server}"
27 echo " -launcher <launcher> use <launcher> instead of '${launcher}'"
28 echo " -socket <socket> set the mir socket [${socket}]"
29 echo " -bindir <bindir> path to the miral executable [${bindir}]"
30 exit 0
31 elif [ "$1" == "-kiosk" ]; then miral_server=miral-kiosk
32 elif [ "$1" == "-launcher" ]; then shift; launcher=$1
33 elif [ "$1" == "-socket" ]; then shift; socket=$1
34 elif [ "$1" == "-bindir" ]; then shift; bindir=$1
35 elif [ "${1:0:2}" == "--" ]; then break
36 fi
37 shift
38done
39
40if [ "${bindir}" != "" ]; then bindir="${bindir}/"; fi
41
42if [ -e "${socket}" ]; then echo "Error: session endpoint '${socket}' already exists"; exit 1 ;fi
43
44sh -c "${bindir}${miral_server} $* ${hostsocket} --file ${socket} --desktop_file_hint=miral-shell.desktop"&
45
46while [ ! -e "${socket}" ]; do echo "waiting for ${socket}"; sleep 1 ;done
47
48unset QT_QPA_PLATFORMTHEME
49MIR_SOCKET=${socket} XDG_SESSION_TYPE=mir GDK_BACKEND=mir QT_QPA_PLATFORM=ubuntumirclient SDL_VIDEODRIVER=mir dbus-run-session -- ${launcher}
50killall ${bindir}${miral_server}
51
052
=== added file 'examples/miral-shell/miral-desktop.sh'
--- examples/miral-shell/miral-desktop.sh 1970-01-01 00:00:00 +0000
+++ examples/miral-shell/miral-desktop.sh 2017-08-29 09:17:20 +0000
@@ -0,0 +1,45 @@
1#! /bin/bash
2
3socket=${XDG_RUNTIME_DIR}/miral_socket
4miral_server=miral-shell
5launcher='gnome-terminal --app-id com.canonical.miral.Terminal'
6bindir=$(dirname $0)
7vt=4
8
9while [ $# -gt 0 ]
10do
11 if [ "$1" == "--help" -o "$1" == "-h" ]
12 then
13 echo "$(basename $0) - Handy launch script for a miral \"desktop session\""
14 echo "Usage: $(basename $0) [options] [shell options]"
15 echo "Options are:"
16 echo " -kiosk use miral-kiosk instead of ${miral_server}"
17 echo " -launcher <launcher> use <launcher> instead of '${launcher}'"
18 echo " -vt <termid> set the virtual terminal [${vt}]"
19 echo " -socket <socket> set the mir socket [${socket}]"
20 echo " -bindir <bindir> path to the miral executable [${bindir}]"
21 exit 0
22 elif [ "$1" == "-kiosk" ]; then miral_server=miral-kiosk
23 elif [ "$1" == "-launcher" ]; then shift; launcher=$1
24 elif [ "$1" == "-vt" ]; then shift; vt=$1
25 elif [ "$1" == "-socket" ]; then shift; socket=$1
26 elif [ "$1" == "-bindir" ]; then shift; bindir=$1/
27 elif [ "${1:0:2}" == "--" ]; then break
28 fi
29 shift
30done
31
32if [ "${bindir}" != "" ]; then bindir="${bindir}/"; fi
33
34if [ -e "${socket}" ]; then echo "Error: '${socket}' already exists"; exit 1 ;fi
35
36sudo ls >> /dev/null
37oldvt=$(sudo fgconsole)
38sudo sh -c "LD_LIBRARY_PATH=${LD_LIBRARY_PATH} ${bindir}${miral_server} --vt ${vt} --arw-file --file ${socket} $*; chvt ${oldvt}"&
39
40while [ ! -e "${socket}" ]; do echo "waiting for ${socket}"; sleep 1 ;done
41
42unset QT_QPA_PLATFORMTHEME
43MIR_SOCKET=${socket} XDG_SESSION_TYPE=mir GDK_BACKEND=mir QT_QPA_PLATFORM=ubuntumirclient SDL_VIDEODRIVER=mir dbus-run-session -- ${launcher}
44sudo killall ${bindir}${miral_server}
45
046
=== added file 'examples/miral-shell/miral-run.sh'
--- examples/miral-shell/miral-run.sh 1970-01-01 00:00:00 +0000
+++ examples/miral-shell/miral-run.sh 2017-08-29 09:17:20 +0000
@@ -0,0 +1,17 @@
1#!/bin/sh
2
3if [ -e "${XDG_RUNTIME_DIR}/miral_socket" ];
4then
5 socket=${XDG_RUNTIME_DIR}/miral_socket
6elif [ -e "${XDG_RUNTIME_DIR}/mir_socket" ];
7then
8 socket=${XDG_RUNTIME_DIR}/mir_socket
9else
10 echo "Error: Cannot detect Mir endpoint"; exit 1
11fi
12
13if [ "$1" = "gnome-terminal" ]
14then extras='--app-id com.canonical.miral.Terminal'
15fi
16unset QT_QPA_PLATFORMTHEME
17MIR_SOCKET=${socket} XDG_SESSION_TYPE=mir GDK_BACKEND=mir QT_QPA_PLATFORM=ubuntumirclient SDL_VIDEODRIVER=mir "$@" ${extras}&
018
=== added file 'examples/miral-shell/miral-screencast.sh'
--- examples/miral-shell/miral-screencast.sh 1970-01-01 00:00:00 +0000
+++ examples/miral-shell/miral-screencast.sh 2017-08-29 09:17:20 +0000
@@ -0,0 +1,48 @@
1#!/bin/bash
2width=1920
3height=1080
4output=screencast.mp4
5socket=${XDG_RUNTIME_DIR}/miral_socket
6if [ -v MIR_SERVER ]; then socket=${MIR_SERVER}; fi
7
8while [ $# -gt 0 ]
9do
10 if [ "$1" == "--help" -o "$1" == "-h" ]
11 then
12 echo "$(basename $0) - screencast capture script for use with Mir servers"
13 echo "Usage: $0 [options]"
14 echo "Options are:"
15 echo " --width set the capture width [${width}]"
16 echo " --height set the capture height [${height}]"
17 echo " --output set the output filename [${output}]"
18 echo " --socket set the mir socket [${socket}]"
19 echo " --tmpfile specify the temporary work file"
20 exit 0
21 elif [ "$1" == "--socket" ]; then shift; socket=$1
22 elif [ "$1" == "--output" ]; then shift; output=$1
23 elif [ "$1" == "--width" ]; then shift; width=$1
24 elif [ "$1" == "--height" ]; then shift; height=$1
25 elif [ "$1" == "--tmpfile" ]; then shift; tempfile=$1
26 fi
27 shift
28done
29
30echo width = ${width}
31echo height = ${height}
32echo output = ${output}
33echo socket = ${socket}
34
35if ! which mirscreencast >> /dev/null ; then echo "Need mirscreencast - run \"sudo apt install mir-utils\""; exit 1 ;fi
36if ! which mencoder >> /dev/null ; then echo "Need mencoder - run \"sudo apt install mencoder\""; exit 1 ;fi
37
38if [ -e ${output} ]; then echo "Output exists, moving to ${output}~"; mv ${output} ${output}~ ;fi
39while [ ! -e "${socket}" ]; do echo "waiting for ${socket}"; sleep 1 ;done
40
41if [ ! -v tempfile ]; then tempfile=$(mktemp); fi
42mirscreencast --size ${width} ${height} -m ${socket} -f ${tempfile}& mirscreencast_pid=$!
43trap 'kill ${mirscreencast_pid}; rm -f -- "${tempfile}"; exit 0' INT TERM HUP EXIT
44
45sleep 1; # don't lose the next message in the spew from mirscreencast
46read -rsp $'\n\nPress enter when recording complete...'
47
48mencoder -demuxer rawvideo -rawvideo fps=60:w=${width}:h=${height}:format=bgra -ovc x264 -o ${output} ${tempfile}
049
=== added file 'examples/miral-shell/miral-xrun.sh'
--- examples/miral-shell/miral-xrun.sh 1970-01-01 00:00:00 +0000
+++ examples/miral-shell/miral-xrun.sh 2017-08-29 09:17:20 +0000
@@ -0,0 +1,45 @@
1#!/bin/bash
2port=0
3
4while [ -e "/tmp/.X11-unix/X${port}" ]; do
5 let port+=1
6done
7
8unset QT_QPA_PLATFORMTHEME
9unset GDK_BACKEND
10unset QT_QPA_PLATFORM
11unset SDL_VIDEODRIVER
12
13if [ -e "${XDG_RUNTIME_DIR}/miral_socket" ];
14then
15 socket=${XDG_RUNTIME_DIR}/miral_socket
16elif [ -e "${XDG_RUNTIME_DIR}/mir_socket" ];
17then
18 socket=${XDG_RUNTIME_DIR}/mir_socket
19else
20 echo "Error: Cannot detect Mir endpoint"; exit 1
21fi
22
23while [ $# -gt 0 ]
24do
25 if [ "$1" == "--help" -o "$1" == "-h" ]
26 then
27 echo "$(basename $0) - Handy launch script for providing an Xmir X11 server"
28 echo "Usage: $(basename $0) [options] command"
29 echo "Options are:"
30 echo " -force set toolkit environment variables to force X11 use"
31 exit 0
32 elif [ "$1" == "-force" ];
33 then
34 export XDG_SESSION_TYPE=x11
35 export GDK_BACKEND=x11
36 export QT_QPA_PLATFORM=xcb
37 export SDL_VIDEODRIVER=x11
38 else break
39 fi
40 shift
41done
42
43MIR_SOCKET=${socket} Xmir -rootless :${port} & pid=$!
44DISPLAY=:${port} "$@"
45kill ${pid}
046
=== added file 'examples/miral-shell/shell_main.cpp'
--- examples/miral-shell/shell_main.cpp 1970-01-01 00:00:00 +0000
+++ examples/miral-shell/shell_main.cpp 2017-08-29 09:17:20 +0000
@@ -0,0 +1,98 @@
1/*
2 * Copyright © 2016-2017 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * under the terms of the GNU General Public License version 2 or 3 as as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Alan Griffiths <alan@octopull.co.uk>
17 */
18
19#include "tiling_window_manager.h"
20#include "floating_window_manager.h"
21#include "titlebar_config.h"
22#include "spinner/splash.h"
23
24#include <miral/display_configuration_option.h>
25#include <miral/runner.h>
26#include <miral/window_management_options.h>
27#include <miral/append_event_filter.h>
28#include <miral/debug_extension.h>
29#include <miral/internal_client.h>
30#include <miral/command_line_option.h>
31#include <miral/cursor_theme.h>
32#include <miral/keymap.h>
33
34#include <linux/input.h>
35
36int main(int argc, char const* argv[])
37{
38 using namespace miral;
39
40 std::function<void()> shutdown_hook{[]{}};
41
42 SpinnerSplash spinner;
43 InternalClientLauncher launcher;
44 ActiveOutputsMonitor outputs_monitor;
45 WindowManagerOptions window_managers
46 {
47 add_window_manager_policy<FloatingWindowManagerPolicy>("floating", spinner, launcher, shutdown_hook),
48 add_window_manager_policy<TilingWindowManagerPolicy>("tiling", spinner, launcher, outputs_monitor),
49 };
50
51 MirRunner runner{argc, argv};
52
53 runner.add_stop_callback([&] { shutdown_hook(); });
54
55 auto const quit_on_ctrl_alt_bksp = [&](MirEvent const* event)
56 {
57 if (mir_event_get_type(event) != mir_event_type_input)
58 return false;
59
60 MirInputEvent const* input_event = mir_event_get_input_event(event);
61 if (mir_input_event_get_type(input_event) != mir_input_event_type_key)
62 return false;
63
64 MirKeyboardEvent const* kev = mir_input_event_get_keyboard_event(input_event);
65 if (mir_keyboard_event_action(kev) != mir_keyboard_action_down)
66 return false;
67
68 MirInputEventModifiers mods = mir_keyboard_event_modifiers(kev);
69 if (!(mods & mir_input_event_modifier_alt) || !(mods & mir_input_event_modifier_ctrl))
70 return false;
71
72 if (mir_keyboard_event_scan_code(kev) != KEY_BACKSPACE)
73 return false;
74
75 runner.stop();
76 return true;
77 };
78
79 Keymap config_keymap;
80 DebugExtension debug_extensions;
81
82 return runner.run_with(
83 {
84 CommandLineOption{[&](std::string const& ) { },
85 "desktop_file_hint", "Ignored for Unity8 compatibility", "miral-shell.desktop"},
86 CursorTheme{"DMZ-White"},
87 window_managers,
88 display_configuration_options,
89 launcher,
90 outputs_monitor,
91 config_keymap,
92 debug_extensions,
93 AppendEventFilter{quit_on_ctrl_alt_bksp},
94 StartupInternalClient{"Intro", spinner},
95 pre_init(CommandLineOption{[&](std::string const& typeface) { ::titlebar::font_file(typeface); },
96 "shell-titlebar-font", "font file to use for titlebars", ::titlebar::font_file()})
97 });
98}
099
=== added directory 'examples/miral-shell/spinner'
=== added file 'examples/miral-shell/spinner/CMakeLists.txt'
--- examples/miral-shell/spinner/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ examples/miral-shell/spinner/CMakeLists.txt 2017-08-29 09:17:20 +0000
@@ -0,0 +1,67 @@
1# -*- Mode: CMake; indent-tabs-mode: nil; tab-width: 2 -*-
2#
3# Copyright © 2014 Canonical Ltd.
4#
5# This program is free software: you can redistribute it and/or modify
6# it under the terms of the GNU General Public License version 3 as
7# published by the Free Software Foundation.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17pkg_check_modules(GLIB REQUIRED glib-2.0)
18find_package(GLESv2 REQUIRED)
19find_package(PIL REQUIRED)
20
21set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-overlength-strings")
22
23
24function(png2header png header varname)
25 add_custom_command(
26 OUTPUT ${header}
27 COMMAND python3 ${CMAKE_CURRENT_SOURCE_DIR}/png2header.py ${png} ${varname} > ${header}
28 DEPENDS ${png} ${CMAKE_CURRENT_SOURCE_DIR}/png2header.py
29 )
30endfunction()
31
32png2header(
33 ${CMAKE_CURRENT_SOURCE_DIR}/spinner-glow.png
34 ${CMAKE_CURRENT_BINARY_DIR}/spinner_glow.h
35 spinner_glow
36)
37
38png2header(
39 ${CMAKE_CURRENT_SOURCE_DIR}/spinner-logo.png
40 ${CMAKE_CURRENT_BINARY_DIR}/spinner_logo.h
41 spinner_logo
42)
43
44include_directories(
45 ${GLIB_INCLUDE_DIRS}
46 ${GLESv2_INCLUDE_DIRS}
47 ${CMAKE_CURRENT_BINARY_DIR}
48)
49
50add_library(miral-spinner STATIC
51 eglapp.cpp
52 eglapp.h
53 eglspinner.cpp
54 miregl.h
55 miregl.cpp
56 splash.h
57 ${CMAKE_CURRENT_BINARY_DIR}/spinner_logo.h
58 ${CMAKE_CURRENT_BINARY_DIR}/spinner_glow.h
59)
60
61target_link_libraries(miral-spinner
62 mirclientcpp
63 EGL
64 ${GLIB_LDFLAGS}
65 ${GLESv2_LIBRARIES}
66 ${MIRCLIENT_LDFLAGS}
67)
068
=== added file 'examples/miral-shell/spinner/eglapp.cpp'
--- examples/miral-shell/spinner/eglapp.cpp 1970-01-01 00:00:00 +0000
+++ examples/miral-shell/spinner/eglapp.cpp 2017-08-29 09:17:20 +0000
@@ -0,0 +1,83 @@
1/*
2 * Copyright © 2013, 2015 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * under the terms of the GNU General Public License version 2 or 3 as as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include "eglapp.h"
18
19#include <mir/client/display_config.h>
20
21#include "miregl.h"
22
23
24float mir_eglapp_background_opacity = 1.0f;
25
26
27namespace
28{
29MirPixelFormat select_pixel_format(MirConnection* connection)
30{
31 unsigned int format[mir_pixel_formats];
32 unsigned int nformats;
33
34 mir_connection_get_available_surface_formats(
35 connection,
36 (MirPixelFormat*) format,
37 mir_pixel_formats,
38 &nformats);
39
40 auto const pixel_format = (MirPixelFormat) format[0];
41
42 printf("Server supports %d of %d surface pixel formats. Using format: %d\n",
43 nformats, mir_pixel_formats, pixel_format);
44
45 return pixel_format;
46}
47}
48
49std::vector<std::shared_ptr<MirEglSurface>> mir_eglapp_init(MirConnection* const connection)
50{
51 char const * const name = "eglappsurface";
52
53 if (!mir_connection_is_valid(connection))
54 throw std::runtime_error("Can't get connection");
55
56 auto const pixel_format = select_pixel_format(connection);
57
58 auto const mir_egl_app = make_mir_eglapp(connection, pixel_format);
59
60 std::vector<std::shared_ptr<MirEglSurface>> result;
61
62 mir::client::DisplayConfig{connection}.for_each_output([&](MirOutput const* output)
63 {
64 if (mir_output_get_connection_state(output) == mir_output_connection_state_connected &&
65 mir_output_is_enabled(output))
66 {
67 auto const mode = mir_output_get_current_mode(output);
68 auto const output_id = mir_output_get_id(output);
69
70 printf("Active output [%u] at (%d, %d) is %dx%d\n",
71 output_id,
72 mir_output_get_position_x(output), mir_output_get_position_y(output),
73 mir_output_mode_get_width(mode), mir_output_mode_get_height(mode));
74
75 result.push_back(std::make_shared<MirEglSurface>(mir_egl_app, name, output));
76 }
77 });
78
79 if (result.empty())
80 throw std::runtime_error("No active outputs found.");
81
82 return result;
83}
084
=== added file 'examples/miral-shell/spinner/eglapp.h'
--- examples/miral-shell/spinner/eglapp.h 1970-01-01 00:00:00 +0000
+++ examples/miral-shell/spinner/eglapp.h 2017-08-29 09:17:20 +0000
@@ -0,0 +1,33 @@
1/*
2 * Copyright © 2013 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * under the terms of the GNU General Public License version 2 or 3 as as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Author: Daniel van Vugt <daniel.van.vugt@canonical.com>
17 */
18
19#ifndef __EGLAPP_H__
20#define __EGLAPP_H__
21
22#include <mir_toolkit/client_types.h>
23
24#include <memory>
25#include <vector>
26
27class MirEglSurface;
28
29extern float mir_eglapp_background_opacity;
30
31std::vector<std::shared_ptr<MirEglSurface>> mir_eglapp_init(MirConnection* const connection);
32
33#endif
034
=== added file 'examples/miral-shell/spinner/eglspinner.cpp'
--- examples/miral-shell/spinner/eglspinner.cpp 1970-01-01 00:00:00 +0000
+++ examples/miral-shell/spinner/eglspinner.cpp 2017-08-29 09:17:20 +0000
@@ -0,0 +1,372 @@
1/*
2 * Copyright © 2013-2015 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * under the terms of the GNU General Public License version 2 or 3 as as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authors: Daniel van Vugt <daniel.van.vugt@canonical.com>
17 * Mirco Müller <mirco.mueller@canonical.com>
18 * Alan Griffiths <alan@octopull.co.uk>
19 * Kevin DuBois <kevin.dubois@canonical.com>
20 */
21
22#include "splash.h"
23
24#include <chrono>
25
26#include "eglapp.h"
27#include "miregl.h"
28#include <assert.h>
29#include <glib.h>
30#include <string.h>
31#include <GLES2/gl2.h>
32#include <sys/stat.h>
33#include <signal.h>
34#include <atomic>
35#include <mutex>
36
37#include <mir_toolkit/mir_client_library.h>
38
39#include "spinner_glow.h"
40#include "spinner_logo.h"
41
42static GLuint load_shader(const char *src, GLenum type)
43{
44 GLuint shader = glCreateShader(type);
45 if (shader)
46 {
47 GLint compiled;
48 glShaderSource(shader, 1, &src, NULL);
49 glCompileShader(shader);
50 glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
51 if (!compiled)
52 {
53 GLchar log[1024];
54 glGetShaderInfoLog(shader, sizeof log - 1, NULL, log);
55 log[sizeof log - 1] = '\0';
56 printf("load_shader compile failed: %s\n", log);
57 glDeleteShader(shader);
58 shader = 0;
59 }
60 }
61 return shader;
62}
63
64// Colours from http://design.ubuntu.com/brand/colour-palette
65//#define MID_AUBERGINE 0.368627451f, 0.152941176f, 0.31372549f
66//#define ORANGE 0.866666667f, 0.282352941f, 0.141414141f
67//#define WARM_GREY 0.682352941f, 0.654901961f, 0.623529412f
68//#define COOL_GREY 0.2f, 0.2f, 0.2f
69#define LIGHT_AUBERGINE 0.466666667f, 0.297297297f, 0.435294118f
70//#define DARK_AUBERGINE 0.17254902f, 0.0f, 0.117647059f
71//#define BLACK 0.0f, 0.0f, 0.0f
72//#define WHITE 1.0f, 1.0f, 1.0f
73
74template <typename Image>
75void uploadTexture (GLuint id, Image& image)
76{
77 glBindTexture(GL_TEXTURE_2D, id);
78
79 glTexImage2D(GL_TEXTURE_2D,
80 0,
81 GL_RGBA,
82 image.width,
83 image.height,
84 0,
85 GL_RGBA,
86 GL_UNSIGNED_BYTE,
87 image.pixel_data);
88 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
89 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
90 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
91 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
92 glBindTexture(GL_TEXTURE_2D, 0);
93}
94
95GLuint createShaderProgram(const char* vertexShaderSrc, const char* fragmentShaderSrc)
96{
97 if (!vertexShaderSrc || !fragmentShaderSrc)
98 return 0;
99
100 GLuint vShaderId = 0;
101 vShaderId = load_shader(vertexShaderSrc, GL_VERTEX_SHADER);
102 assert(vShaderId);
103
104 GLuint fShaderId = 0;
105 fShaderId = load_shader(fragmentShaderSrc, GL_FRAGMENT_SHADER);
106 assert(fShaderId);
107
108 GLuint progId = 0;
109 progId = glCreateProgram();
110 assert(progId);
111 glAttachShader(progId, vShaderId);
112 glAttachShader(progId, fShaderId);
113 glLinkProgram(progId);
114
115 GLint linked = 0;
116 glGetProgramiv(progId, GL_LINK_STATUS, &linked);
117 if (!linked)
118 {
119 GLchar log[1024];
120 glGetProgramInfoLog(progId, sizeof log - 1, NULL, log);
121 log[sizeof log - 1] = '\0';
122 printf("Link failed: %s\n", log);
123 return 0;
124 }
125
126 return progId;
127}
128
129typedef struct _AnimationValues
130{
131 double lastTimeStamp;
132 GLfloat angle;
133 GLfloat fadeBackground;
134 GLfloat fadeLogo;
135 GLfloat fadeGlow;
136} AnimationValues;
137
138bool updateAnimation (GTimer* timer, AnimationValues* anim)
139{
140 if (!timer || !anim)
141 return false;
142
143 //1.) 0.0 - 0.6: logo fades in fully
144 //2.) 0.0 - 6.0: logo does one full spin 360°
145 //3.) 6.0 - 6.833: glow fades in fully, black-background fades out to 50%
146 //4.) 6.833 - 7.666: glow fades out fully, black-background fades out to 0%
147 //5.) 7.666 - 8.266: logo fades out fully
148 //8.266..: now spinner can be closed as all its elements are faded out
149
150 // Hacked to run three times as fast
151 double elapsed = 3*g_timer_elapsed (timer, NULL);
152 double dt = elapsed - anim->lastTimeStamp;
153 anim->lastTimeStamp = elapsed;
154
155 // step 1.)
156 if (elapsed < 0.6f)
157 anim->fadeLogo += 1.6f * dt;
158
159 // step 2.)
160 anim->angle -= (0.017453292519943f * 360.0f / 18.0f) * dt;
161
162 // step 3.) glow
163 if (elapsed > 6.0f && elapsed < 6.833f)
164 anim->fadeGlow += 1.2f * dt;
165
166 // step 3.) background
167 if (elapsed > 0.6f && elapsed < 6.833f)
168 { if (anim->fadeBackground > 0) anim->fadeBackground -= 0.15f * dt; else anim->fadeBackground = 0; }
169
170 // step 4.) glow
171 if (elapsed > 7.0f)
172 anim->fadeGlow -= 0.6f * dt;
173
174 // step 5.)
175 if (elapsed > 6.833f)
176 anim->fadeLogo -= 1.6f * dt;
177
178 return elapsed < 8.266f;
179}
180
181namespace
182{
183const char vShaderSrcSpinner[] =
184 "attribute vec4 vPosition; \n"
185 "attribute vec2 aTexCoords; \n"
186 "uniform float theta; \n"
187 "varying vec2 vTexCoords; \n"
188 "void main() \n"
189 "{ \n"
190 " float c = cos(theta); \n"
191 " float s = sin(theta); \n"
192 " mat2 m; \n"
193 " m[0] = vec2(c, s); \n"
194 " m[1] = vec2(-s, c); \n"
195 " vTexCoords = m * aTexCoords + vec2 (0.5, 0.5); \n"
196 " gl_Position = vec4(vPosition.xy, -1.0, 1.0); \n"
197 "} \n";
198
199const char fShaderSrcGlow[] =
200 "precision mediump float; \n"
201 "varying vec2 vTexCoords; \n"
202 "uniform sampler2D uSampler; \n"
203 "uniform float uFadeGlow; \n"
204 "void main() \n"
205 "{ \n"
206 " vec4 col = texture2D(uSampler, vTexCoords); \n"
207 " col = col * uFadeGlow; \n"
208 " gl_FragColor = col; \n"
209 "} \n";
210
211const char fShaderSrcLogo[] =
212 "precision mediump float; \n"
213 "varying vec2 vTexCoords; \n"
214 "uniform sampler2D uSampler; \n"
215 "uniform float uFadeLogo; \n"
216 "void main() \n"
217 "{ \n"
218 " vec4 col = texture2D(uSampler, vTexCoords); \n"
219 " col = col * uFadeLogo; \n"
220 " gl_FragColor = col; \n"
221 "} \n";
222
223std::atomic<bool> dying{false};
224void lifecycle_event_callback(MirConnection* /*connection*/, MirLifecycleState state, void* context)
225{
226 if (state == mir_lifecycle_connection_lost)
227 static_cast<decltype(dying)*>(context)->store(true);
228}
229}
230
231struct SpinnerSplash::Self
232{
233 std::mutex mutex;
234 std::weak_ptr<mir::scene::Session> session;
235};
236
237SpinnerSplash::SpinnerSplash() : self{std::make_shared<Self>()} {}
238
239SpinnerSplash::~SpinnerSplash() = default;
240
241void SpinnerSplash::operator()(std::weak_ptr<mir::scene::Session> const& session)
242{
243 std::lock_guard<decltype(self->mutex)> lock{self->mutex};
244 self->session = session;
245}
246
247auto SpinnerSplash::session() const
248-> std::shared_ptr<mir::scene::Session>
249{
250 std::lock_guard<decltype(self->mutex)> lock{self->mutex};
251 return self->session.lock();
252}
253
254void SpinnerSplash::operator()(MirConnection* const connection)
255try
256{
257 GLuint prog[2];
258 GLuint texture[2];
259 GLint vpos[2];
260 GLint theta;
261 GLint fadeGlow;
262 GLint fadeLogo;
263 GLint aTexCoords[2];
264 GLint sampler[2];
265
266 mir_connection_set_lifecycle_event_callback(connection, &lifecycle_event_callback, &dying);
267 auto const windows = mir_eglapp_init(connection);
268
269 if (!windows.size()) return;
270
271 double pixelSize = 10 * 11.18;
272 const GLfloat texCoordsSpinner[] =
273 {
274 -0.5f, 0.5f,
275 -0.5f, -0.5f,
276 0.5f, 0.5f,
277 0.5f, -0.5f,
278 };
279
280 prog[0] = createShaderProgram(vShaderSrcSpinner, fShaderSrcGlow);
281 prog[1] = createShaderProgram(vShaderSrcSpinner, fShaderSrcLogo);
282
283 // setup proper GL-blending
284 glEnable(GL_BLEND);
285 glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
286 glBlendEquation(GL_FUNC_ADD);
287
288 // get locations of shader-attributes/uniforms
289 vpos[0] = glGetAttribLocation(prog[0], "vPosition");
290 aTexCoords[0] = glGetAttribLocation(prog[0], "aTexCoords");
291 theta = glGetUniformLocation(prog[0], "theta");
292 sampler[0] = glGetUniformLocation(prog[0], "uSampler");
293 fadeGlow = glGetUniformLocation(prog[0], "uFadeGlow");
294 vpos[1] = glGetAttribLocation(prog[1], "vPosition");
295 aTexCoords[1] = glGetAttribLocation(prog[1], "aTexCoords");
296 sampler[1] = glGetUniformLocation(prog[1], "uSampler");
297 fadeLogo = glGetUniformLocation(prog[1], "uFadeLogo");
298
299 // create and upload spinner-artwork
300 // note that the embedded image data has pre-multiplied alpha
301 glGenTextures(2, texture);
302 uploadTexture(texture[0], spinner_glow);
303 uploadTexture(texture[1], spinner_logo);
304
305 // bunch of shader-attributes to enable
306 glVertexAttribPointer(aTexCoords[0], 2, GL_FLOAT, GL_FALSE, 0, texCoordsSpinner);
307 glVertexAttribPointer(aTexCoords[1], 2, GL_FLOAT, GL_FALSE, 0, texCoordsSpinner);
308 glEnableVertexAttribArray(vpos[0]);
309 glEnableVertexAttribArray(vpos[1]);
310 glEnableVertexAttribArray(aTexCoords[0]);
311 glEnableVertexAttribArray(aTexCoords[1]);
312 glActiveTexture(GL_TEXTURE0);
313
314 AnimationValues anim = {0.0, 0.0, 1.0, 0.0, 0.0};
315 GTimer* timer = g_timer_new();
316
317 do
318 {
319 for (auto const& surface : windows)
320 surface->paint([&](unsigned int width, unsigned int height)
321 {
322 GLfloat halfRealWidth = ((2.0 / width) * pixelSize) / 2.0;
323 GLfloat halfRealHeight = ((2.0 / height) * pixelSize) / 2.0;
324
325 const GLfloat vertices[] =
326 {
327 halfRealWidth, halfRealHeight,
328 halfRealWidth, -halfRealHeight,
329 -halfRealWidth, halfRealHeight,
330 -halfRealWidth,-halfRealHeight,
331 };
332
333 glVertexAttribPointer(vpos[0], 2, GL_FLOAT, GL_FALSE, 0, vertices);
334 glVertexAttribPointer(vpos[1], 2, GL_FLOAT, GL_FALSE, 0, vertices);
335
336 glViewport(0, 0, width, height);
337
338 GLfloat color[] = {LIGHT_AUBERGINE};
339 for (auto& c : color) { c*= anim.fadeBackground; }
340
341 glClearColor(color[0], color[1], color[2], anim.fadeBackground);
342 glClear(GL_COLOR_BUFFER_BIT);
343
344 // draw glow
345 glUseProgram(prog[0]);
346 glBindTexture(GL_TEXTURE_2D, texture[0]);
347 glUniform1i(sampler[0], 0);
348 glUniform1f(theta, anim.angle);
349 glUniform1f(fadeGlow, anim.fadeGlow);
350 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
351
352 // draw logo
353 glUseProgram(prog[1]);
354 glBindTexture(GL_TEXTURE_2D, texture[1]);
355 glUniform1i(sampler[1], 0);
356 glUniform1f(theta, anim.angle);
357 glUniform1f(fadeLogo, anim.fadeLogo);
358 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
359 });
360
361 if (dying.load())
362 throw std::runtime_error("Server disconnected");
363 }
364 while (updateAnimation(timer, &anim));
365
366 glDeleteTextures(2, texture);
367 g_timer_destroy (timer);
368}
369catch (std::exception const& x)
370{
371 printf("%s\n", x.what());
372}
0373
=== added file 'examples/miral-shell/spinner/miregl.cpp'
--- examples/miral-shell/spinner/miregl.cpp 1970-01-01 00:00:00 +0000
+++ examples/miral-shell/spinner/miregl.cpp 2017-08-29 09:17:20 +0000
@@ -0,0 +1,239 @@
1/*
2 * Copyright © 2015 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * under the terms of the GNU General Public License version 2 or 3 as as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include "miregl.h"
18#include <miral/window_specification.h>
19#include <mir/client/window_spec.h>
20#include <mir_toolkit/mir_client_library.h>
21
22#include <cstring>
23
24#include <GLES2/gl2.h>
25
26using namespace mir::client;
27
28class MirEglApp
29{
30public:
31 MirEglApp(MirConnection* const connection, MirPixelFormat pixel_format);
32
33 EGLSurface create_surface(MirRenderSurface* surface);
34
35 void make_current(EGLSurface eglsurface) const;
36
37 void swap_buffers(EGLSurface eglsurface) const;
38
39 void destroy_surface(EGLSurface eglsurface) const;
40
41 void get_surface_size(EGLSurface eglsurface, int* width, int* height) const;
42
43 void set_swap_interval(EGLSurface eglsurface, int interval) const;
44
45 bool supports_surfaceless_context();
46
47 ~MirEglApp();
48
49 MirConnection* const connection;
50private:
51 EGLDisplay egldisplay;
52 EGLContext eglctx;
53 EGLConfig eglconfig;
54 EGLint neglconfigs;
55 EGLSurface dummy_surface;
56};
57
58std::shared_ptr<MirEglApp> make_mir_eglapp(
59 MirConnection* const connection, MirPixelFormat const& pixel_format)
60{
61 return std::make_shared<MirEglApp>(connection, pixel_format);
62}
63
64MirEglSurface::MirEglSurface(
65 std::shared_ptr<MirEglApp> const& mir_egl_app,
66 char const* name,
67 MirOutput const* output)
68:
69 mir_egl_app{mir_egl_app}
70{
71 auto const mode = mir_output_get_current_mode(output);
72 auto const output_id = mir_output_get_id(output);
73 auto const width = mir_output_mode_get_width(mode);
74 auto const height = mir_output_mode_get_height(mode);
75
76 surface = Surface{mir_connection_create_render_surface_sync(mir_egl_app->connection, width, height)};
77
78 eglsurface = mir_egl_app->create_surface(surface);
79
80 window = WindowSpec::for_normal_window(mir_egl_app->connection, width, height)
81 .add_surface(surface, width, height, 0, 0)
82 .set_name(name)
83 .set_fullscreen_on_output(output_id)
84 .create_window();
85
86 if (!mir_window_is_valid(window))
87 throw std::runtime_error(std::string("Can't create a window ") + mir_window_get_error_message(window));
88
89 mir_egl_app->set_swap_interval(eglsurface, -1);
90}
91
92MirEglSurface::~MirEglSurface()
93{
94 mir_egl_app->destroy_surface(eglsurface);
95}
96
97void MirEglSurface::egl_make_current()
98{
99 mir_egl_app->get_surface_size(eglsurface, &width_, &height_);
100 mir_egl_app->make_current(eglsurface);
101}
102
103void MirEglSurface::swap_buffers()
104{
105 mir_egl_app->swap_buffers(eglsurface);
106}
107
108unsigned int MirEglSurface::width() const
109{
110 return width_;
111}
112
113unsigned int MirEglSurface::height() const
114{
115 return height_;
116}
117
118MirEglApp::MirEglApp(MirConnection* const connection, MirPixelFormat pixel_format) :
119 connection{connection},
120 dummy_surface{EGL_NO_SURFACE}
121{
122 unsigned int bpp = 8*MIR_BYTES_PER_PIXEL(pixel_format);
123
124 EGLint attribs[] =
125 {
126 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
127 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
128 EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER,
129 EGL_BUFFER_SIZE, (EGLint) bpp,
130 EGL_NONE
131 };
132
133 egldisplay = eglGetDisplay((EGLNativeDisplayType)(connection));
134 if (egldisplay == EGL_NO_DISPLAY)
135 throw std::runtime_error("Can't eglGetDisplay");
136
137 EGLint major;
138 EGLint minor;
139 if (!eglInitialize(egldisplay, &major, &minor))
140 throw std::runtime_error("Can't eglInitialize");
141
142 if (major != 1 || minor != 4)
143 throw std::runtime_error("EGL version is not 1.4");
144
145 if (!eglChooseConfig(egldisplay, attribs, &eglconfig, 1, &neglconfigs))
146 throw std::runtime_error("Could not eglChooseConfig");
147
148 if (neglconfigs == 0)
149 throw std::runtime_error("No EGL config available");
150
151 EGLint ctxattribs[] =
152 {
153 EGL_CONTEXT_CLIENT_VERSION, 2,
154 EGL_NONE
155 };
156
157 eglctx = eglCreateContext(egldisplay, eglconfig, EGL_NO_CONTEXT, ctxattribs);
158 if (eglctx == EGL_NO_CONTEXT)
159 throw std::runtime_error("eglCreateContext failed");
160
161 if (!supports_surfaceless_context())
162 {
163 static EGLint const dummy_pbuffer_attribs[] =
164 {
165 EGL_WIDTH, 1,
166 EGL_HEIGHT, 1,
167 EGL_NONE
168 };
169
170 dummy_surface = eglCreatePbufferSurface(egldisplay, eglconfig, dummy_pbuffer_attribs);
171 if (dummy_surface == EGL_NO_SURFACE)
172 throw std::runtime_error("eglCreatePbufferSurface failed");
173 }
174
175 make_current(dummy_surface);
176}
177
178EGLSurface MirEglApp::create_surface(MirRenderSurface* surface)
179{
180 auto const eglsurface = eglCreateWindowSurface(
181 egldisplay,
182 eglconfig,
183 (EGLNativeWindowType)surface, NULL);
184
185 if (eglsurface == EGL_NO_SURFACE)
186 throw std::runtime_error("eglCreateWindowSurface failed");
187
188 return eglsurface;
189}
190
191void MirEglApp::make_current(EGLSurface eglsurface) const
192{
193 if (!eglMakeCurrent(egldisplay, eglsurface, eglsurface, eglctx))
194 throw std::runtime_error("Can't eglMakeCurrent");
195}
196
197void MirEglApp::swap_buffers(EGLSurface eglsurface) const
198{
199 eglSwapBuffers(egldisplay, eglsurface);
200}
201
202void MirEglApp::destroy_surface(EGLSurface eglsurface) const
203{
204 eglDestroySurface(egldisplay, eglsurface);
205}
206
207void MirEglApp::get_surface_size(EGLSurface eglsurface, int* width, int* height) const
208{
209 eglQuerySurface(egldisplay, eglsurface, EGL_WIDTH, width);
210 eglQuerySurface(egldisplay, eglsurface, EGL_HEIGHT, height);
211}
212
213void MirEglApp::set_swap_interval(EGLSurface eglsurface, int interval) const
214{
215 auto const previous_surface = eglGetCurrentSurface(EGL_DRAW);
216
217 make_current(eglsurface);
218 eglSwapInterval(egldisplay, interval);
219
220 if (previous_surface != EGL_NO_SURFACE)
221 make_current(previous_surface);
222}
223
224bool MirEglApp::supports_surfaceless_context()
225{
226 auto const extensions = eglQueryString(egldisplay, EGL_EXTENSIONS);
227 if (!extensions)
228 return false;
229 return std::strstr(extensions, "EGL_KHR_surfaceless_context") != nullptr;
230}
231
232MirEglApp::~MirEglApp()
233{
234 eglMakeCurrent(egldisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
235 if (dummy_surface != EGL_NO_SURFACE)
236 destroy_surface(dummy_surface);
237 eglDestroyContext(egldisplay, eglctx);
238 eglTerminate(egldisplay);
239}
0240
=== added file 'examples/miral-shell/spinner/miregl.h'
--- examples/miral-shell/spinner/miregl.h 1970-01-01 00:00:00 +0000
+++ examples/miral-shell/spinner/miregl.h 2017-08-29 09:17:20 +0000
@@ -0,0 +1,67 @@
1/*
2 * Copyright © 2015 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * under the terms of the GNU General Public License version 2 or 3 as as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef UNITYSYSTEMCOMPOSITOR_MIREGL_H
18#define UNITYSYSTEMCOMPOSITOR_MIREGL_H
19
20#include <mir/client/surface.h>
21#include <mir/client/window.h>
22
23#include <EGL/egl.h>
24
25#include <memory>
26
27class MirEglApp;
28class MirEglSurface;
29
30std::shared_ptr<MirEglApp> make_mir_eglapp(
31 MirConnection* const connection,
32 MirPixelFormat const& pixel_format);
33
34class MirEglSurface
35{
36public:
37 MirEglSurface(
38 std::shared_ptr<MirEglApp> const& mir_egl_app,
39 char const* name,
40 MirOutput const* output);
41
42 ~MirEglSurface();
43
44 template<typename Painter>
45 void paint(Painter const& functor)
46 {
47 egl_make_current();
48 functor(width(), height());
49 swap_buffers();
50 }
51
52private:
53 void egl_make_current();
54
55 void swap_buffers();
56 unsigned int width() const;
57 unsigned int height() const;
58
59 std::shared_ptr<MirEglApp> const mir_egl_app;
60 mir::client::Surface surface;
61 mir::client::Window window;
62 EGLSurface eglsurface;
63 int width_;
64 int height_;
65};
66
67#endif //UNITYSYSTEMCOMPOSITOR_MIREGL_H
068
=== added file 'examples/miral-shell/spinner/png2header.py'
--- examples/miral-shell/spinner/png2header.py 1970-01-01 00:00:00 +0000
+++ examples/miral-shell/spinner/png2header.py 2017-08-29 09:17:20 +0000
@@ -0,0 +1,87 @@
1#!/usr/bin/env python
2# coding: utf-8
3
4# Copyright © 2015 Canonical Ltd.
5#
6# This program is free software: you can redistribute it and/or modify
7# it under the terms of the GNU General Public License version 2 or 3
8# as published by the Free Software Foundation.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program. If not, see <http://www.gnu.org/licenses/>.
17#
18# Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>
19
20import sys
21from PIL import Image
22
23def premultiply(image):
24 pixels = image.load()
25 for i in range(image.size[0]):
26 for j in range(image.size[1]):
27 orig = pixels[i,j]
28 m = orig[3] / 255.0
29 pixels[i,j] = (int(orig[0] * m) , int(orig[1] * m), int(orig[2] * m), orig[3])
30
31def tocstring(data):
32 result = ''
33 line_chars = 0
34 line_limit = 80
35
36 for c in data:
37 if line_chars == 0:
38 result += ' "'
39
40 s = '\\%o' % c
41 result += s
42 line_chars += len(s)
43
44 if line_chars >= line_limit:
45 result += '"\n'
46 line_chars = 0
47
48 if line_chars != 0:
49 result += '"'
50
51 return result
52
53def bytes_per_pixel(image):
54 if image.mode == 'RGBA':
55 return 4
56 elif image.mode == 'RGB':
57 return 3
58 else:
59 raise "Unsupported image mode %s" % image.mode
60
61def export(image, variable_name):
62 image_info = (image.size[0], image.size[1], bytes_per_pixel(image))
63 print("static const struct {")
64 print(" unsigned int width;")
65 print(" unsigned int height;")
66 print(" unsigned int bytes_per_pixel; /* 3:RGB, 4:RGBA */")
67 print(" unsigned char pixel_data[%d * %d * %d + 1];" % image_info)
68 print("} %s = {" % variable_name)
69 print(" %d, %d, %d," % image_info)
70 print(tocstring(image.tobytes()))
71 print("};")
72
73def show_usage():
74 print("Usage: ./png2header.py PNGFILE VARNAME > HEADER_FILE", file=sys.stderr)
75 print("Convert a PNG image to an embeddable C/C++ header file", file=sys.stderr)
76
77if len(sys.argv) < 3:
78 show_usage()
79 sys.exit(1)
80
81image_filename = sys.argv[1]
82variable_name = sys.argv[2]
83
84image = Image.open(image_filename)
85if image.mode == 'RGBA':
86 premultiply(image)
87export(image, variable_name)
088
=== added file 'examples/miral-shell/spinner/spinner-glow.png'
1Binary files examples/miral-shell/spinner/spinner-glow.png 1970-01-01 00:00:00 +0000 and examples/miral-shell/spinner/spinner-glow.png 2017-08-29 09:17:20 +0000 differ89Binary files examples/miral-shell/spinner/spinner-glow.png 1970-01-01 00:00:00 +0000 and examples/miral-shell/spinner/spinner-glow.png 2017-08-29 09:17:20 +0000 differ
=== added file 'examples/miral-shell/spinner/spinner-logo.png'
2Binary files examples/miral-shell/spinner/spinner-logo.png 1970-01-01 00:00:00 +0000 and examples/miral-shell/spinner/spinner-logo.png 2017-08-29 09:17:20 +0000 differ90Binary files examples/miral-shell/spinner/spinner-logo.png 1970-01-01 00:00:00 +0000 and examples/miral-shell/spinner/spinner-logo.png 2017-08-29 09:17:20 +0000 differ
=== added file 'examples/miral-shell/spinner/splash.h'
--- examples/miral-shell/spinner/splash.h 1970-01-01 00:00:00 +0000
+++ examples/miral-shell/spinner/splash.h 2017-08-29 09:17:20 +0000
@@ -0,0 +1,45 @@
1/*
2 * Copyright © 2016 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 or 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Alan Griffiths <alan@octopull.co.uk>
17 */
18
19#ifndef MIRAL_SHELL_SPINNER_SPLASH_H
20#define MIRAL_SHELL_SPINNER_SPLASH_H
21
22#include <mir_toolkit/client_types.h>
23
24#include <memory>
25
26namespace mir { namespace scene { class Session; }}
27
28namespace mir { class Server; namespace scene { class Session; }}
29
30class SpinnerSplash
31{
32public:
33 SpinnerSplash();
34 ~SpinnerSplash();
35
36 void operator()(MirConnection* connection);
37 void operator()(std::weak_ptr<mir::scene::Session> const& session);
38 auto session() const -> std::shared_ptr<mir::scene::Session>;
39
40private:
41 struct Self;
42 std::shared_ptr<Self> const self;
43};
44
45#endif //MIRAL_SHELL_SPINNER_SPLASH_H
046
=== added file 'examples/miral-shell/tiling_window_manager.cpp'
--- examples/miral-shell/tiling_window_manager.cpp 1970-01-01 00:00:00 +0000
+++ examples/miral-shell/tiling_window_manager.cpp 2017-08-29 09:17:20 +0000
@@ -0,0 +1,688 @@
1/*
2 * Copyright © 2015-2016 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 or 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored By: Alan Griffiths <alan@octopull.co.uk>
17 */
18
19#include "tiling_window_manager.h"
20
21#include <miral/application_info.h>
22#include <miral/window_info.h>
23#include <miral/window_manager_tools.h>
24#include <miral/output.h>
25
26#include <linux/input.h>
27#include <algorithm>
28#include <csignal>
29
30namespace ms = mir::scene;
31using namespace miral;
32
33namespace
34{
35struct TilingWindowManagerPolicyData
36{
37 Rectangle tile;
38 Rectangle old_tile;
39};
40
41template<class Info>
42inline Rectangle& tile_for(Info& info)
43{
44 return std::static_pointer_cast<TilingWindowManagerPolicyData>(info.userdata())->tile;
45}
46
47template<class Info>
48inline Rectangle const& tile_for(Info const& info)
49{
50 return std::static_pointer_cast<TilingWindowManagerPolicyData>(info.userdata())->tile;
51}
52}
53
54void TilingWindowManagerPolicy::MRUTileList::push(std::shared_ptr<void> const& tile)
55{
56 tiles.erase(remove(begin(tiles), end(tiles), tile), end(tiles));
57 tiles.push_back(tile);
58}
59
60void TilingWindowManagerPolicy::MRUTileList::erase(std::shared_ptr<void> const& tile)
61{
62 tiles.erase(remove(begin(tiles), end(tiles), tile), end(tiles));
63}
64
65void TilingWindowManagerPolicy::MRUTileList::enumerate(Enumerator const& enumerator) const
66{
67 for (auto i = tiles.rbegin(); i != tiles.rend(); ++i)
68 enumerator(const_cast<std::shared_ptr<void> const&>(*i));
69}
70
71// Demonstrate implementing a simple tiling algorithm
72
73TilingWindowManagerPolicy::TilingWindowManagerPolicy(
74 WindowManagerTools const& tools,
75 SpinnerSplash const& spinner,
76 miral::InternalClientLauncher const& launcher,
77 miral::ActiveOutputsMonitor& outputs_monitor) :
78 tools{tools},
79 spinner{spinner},
80 launcher{launcher},
81 outputs_monitor{outputs_monitor}
82{
83 outputs_monitor.add_listener(this);
84}
85
86TilingWindowManagerPolicy::~TilingWindowManagerPolicy()
87{
88 outputs_monitor.delete_listener(this);
89}
90
91void TilingWindowManagerPolicy::click(Point cursor)
92{
93 auto const window = tools.window_at(cursor);
94 tools.select_active_window(window);
95}
96
97void TilingWindowManagerPolicy::resize(Point cursor)
98{
99 if (auto const application = application_under(cursor))
100 {
101 if (application == application_under(old_cursor))
102 {
103 if (auto const window = tools.select_active_window(tools.window_at(old_cursor)))
104 {
105 resize(window, cursor, old_cursor, tile_for(tools.info_for(application)));
106 }
107 }
108 }
109}
110
111auto TilingWindowManagerPolicy::place_new_window(
112 ApplicationInfo const& app_info,
113 WindowSpecification const& request_parameters)
114 -> WindowSpecification
115{
116 auto parameters = request_parameters;
117
118 parameters.userdata() = app_info.userdata();
119 parameters.state() = parameters.state().is_set() ?
120 transform_set_state(parameters.state().value()) : mir_window_state_restored;
121
122 if (app_info.application() != spinner.session())
123 {
124 Rectangle const& tile = tile_for(app_info);
125
126 if (!parameters.parent().is_set() || !parameters.parent().value().lock())
127 {
128 if (app_info.windows().empty())
129 {
130 parameters.top_left() = tile.top_left;
131 parameters.size() = tile.size;
132 }
133 else
134 {
135 auto top_level_windows = count_if(begin(app_info.windows()), end(app_info.windows()), [this]
136 (Window const& window){ return !tools.info_for(window).parent(); });
137
138 parameters.top_left() = tile.top_left + top_level_windows*Displacement{15, 15};
139 }
140 }
141
142 clip_to_tile(parameters, tile);
143 }
144
145 return parameters;
146}
147
148void TilingWindowManagerPolicy::advise_new_window(WindowInfo const& window_info)
149{
150 if (window_info.type() == mir_window_type_normal &&
151 !window_info.parent() &&
152 window_info.state() == mir_window_state_restored)
153 {
154 WindowSpecification specification;
155
156 specification.state() = mir_window_state_maximized;
157
158 tools.place_and_size_for_state(specification, window_info);
159 constrain_size_and_place(specification, window_info.window(), tile_for(window_info));
160 tools.modify_window(window_info.window(), specification);
161 }
162}
163
164void TilingWindowManagerPolicy::handle_window_ready(WindowInfo& window_info)
165{
166 if (window_info.can_be_active())
167 tools.select_active_window(window_info.window());
168
169 if (spinner.session() != window_info.window().application())
170 {
171 tiles.push(window_info.userdata());
172 dirty_tiles = true;
173 }
174}
175
176namespace
177{
178template<typename ValueType>
179void reset(mir::optional_value<ValueType>& option)
180{
181 if (option.is_set()) option.consume();
182}
183}
184
185void TilingWindowManagerPolicy::handle_modify_window(
186 miral::WindowInfo& window_info,
187 miral::WindowSpecification const& modifications)
188{
189 auto const window = window_info.window();
190 auto const tile = tile_for(window_info);
191 auto mods = modifications;
192
193 constrain_size_and_place(mods, window, tile);
194
195 reset(mods.output_id());
196
197 tools.modify_window(window_info, mods);
198}
199
200void TilingWindowManagerPolicy::constrain_size_and_place(
201 WindowSpecification& mods, Window const& window, Rectangle const& tile) const
202{
203 if (mods.size().is_set())
204 {
205 auto width = std::min(tile.size.width, mods.size().value().width);
206 auto height = std::min(tile.size.height, mods.size().value().height);
207
208 mods.size() = Size{width, height};
209 }
210
211 if (mods.top_left().is_set())
212 {
213 auto x = std::max(tile.top_left.x, mods.top_left().value().x);
214 auto y = std::max(tile.top_left.y, mods.top_left().value().y);
215
216 mods.top_left() = Point{x, y};
217 }
218
219 auto top_left = mods.top_left().is_set() ? mods.top_left().value() : window.top_left();
220 auto bottom_right = top_left + as_displacement(mods.size().is_set() ? mods.size().value() : window.size());
221 auto overhang = bottom_right - tile.bottom_right();
222
223 if (overhang.dx > DeltaX{0}) top_left = top_left - overhang.dx;
224 if (overhang.dy > DeltaY{0}) top_left = top_left - overhang.dy;
225
226 if (top_left != window.top_left())
227 mods.top_left() = top_left;
228 else
229 reset(mods.top_left());
230}
231
232auto TilingWindowManagerPolicy::transform_set_state(MirWindowState value)
233-> MirWindowState
234{
235 switch (value)
236 {
237 default:
238 return mir_window_state_restored;
239
240 case mir_window_state_hidden:
241 case mir_window_state_minimized:
242 return mir_window_state_hidden;
243 }
244}
245
246void TilingWindowManagerPolicy::drag(Point cursor)
247{
248 if (auto const application = application_under(cursor))
249 {
250 if (application == application_under(old_cursor))
251 {
252 if (auto const window = tools.select_active_window(tools.window_at(old_cursor)))
253 {
254
255 auto const tile = tile_for(tools.info_for(application));
256 WindowSpecification mods;
257 mods.top_left() = window.top_left() + (cursor-old_cursor);
258 constrain_size_and_place(mods, window, tile);
259 tools.modify_window(window, mods);
260 }
261 }
262 }
263}
264
265void TilingWindowManagerPolicy::handle_raise_window(WindowInfo& window_info)
266{
267 tools.select_active_window(window_info.window());
268}
269
270bool TilingWindowManagerPolicy::handle_keyboard_event(MirKeyboardEvent const* event)
271{
272 auto const action = mir_keyboard_event_action(event);
273 auto const scan_code = mir_keyboard_event_scan_code(event);
274 auto const modifiers = mir_keyboard_event_modifiers(event) & modifier_mask;
275
276 if (action == mir_keyboard_action_down && scan_code == KEY_F12 &&
277 (modifiers & modifier_mask) == mir_input_event_modifier_alt)
278 {
279 launcher.launch("Spinner", spinner);
280 return true;
281 }
282
283 if (action == mir_keyboard_action_down && scan_code == KEY_F11)
284 {
285 switch (modifiers & modifier_mask)
286 {
287 case mir_input_event_modifier_alt:
288 toggle(mir_window_state_maximized);
289 return true;
290
291 case mir_input_event_modifier_shift:
292 toggle(mir_window_state_vertmaximized);
293 return true;
294
295 case mir_input_event_modifier_ctrl:
296 toggle(mir_window_state_horizmaximized);
297 return true;
298
299 default:
300 break;
301 }
302 }
303 else if (action == mir_keyboard_action_down && scan_code == KEY_F4)
304 {
305 switch (modifiers & modifier_mask)
306 {
307 case mir_input_event_modifier_alt|mir_input_event_modifier_shift:
308 if (auto const& window = tools.active_window())
309 kill(window.application(), SIGTERM);
310 return true;
311
312 case mir_input_event_modifier_alt:
313 tools.ask_client_to_close(tools.active_window());;
314 return true;
315
316 default:
317 break;
318 }
319 }
320 else if (action == mir_keyboard_action_down &&
321 modifiers == mir_input_event_modifier_alt &&
322 scan_code == KEY_TAB)
323 {
324 tools.focus_next_application();
325
326 return true;
327 }
328 else if (action == mir_keyboard_action_down &&
329 modifiers == mir_input_event_modifier_alt &&
330 scan_code == KEY_GRAVE)
331 {
332 tools.focus_next_within_application();
333
334 return true;
335 }
336 else if (action == mir_keyboard_action_down &&
337 modifiers == (mir_input_event_modifier_alt | mir_input_event_modifier_shift) &&
338 scan_code == KEY_GRAVE)
339 {
340 tools.focus_prev_within_application();
341
342 return true;
343 }
344
345 return false;
346}
347
348bool TilingWindowManagerPolicy::handle_touch_event(MirTouchEvent const* event)
349{
350 auto const count = mir_touch_event_point_count(event);
351
352 long total_x = 0;
353 long total_y = 0;
354
355 for (auto i = 0U; i != count; ++i)
356 {
357 total_x += mir_touch_event_axis_value(event, i, mir_touch_axis_x);
358 total_y += mir_touch_event_axis_value(event, i, mir_touch_axis_y);
359 }
360
361 Point const cursor{total_x/count, total_y/count};
362
363 bool is_drag = true;
364 for (auto i = 0U; i != count; ++i)
365 {
366 switch (mir_touch_event_action(event, i))
367 {
368 case mir_touch_action_up:
369 return false;
370
371 case mir_touch_action_down:
372 is_drag = false;
373 continue;
374
375 default:
376 continue;
377 }
378 }
379
380 bool consumes_event = false;
381 if (is_drag)
382 {
383 switch (count)
384 {
385 case 4:
386 resize(cursor);
387 consumes_event = true;
388 break;
389
390 case 3:
391 drag(cursor);
392 consumes_event = true;
393 break;
394 }
395 }
396 else
397 {
398 if (auto const& window = tools.window_at(cursor))
399 tools.select_active_window(window);
400 }
401
402 old_cursor = cursor;
403 return consumes_event;
404}
405
406bool TilingWindowManagerPolicy::handle_pointer_event(MirPointerEvent const* event)
407{
408 auto const action = mir_pointer_event_action(event);
409 auto const modifiers = mir_pointer_event_modifiers(event) & modifier_mask;
410 Point const cursor{
411 mir_pointer_event_axis_value(event, mir_pointer_axis_x),
412 mir_pointer_event_axis_value(event, mir_pointer_axis_y)};
413
414 bool consumes_event = false;
415
416 if (action == mir_pointer_action_button_down)
417 {
418 click(cursor);
419 }
420 else if (action == mir_pointer_action_motion &&
421 modifiers == mir_input_event_modifier_alt)
422 {
423 if (mir_pointer_event_button_state(event, mir_pointer_button_primary))
424 {
425 drag(cursor);
426 consumes_event = true;
427 }
428 else if (mir_pointer_event_button_state(event, mir_pointer_button_tertiary))
429 {
430 resize(cursor);
431 consumes_event = true;
432 }
433 }
434
435 old_cursor = cursor;
436 return consumes_event;
437}
438
439void TilingWindowManagerPolicy::toggle(MirWindowState state)
440{
441 if (auto window = tools.active_window())
442 {
443 auto& window_info = tools.info_for(window);
444
445 if (window_info.state() == state)
446 state = mir_window_state_restored;
447
448 WindowSpecification mods;
449 mods.state() = transform_set_state(state);
450 tools.modify_window(window_info, mods);
451 }
452}
453
454auto TilingWindowManagerPolicy::application_under(Point position)
455-> Application
456{
457 return tools.find_application([&, this](ApplicationInfo const& info)
458 { return spinner.session() != info.application() && tile_for(info).contains(position);});
459}
460
461void TilingWindowManagerPolicy::update_tiles(Rectangles const& outputs)
462{
463 auto const tile_count = tiles.count();
464
465 if (tile_count < 1 || outputs.size() < 1) return;
466
467 auto const bounding_rect = outputs.bounding_rectangle();
468
469 auto const total_width = bounding_rect.size.width.as_int();
470 auto const total_height = bounding_rect.size.height.as_int();
471
472 auto index = 0;
473
474 if (tile_count < 3)
475 {
476 tiles.enumerate([&](std::shared_ptr<void> const& userdata)
477 {
478 auto const tile_data = std::static_pointer_cast<TilingWindowManagerPolicyData>(userdata);
479 tile_data->old_tile = tile_data->tile;
480
481 auto const x = (total_width * index) / tile_count;
482 ++index;
483 auto const dx = (total_width * index) / tile_count - x;
484
485 tile_data->tile = Rectangle{{x, 0}, {dx, total_height}};
486 });
487 }
488 else
489 {
490 tiles.enumerate([&](std::shared_ptr<void> const& userdata)
491 {
492 auto const tile_data = std::static_pointer_cast<TilingWindowManagerPolicyData>(userdata);
493 tile_data->old_tile = tile_data->tile;
494
495 auto const dx = total_width/2;
496 if (!index)
497 {
498 tile_data->tile = Rectangle{{0, 0}, {dx, total_height}};
499 }
500 else
501 {
502 auto const x = dx;
503 auto const y = total_height*(index-1) / (tile_count-1);
504 auto const dy = total_height / (tile_count-1);
505 tile_data->tile = Rectangle{{x, y}, {dx, dy}};
506 }
507
508 ++index;
509 });
510 }
511
512 tools.for_each_application([&](ApplicationInfo& info)
513 {
514 if (spinner.session() == info.application())
515 return;
516
517 auto const tile_data = std::static_pointer_cast<TilingWindowManagerPolicyData>(info.userdata());
518 update_surfaces(info, tile_data->old_tile, tile_data->tile);
519 });
520}
521
522void TilingWindowManagerPolicy::update_surfaces(ApplicationInfo& info, Rectangle const& old_tile, Rectangle const& new_tile)
523{
524 for (auto const& window : info.windows())
525 {
526 if (window)
527 {
528 auto& window_info = tools.info_for(window);
529
530 if (!window_info.parent())
531 {
532 auto const new_pos = window.top_left() + (new_tile.top_left - old_tile.top_left);
533 auto const offset = new_pos - new_tile.top_left;
534
535 // For now just scale if was filling width/height of tile
536 auto const old_size = window.size();
537 auto const scaled_width = old_size.width == old_tile.size.width ? new_tile.size.width : old_size.width;
538 auto const scaled_height = old_size.height == old_tile.size.height ? new_tile.size.height : old_size.height;
539
540 auto width = std::min(new_tile.size.width.as_int() - offset.dx.as_int(), scaled_width.as_int());
541 auto height = std::min(new_tile.size.height.as_int() - offset.dy.as_int(), scaled_height.as_int());
542
543 WindowSpecification modifications;
544 modifications.top_left() = new_pos;
545 modifications.size() = {width, height};
546 tools.modify_window(window_info, modifications);
547 }
548 }
549 }
550}
551
552void TilingWindowManagerPolicy::clip_to_tile(miral::WindowSpecification& parameters, Rectangle const& tile)
553{
554 auto const displacement = parameters.top_left().value() - tile.top_left;
555
556 auto width = std::min(tile.size.width.as_int()-displacement.dx.as_int(), parameters.size().value().width.as_int());
557 auto height = std::min(tile.size.height.as_int()-displacement.dy.as_int(), parameters.size().value().height.as_int());
558
559 parameters.size() = Size{width, height};
560}
561
562void TilingWindowManagerPolicy::resize(Window window, Point cursor, Point old_cursor, Rectangle bounds)
563{
564 auto const top_left = window.top_left();
565
566 auto const old_displacement = old_cursor - top_left;
567 auto const new_displacement = cursor - top_left;
568
569 auto const scale_x = float(new_displacement.dx.as_int())/std::max(1.0f, float(old_displacement.dx.as_int()));
570 auto const scale_y = float(new_displacement.dy.as_int())/std::max(1.0f, float(old_displacement.dy.as_int()));
571
572 if (scale_x <= 0.0f || scale_y <= 0.0f) return;
573
574 auto const old_size = window.size();
575 Size new_size{scale_x*old_size.width, scale_y*old_size.height};
576
577 auto const size_limits = as_size(bounds.bottom_right() - top_left);
578
579 if (new_size.width > size_limits.width)
580 new_size.width = size_limits.width;
581
582 if (new_size.height > size_limits.height)
583 new_size.height = size_limits.height;
584
585 window.resize(new_size);
586}
587
588void TilingWindowManagerPolicy::advise_focus_gained(WindowInfo const& info)
589{
590 tools.raise_tree(info.window());
591
592 if (auto const spinner_session = spinner.session())
593 {
594 auto const& spinner_info = tools.info_for(spinner_session);
595
596 if (spinner_info.windows().size() > 0)
597 tools.raise_tree(spinner_info.windows()[0]);
598 }
599 else
600 {
601 tiles.push(info.userdata());
602 dirty_tiles = true;
603 }
604}
605
606void TilingWindowManagerPolicy::advise_new_app(miral::ApplicationInfo& application)
607{
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches