Canonical Voices

Michael Hall

I’ve had a Nexus 4 since 2013, and I’ve been using it to test out desktop convergence (where you run a desktop environment from the phone) ever since that feature landed just over a year ago. Usually that meant plugging it into my TV via HDMI to make sure it automatically switched to the larger screen, and playing a bit with the traditional windowed-mode of Unity 8, or checking on adaptive layouts in some of the apps. I’ve also run it for hours on end as a demo at conferences such as SCaLE, FOSSETCON, OSCON and SELF. But through all that, I’ve never used it as an actual replacement for my laptop. Until now.

Thanks Frontier

A bit of back-story first. I had been a Verizon FiOS customer for years, and recently they sold all of their FiOS business to Frontier. The transition has been…..less than ideal. A couple of weeks ago I lost all services (phone, TV and internet) and was eventually told that nobody would be out to fix it until the following day. I still had my laptop, but without internet access I couldn’t really do my job on it. And while Ubuntu on phones can offer up a Hotspot, that particular feature doesn’t work on the Nexus 4 (something something, driver, something). Which meant that the only device that I had which could get online was my phone.

No Minecraft for you

13528720_10154238389913419_2608531900571217522_nFortunately, the fact that I’ve been demoing convergence at conferences meant I had all of the equipment I needed to turn my phone into a desktop and keep right on working. I have a bluetooth mouse and keyboard, and a Slimport adapter that let’s me plug it into a bigger screen. But while a TV works for testing, it’s not really great for long-term work. Don’t get me wrong, working from the couch is nice, but the screen is just too far away for reading and writing. Fortunately for me, and unfortunately for my children, their computer is at a desk and is plugged into a monitor with HDMI ports. So I took it over for the day. They didn’t have internet either that day, so they didn’t miss out on much right?

A day of observations

Throughout the day I posted a series of comments on Google+ about my experience. You could go through my post history looking for them, but I’m not going to make you do that. So here’s a quick summary of what I learned:

  • 3G is not nearly fast enough for my daily work. It’s good when using my phone as a phone, doing one thing at a time. But it falls short of broadband when I’ve got a lot of things using it. Still, on that day it was better than my fiber optic service, so there’s that.
  • I had more apps installed on my phone than I thought I did. I was actually taken aback when I opened the Dash in desktop mode and I saw so many icons. It’s far more than I had on Android, though not quite as many as on my laptop.
  • Having a fully-functional Terminal is a lifesaver. I do a lot of my work from the terminal, including IRC, and having one with tabs and keyboard shortcuts for them is a must for me to work.
  • I missed having physical buttons on my keyboard for home/end and page up/down. Thankfully a couple of people came to my rescue in the comments and taught me other combinations to get those.
  • Unity 8 is Unity. Almost all of the keyboard shortcuts that have become second nature to me (an there are a lot of them) were there. There was no learning curve, I didn’t have to change how I did anything or teach myself something new.
  • The phone is still a phone. I got a call (from Frontier, reminding me about an appointment that never happened) while using the device as a desktop. It was a bit disorienting at first, I had forgotten that I was running the desktop the Nexus 4, so when a notification of an incoming call popped up on the screen I didn’t know what was happening. That only lasted a second though, and after clicking answer and picking up the device, I just used it as a phone. Pretty cool

screenshot20160701_151104996

Must go faster

While I was able to do pretty much all of my work that day thanks to my phone, it wasn’t always easy or fun, and I’m not ready to give up my laptop just yet. The Nexus 4 is simply not powerful enough for the kind of workload I was putting on it. But then again, it’s a nearly 4 year old phone, and wasn’t considered a powerhouse even when it was released. The newest Ubuntu phone on the market, the Meizu Pro 5, packs a whole lot more power, and I think it would be able to give a really nice desktop experience.

Read more
facundo

Europython, otra vez


La semana que viene se hace la mayor conferencia de Python de Europa, la Europython. Esta vez es en Bilbao.

Es larga. El domingo hay un día de tutoriales y cursos para principiantes. La conferencia en sí es de lunes a viernes. Y sábado y domingo de la otra semana hay sprints. Pueden ver el schedule online.

alt

Lo que más me entusiasma de esta edición de la conferencia es que voy a ir, :). No es la primera vez que voy, sin embargo; vuelvo luego de once (sí, 11) años de ausencia!!

No sé si me sorprende más eso o que mi blog ya es tan viejo que tengo registro de eso que pasó hace tanto: en estos cuatro posts.

Ahora que lo pienso, hace *años* que tampoco voy a una PyCon US (la default, digamos)...

La frutilla del postre es que esta vez voy a presentar dos charlas, en dos idiomas. En castellano va mi repetidísima "Entendiendo Unicode" (el público se renueva, me dicen algunos; dejá de robar, me dicen otros). Y en inglés la versión anglosajona de la charla que preparamos con joac para la PyCon pasada: "No es magia: Descriptores al desnudo".

Ya les iré reportando como va todo :)

Read more
Daniel Holbach

Distributing software has never been easier. snapcraft makes it easy to build any kind of app, snapd and snap-confine bring security and hassle-free updates. Maintaining the app in the store is simple and you get lots of flexibility with different release channels.

If you’re interested or curious, adding your software to the Snappy Playpen, might be a good first step. Tomorrow, Tuesday 12th July 2016, we are working together on getting more snaps landed, getting things improved, updating our docs, helping out the snapd/snapcraft people, and upstreaming snaps.

It’s easy to get in touch, we are both hanging out in

We are looking forward to seeing you there.

Read more
David Callé

If it hasn't already, snapd 2.0.10 should be making its way to your 16.04 systems. Here is what’s new!

The 2.0.10 release contains a number of improvements and fixes over the 2.0.9 release that was available before. The highlights:

Channels

Channels (stable, candidate, beta, edge) usage has been streamlined on the client.

As a shorthand to --channel=<channel>, you can now use --<channel> with the refresh and install commands.

For example:

2027ba20a6d8c6adad917f1b47bc6df3feed300c.png

Interfaces

New interfaces have landed with this release, giving you more freedom to interact with the OS, while keeping your app into the bounds of the existing confinement. This allows, for example, for improvements in the VLC snap’s user experience.

Screenshot from 2016-07-11 13-35-02.png

mpris (new)

  • Allows snaps such as music players to connect to D-Bus as an MPRIS server.
  • You can see an usage example in the VLC snapcraft.yaml.

camera (new)

optical-drive (new)

  • Grants read access to optical drives.

home

  • Allow gvfs shares in home.

General

  • Snaps can be launched under KDE Neon

  • SNAP_COMMON and SNAP_USER_COMMON are paths to unversioned data directories

  • Better handling of removed `snap try` directories

  • Fixes towards running snapd inside LXC

  • `snap change <taskid>` shows task progress

  • Auto-connect the home interface only if running on classic

The changelog is available here and the full details can be found here: https://github.com/snapcore/snapd/tree/2.0.10

Let us know what you think!

We’d like to hear your feedback about snapd and snap technologies. Is there an interface you would need for your app to be working better? Can we do better with integrating with a particular distro? Here’s how we can talk:

Read more
facundo


La primera vez que probé cerveza de trigo, fue en Bruselas. No soy fan, las esquivo, cada tanto vuelvo a probarlas, though.

Esta foto la saqué en el bar del hotel, estaba charlando con "el John".

Cerveza de trigo

Para más detalles de ese viaje de laburo: uno, dos tres.

Read more
Steph Wilson

photo_2016-07-08_13-59-27

You can now follow us on Dribbble and Behance for design inspiration.

See things like: the Ubuntu #reinvent digital campaign, Juju embeddable card and Suru app icon designs.

Follow us :)

Read more
Inayaili de León Persson

Getting Vanilla ready for v1: the roadmap

We have been using our front end framework Vanilla across our sites for a while now, so it might surprise you to know that its first official version (let’s call it v1) hasn’t yet been released.

In preparation for v1 (which we are tentatively aiming for early September), there are a few tasks that we have been, and will be, working on to make sure that Vanilla is as robust as we can make it, and to make the process of using and improving it clear.

Future-thinking: defining a high level roadmap

It’s important that long-term, ongoing projects have defined goals that people can focus on and strive for. Having short, mid and long-term goals makes it easier to prioritise and concentrate efforts on tasks that will get you closer to achieving the ultimate vision for the project.

The first thing we did in order to outline a roadmap for Vanilla was to collect all the things that we felt needed to happen for it to be ready for release, things we’d like to improve, and wishlist items that might not be urgent but that we would like to tackle at some point in the future.

With this list at hand, we organised the tasks by priority and added them to a roadmap board in Trello, which is open for anyone to have a look at. You can see which tasks we are working on during the current two-week sprint, and which tasks are queued to be done next.

 

Vanilla roadmap in TrelloThe Vanilla framework roadmap Trello board

 

Contributing: defining the process for adding new patterns

Releasing Vanilla v1 does not mean that Vanilla will then be finished. As a working style guide that is used across Canonical on various different projects with different needs, new patterns will emerge and existing ones will have to be improved to be more flexible.

We thought that it would be good to document the process that a pattern should follow in order to become a Vanilla pattern, so after a little bit of brainstorming, we created a diagram that shows the different steps that should be taken from before submitting a pattern proposal to its full acceptance as a Vanilla pattern.

Most of the steps in the diagram happen in just a few seconds, but it is good to be able to visualise the entire process.

 

Vanilla process diagramDiagram of the process to submit a new pattern to Vanilla

 

As Vanilla itself, this process diagram is not really finished. Once we start using it more frequently, we will probably have to make some adjustments to improve it. Also, there are a few branches of the process that we still need to include, namely how a pattern is added to a theme as opposed to the main Vanilla framework, and how an existing pattern (in a website of Vanilla theme) can be promoted to Vanilla.

As part of this task, we also updated the existing GitHub template that pops up when you submit a new issue on the Vanilla repository to include the option of submitting a pattern proposal.

The proposals will be reviewed on a fortnightly basis by the web team during the Vanilla working group meetings. We are pondering how we can make these meetings open to anyone who’d like to participate, as we know that lots of you would like to contribute with new patterns and improvements. We’d be happy to hear your ideas on how this could work.

Defining browser support guidelines

While internally, in the web team, we tend to agree on and follow consistent browser support guidelines, the process isn’t documented.

We want to make sure that Vanilla is built following the latest web standards, and that people can build sites with it that will work on as many form factors as possible, so we thought defining the browser support guidelines that we want contributors to follow was a vital step in preparation for the v1 release.

The document isn’t yet finished, but we are working on it as we speak and will be sharing it soon enough.

Future tasks

You can see the roadmap that we have planned for Vanilla in preparation for v1 and after in Trello, but there are few key tasks that we want to carry out before September that we’d like to highlight:

  • Defining the accessibility standards that all patterns will have to follow, and adding automated tests to the build process to ensure they are adhered to
  • Conducting an internal accessibility audit and making as many changes as we can to improve accessibility
  • Redesigning the dedicated Vanilla website to include the new documentation we are writing and other pieces of useful information, including the style guide itself — all living together in one single site
  • And, obviously, making sure that Vanilla has its own logo — as any respectable framework does :)

Final words

This is all from me for now! Barry is writing a companion post that will go into more detail about the technical tasks that are being done on Vanilla, which he will be publishing soon.

We would love to know if you have any ideas on how to improve Vanilla — share your thoughts in the comments.

Read more

Thinking about writing an Ubuntu application that will work in Unity 8? You’ll be writing a “convergent” app, which is an application that can respond to touch or mouse, and will adapt appropriately to a phone, tablet, or desktop screen. It will even be able to update its display on-the-fly if, say, you plug your phone into a monitor or bluetooth keyboard.

There are lots of ways to write a convergent application with the Ubuntu SDK. You can build apps in pure QML, C++ with QML, QtQuick, pure HTML5/Javascript, or even Golang with QML. We’ll be focusing on go apps for the rest of this post.

Go is a young language, and the recent release of go 1.6 has introduced some nasty changes particularly involving cgo. It has also introduced vendoring by default, which is a welcome change.

I’m using go 1.6.2. For me, the current project template provided by the Ubuntu SDK feels quite broken. I can’t get things to build locally, and furthermore I see no options for pushing an ARM build to my device.

Fortunately, I found this ubuntu-go-qml-template which is a template to enable running/building a go/qml application locally while also supporting building/installing onto an arm device. The kicker? This tool was designed to work for go 1.3.3. Sigh! Since I’m unwilling to compromise and use old technology, I forked the project and updated it to fit my more modern needs.

Because our go template will depend on QML, we depend on the go-qml project to create the necessary C bindings to allow us to use QML. However, with the update to go 1.6, the current version (revision 2ee7e5f) of go-qml will give a runtime error from cgo with the wonderfully helpful panic: runtime error: cgo argument has Go pointer to Go pointer. Another thorn in our side. Fortunately, this issue is in previously tread-upon ground and there is a fork of go-qml with enough of the cgo issues fixed to run our application with no problems. In the ubuntu-go-qml-template I forked above, I’ve gone ahead and vendored this fork of go-qml. It all works because of the default vendoring available in go 1.6.

With that background out of the way, let’s run through getting a project started:

1
2
3
4
5
6
7
8
9
10
11
$ sudo apt-get install golang g++ qtdeclarative5-dev qtbase5-private-dev \
                       qtdeclarative5-private-dev libqt5opengl5-dev \
                                           qtdeclarative5-qtquick2-plugin
# installing dependencies...
$ git clone https://github.com/larryprice/ubuntu-go-qml-template.git your-project-name
# cloning repo...
$ cd your-project-name
$ chroot-scripts/setup-chroot.sh
# building a chroot for ubuntu-sdk-15.04
# distro=vivid, arch=arm
# with go 1.6.2 with armhf compilation support

You may need to have other dependencies including click or phablet-tools. The above commands installed dependencies, cloned the repo, and built and/or updated a chroot for building our source for arm.

Next you’ll want to setup the project for your own needs. The original template creator included a nifty setup script to get this done:

1
2
$ ruby setup.rb -v -n your-project-name -a "Your Name" -e "your.email@example.com" \
                   -d "your-developer-namespace"

This will do some fancy gsub and file renaming to make the template your own.

If you check src/, you’ll find a main.go file ready for your use. You’ll also find a main.qml file in share/qml/. You can vendor all of your dependencies in vendor/, where you’ll already find the qml package.

As far as getting your application to work, there are more scripts available:

1
2
3
4
$ ./build.sh
# this will build your project locally
$ ./run.sh
# this will build your project locally and then run it on the desktop

The best part about this template is the ability to build for arm and load your applications onto a device:

1
2
3
4
5
$ ./build-in-chroot.sh
# builds the package using the vivid+armhf chroot we set up previously
$ ./install-on-device.sh
# builds for vivid+armhf and installs the click directly on
# the first USB-connected Ubuntu Touch device

Now you can run and install go/qml applications on desktop or on devices. Time to go build something cool!

Disclaimer: In the future, this template will likely need to be updated for new go versions or new default versions of the Ubuntu SDK. Don’t be afraid to make a comment below or submit a PR.

Read more
kevin gunn

Snap on Unity8 classic

I wanted to provide a quick guide for those who might be tinkering around with snaps. This is a demonstration for developers interested in the ability to create snaps of their applications as well for Unity8, analogous to the experience of snaps on classic Ubuntu on Unity7, as outlined at https://developer.ubuntu.com/en/desktop/get-started/. These instructions assume you’ve already installed and experienced ubuntu-core, the ubuntu-snappy-cli, installing and running snaps on Unity7. You should also be running an up-to-date Ubuntu 16.04 system, since there are updates consistently being made to snapcraft and snapd.

In following this guide you’ll eventually run ubuntu-clock-app as the demonstration. In order to avoid confusion, ensure you do not have the clock application installed on your ubuntu-core from previous experimentation. The reason for this is that ubuntu-clock-app in the store assumes it is running on an X11 based system, but the snap we are going to build and install here assumes it is running on a Mir based system and there is no X11 in the Unity8 session. So before we begin, while logged into your Unity7 session run the following:

 

$ sudo snap remove ubuntu-clock-app

 

If you haven’t already, you need to install the unity8-desktop-session-mir package and add ppa:ci-train-ppa-service/stable-phone-overlay (the addition of the ppa is in order to keep up to date with the latest Unity8, UI toolkit and Mir changes that are being regularly released for the phone).

Note1: we are in the process of SRU’ing a change to Unity8-desktop-session-mir that will automatically add the PPA, but for now this is required as the SRU process will take time.

Note2: you must be using free graphics drivers for the unity8-desktop-session-mir, for instance if you are on an Intel gpu you will have no problems, if you are on an AMD gpu you will need radeon, if you are on Nvidia you will need Nouvea.

Open a terminal and run the following commands:

 

$ sudo apt-add-repository ppa:ci-train-ppa-service/stable-phone-overlay

$ sudo apt-get update

$ sudo apt-get dist-upgrade

$ sudo apt-get install unity8-desktop-session-mir

 

At this point, you should be able to log out of your Unity7 session and toggle the greeter icon to Unity8 and login. Once in your Unity8 session, you can navigate to the Ubuntu Store scope on the Dash via the Apps scope. Search for the terminal app and install it.

NOTE: i’m trying to get the terminal app updated in the store to be a “fat package” which means working for both amd64 and armhf architectures. Until then you can find and install the terminal app from http://people.ubuntu.com/~mhall119/dogfooding-unity8/ per the instructions in this post http://mhall119.com/2016/05/dogfooding-unity-8/

 

Open up the terminal app to download the ubuntu-clock-app source that has relevant snapcraft files and modifications to support running on the Unity8-Mir system. If you want to see the what modifications I had to add you may compare the branch we’ll be building, lp:~kgunn72/snappy-desktop-exmaples/try-mir-take1 to lp:snappy-desktop-examples . The modifications are mainly that the snap needs to contain the qtmir plugin since Unity8 is running on the Mir stack for graphics and X11 is not running.

 

You’ll notice on the installation step we install with –devmode, as we are just now in the process of creating the interfaces for Unity8 and Mir. Running in –devmode means that the application is not confined. Then enjoy building and running the snap:

 

$ bzr branch lp:~kgunn72/snappy-desktop-examples/try-mir-take1

$ cd ./try-mir-take1/ubuntu-clock-app

$ snapcraft

$ sudo snap install ubuntu-clock-app*.snap –devmode

 

OK congrats, you’ve built a snap for an application that runs on unity8. There is one bug (https://bugs.launchpad.net/ubuntu/+source/unity8-desktop-session/+bug/1590439) that we need to account for to add /snap/bin to our path. But once done, you should be able to launch the app.

 

$ export PATH=$PATH: /snap/bin

$ ubuntu-clock-app.clock

Hope you enjoyed this exercise. In theory this could be applied to any application that might have been created for the Ubuntu phone. We’ll be working to make this process less manual over time.

Read more
Daniel Holbach

Zygmunt Krynicki wrote about the availability of bite-sized bugs for the snapd project.

I took this as an opportunity to go through the snapcraft bugs as well and tag a few as bitesize myself. snapcraft is written in python, nicely commented documented and comes with a comprehensive test-suite. The people working on it are a lovely bunch and very helpful. So if you are interested in publishing software and have some knowledge in how a certain class of projects is built, you could do a lot of good here.

If you can’t write python or go (for snapd) code, that’s fine – there are lots of other ways to help out:

This is an exciting time for Ubuntu and other distributions – we’re making software much more easily available.

Read more
Didier Roche

Background

Integrating desktop applications with snaps has been a little bit challenging in terms of getting them looking and behaving as part of the system. This means following general desktop theming, having global application menu integration, getting the icon caches, getting configuration keys and such. Also, the technologies and toolkits like GTK, Qt, demand a little bit of expertise on that front.

That's the reason why we saw flourishing some desktop helpers like gtkconf or qtconf as cloud snapcraft parts for this. However, they were sharing little code and some part of the integration was working for one flavor and not the other flavor and vice-versa.

New desktop launchers to the rescue!

This is the reason why we are announcing new destkop launchers! The goal was to streamline the experience and ensuring that all following user visible features are working, independent of the toolkit or technology you are using:

  • Bind with current desktop theme if shipped by default (GTK & Qt)
  • Icons theme available for decoding (with the right decoders automatically shipped)
  • Application menu integration (in Unity)
  • Icon cache and images generated on first launch (no more need to ship pre-compile GSettings and Gio caching modules) after a new upgrade
  • Keep previous xdg-based data, even after upgrade
  • GSettings keys available for reading (not only writing)
  • Most of the code is shared between the launchers, so any fix in one will benefit others, and we assemble them at build time.
  • Avoid erratic behavior like cd $SNAP that some launchers were doing and not others (we don't change the current working directory anymore)

Ristretto before applying desktop/gtk3     Ristretto with desktop/gtk3

Those new cloud parts also ship with default package set configuration to ensure all features are enabled, this is overridable as well, as explained by Sergio in his blog post.

Qt-based applications also show those drastic improvements. Note that the appmenu fix for Qt applications will only work starting with snapd 2.0.10.

SMPlayer before using desktop/qt5   SMPlayer using desktop/qt5

Definition and usage

We currently have 5 launchers, depending on the technology you want to support: gtk2, gtk3, qt4, qt5 and glib-only for a lightweight, non graphical app, but needing basic integration like GSettings and MIME types.

Those are grouped under the "desktop" namespace from the snapcraft cloud part functionality, with extensive help on how to use them:

$ snapcraft define desktop/qt5
Maintainer: 'Snapcraft community <snapcraft@lists.snapcraft.io>'
Description:  |
  Helpers for gtk2, gtk3, qt4 and qt5 or glib minimal launchers.
  It brings the necessary code and exports for binding and using those
  desktop technologies in a relocatable fashion, enabling binding with
  global desktop theme, icon theme, image caching, fonts, mimetype handlers
  application global menu and gsettings integration.
  It also brings basics ubuntu dependency packages.
  .
  Usage:
    1. add "after: [desktop/<technology>]" to your launcher:
       - gtk2, gtk3, qt4 and qt5 corresponds to their respective toolkit
         main dependencies and default choices.
       - glib-only enables to compile mime types and gsettings infos. If you
         added your own graphical drivers, it will link them as well.
    2. prepend your command with "desktop-launch", like:
       commands: "desktop-launch foo" if foo is in $PATH. You can as well
       specify: "desktop-launch $SNAP/foo".
    3. add needed plugs to your application:
       - for graphical application:
         plugs: [x11 (or unity7 for appmenu integration)]. Think about adding
         opengl if you need hw acceleration.
       - if your application needs access to sound:
         plugs: [pulseaudio]
       - accessing to user's home directory:
         plugs: [home]
       - read/write to gsettings:
         plugs: [gsettings, home]
         (note that the home plug is needed to read new value)'
desktop/qt5:
  build-packages:
  - qtbase5-dev
  - dpkg-dev
  make-parameters:
  - FLAVOR=qt5
  plugin: make
  source: https://github.com/ubuntu/snapcraft-desktop-helpers.git
  source-subdir: qt
  stage-packages:
  - libxkbcommon0
  - ttf-ubuntu-font-family
  - dmz-cursor-theme
  - light-themes
  - shared-mime-info
  - libqt5gui5
  - libgdk-pixbuf2.0-0
  - libqt5svg5
  - appmenu-qt5

(Note that the descriptions are for now common to any namespaces launchers)

Migrating from gtkconf/qt4conf/qt5conf

As part of this journey, I wanted to see this applied in the real world and migrated all snappy playpen examples to this new launchers. I was delighted to see that some of the goals, like having smaller snapcraft.yaml was a success. Also, broken examples are now fully integrated to the desktop (see some of the pictures above).

Migrating is the existing gtkconf/qt4conf/qt5conf (we plan to deprecate them after a while) is a 2 minutes job:

  1. Replace: after: [<xxx>conf] with after: [desktop/<xxx>] where <xxx> is the targeted toolkit.
  2. Change command: gtk-launch (or qt-launch) foo with commands: desktop-launch foo. For simplicity, all launchers are now called "desktop-launch". Note that foo needs to be in $PATH for your snap, if it's not, replace it to $SNAP/foo.
  3. You can (not mandatory) clean up any build-packages or stages-packages that are shipped and expose in the desktop launcher definition.

By following those simple steps, you can get from an unthemed, no matching icons and no appmenu VLC to a fully integrated one!

Happy snap desktop integration! :)

Read more
David Planella

Shaping up universal snaps

Following the announcement of snaps being supported across a range of key Linux distributions, the development teams working on snaps and Snapcraft are making universal snaps one of the main topics of their next sprint in Heidelberg, Germany, from 18-22 July.

Snappy sprints are face-to-face events where multiple teams working on snap technologies, including Ubuntu founder Mark Shuttleworth, get together to plan, design and develop their next release and longer term roadmap. After the initial positive reception amongst initial adopters, tech media and wider open source community, continuous improvement of the snap user and developer experience is a major focus.

A number of upstreams, contributors and developers of leading open source projects such as DebianElementary OS, Fedora, KDE, Kubuntu, MATE or VLC have already confirmed participation at the sprint to collaborate on better distro-agnostic snap support.

At this point, we'd like to extend this invitation to contributors of other projects to influence the roadmap and work together on shaping up the universal snaps story. If you are interested in participating, we have a limited amount of seats available at the sprint, subject to review and confirmation. Should they need it, sponsorship for travel and accommodation will be available for a set of contributors of upstreams, distros or desktop projects who are willing to actively work towards this goal.

If the answer is yes, feel free to apply for participation and sponsorship to the Heidelberg snappy sprint

Please note that a sprint is not a tech conference: it is a set of focused working and planning sessions where the snappy Engineering team execute work items and plan the next iteration of snapd and Snapcraft. Attendees will be expected to actively participate in discussions and decision making and be willing to take work items where appropriate.

Also do note that while all contributions are valuable, we have a limited capacity to sponsor participants and we cannot support everyone. As such, sponsorship will be subject to review and final confirmation. Once the requests are in, we will review all of the applicants and contact you as soon as possible to let you know if your request for sponsorship has been approved.

It will be a great chance to build together app distribution across platforms and we’ll be looking forward to working with you!

Read more
karlwaghorn-moyce

Vancouver sprint recap: MAAS and Juju

This was my first cycle sprint within the Cloud design team and my first time to Vancouver, Canada #winner

Having only been with Canonical for 8 weeks and working closely my fellow design colleagues, it was a great opportunity for me meet and collaborate with product engineers working around the world.

Not only was it great to meet engineers but also to sit in meetings with them and learn more about our products, giving me further insight and understanding into MAAS. Discussing new features, sketching, presenting and planning during the week really helped us to evolve our thinking about what we plan to deliver in the next few months. I also had the chance to showcase recent designs and get feedback from a variety of people across different areas of the business.

An exciting new project I worked on whilst at the sprint was Snapcraft.io, a tool that enables you to deliver and package your app to any Linux desktop or cloud server. I was given the task of creating a micro website promoting this tool and showcasing how easy it is to use to setup your app.

But it wasn’t just all #workworkwork… as the evenings gave us opportunity to socialise and get to know different people and explore the city of Vancouver.

It’s an exciting time to be at Canonical with big product releases on the horizon. I’m looking forward to our releases of MAAS 2.0 and Juju 2.0!

Below are some photos of our week in Vancouver. Enjoy :)

Vancouver sprint

Vancouver sprint

Vancouver sprint

Read more
Joseph Williams

Juju Lithuania sprint recap

Last month the Juju design team was away in Lithuania, Vilnius on a working sprint. We met up with the distributed development team to help tackle technical and design issues.

These sprints take away the barrier of time zones — which usually make it harder to ask engineers questions about features that are being designed.

13616221_10209952745325460_1919613808_o

Everyday started with a run down of the workshops and discussions that would happen on that day. This made sure everyone was aware and welcome (and very much encouraged) to join the sessions and give their valuable insight or just widen their knowledge of the product.

13589133_10209952745245458_1275611017_o

The day would then play out in an enjoyable whirlwind of knowledge, clarity and alarming amounts of progress as queries would be answered in real time without the assistance of an email client or a hangout session.

At lunch time the Juju team took the fantastic opportunity to explore the city. Walking the cobbled streets and enjoying the vast range of foods from a variety of different cultures. While we were there we ate everything from classic Lithuanian cuisine to a big shared spread of Mexican food.

13616195_10209952745285459_595293251_o

At the end of the day we would go through all of the things which were accomplished and have lightning talks (short presentations of work to the rest of the team) about the work that had been completed. This is a fantastic exercise for design as it lets us show wireframes, prototypes, research or just flat visuals for the features that are being implemented within Juju and gives the engineers a chance to see and discuss the work directly with the designers. Lightning talks are also great for engineering as they can show features that are under development or just talk through the back end of the solution.

This has been my fourth sprint with Canonical and they never cease to be valuable as they promote collaboration, forward thinking and team bonding. I look forward to the team’s next adventure and the challenges that we will conquer.

Read more
UbuntuTouch

由于Ubuntu手机平台安全的限制,在Ubuntu手机的应用中我们只能访问自己的空间.如果我们所需要访问的文件不存在于我们应用所在的空间,我们是没有办法访问到的.我们的应用只能访问系统提供的库.如果系统没有所需要的库的话,我们通过可以通过如下的方法实现:

  1. 在我的应用中把应用的所需要的第三方的源码放入到我的应用项目中,并形成plugin(通常是C++代码)从而被应用调用
  2. 在我们的应用中把第三方的库打包进我们的应用包中,并在我的plugin(通常是C++代码)中调用,进而被应用调用
我们可以选择Ubuntu SDK所提供的标准的带有C++ plugin的模版来实现.对于第二种情况,我们同样需要在我们的项目中加入所需要的文件,并打包到我们的应用中去.第二种方法对于一些不存在于Ubuntu SDK所提供的标准库里的情况是非常有用的.比如我们可以得到PDF reader的库的源码,并编译成为我们自己的库.最终我们可以把这些库一起打包并安装到我们的手机中使用.

在今天的这篇文章中,我们就第二种方法来详细介绍.


1)创建一个最小的shared库


我已经创建好了一个最基本的shared库.开发者可以通过如下的方式来下载我们的代码:

$ git clone https://github.com/liu-xiao-guo/studentlib_shared

我们的这个库非常地简单:

Student.h

#include<string>

class Student{
private:
	std::string name;
public:
	Student(std::string);
	virtual void display();
};

student.cpp

#include <iostream>
#include "Student.h"
using namespace std;

Student::Student(string name):name(name){}

void Student::display(){
	cout << "A student with name " << this->name << endl;
}

接下来,我们以armhf chroot为例,当然我们也可以对i386使用同样的方法.我们通过我们已经安装好的armhf chroot来编译我们的这个库.首先我们通过如下的方式进入到我的chroot:

$ click chroot -aarmhf -fubuntu-sdk-15.04 run  

当我们进入到我买的chroot中后,我们就可以开始编译我们的应用库了.我们进入到我们的项目的根目录中,并打入如下的命令

$ mkdir build
$ cd build 
$ cmake ..
$ make

这样在我们的build子目录下就可以看到我们希望的库了.

 

(click-ubuntu-sdk-15.04-armhf)liuxg@liuxg:~/qml/studentlib_shared/build$ ls
CMakeCache.txt  CMakeFiles  Makefile  cmake_install.cmake  libtestStudent.so
(click-ubuntu-sdk-15.04-armhf)liuxg@liuxg:~/qml/studentlib_shared/build$ 


2)创建一个带有plugin的最基本的应用.


我们选择"QML App with C++ plugin (qmake)"模版来创建一个最基本的testplugin应用.在这个应用中,我们将展示如何使用我们上面已经创建好的shared库.



接下来,我们修改我们的mytype.cpp及mytype.h文件:

mytype.h


#ifndef MYTYPE_H
#define MYTYPE_H

#include <QObject>

class MyType : public QObject
{
    Q_OBJECT
    Q_PROPERTY( QString helloWorld READ helloWorld WRITE setHelloWorld NOTIFY helloWorldChanged )

public:
    explicit MyType(QObject *parent = 0);
    Q_INVOKABLE void testlib();
    ~MyType();

Q_SIGNALS:
    void helloWorldChanged();

protected:
    QString helloWorld() { return m_message; }
    void setHelloWorld(QString msg) { m_message = msg; Q_EMIT helloWorldChanged(); }

    QString m_message;
};

#endif // MYTYPE_H

mytype.cpp

#include "mytype.h"
#include "Student.h"

MyType::MyType(QObject *parent) :
    QObject(parent),
    m_message("")
{

}

void MyType::testlib()
{
     Student student("johnddfsfdfdfds");
     student.display();
}

MyType::~MyType() {

}

在上面的代码中,我们已经使用了我们shared库中的display()方法.如果这个时候我们去运行我们的应用的话,我们会发现我们的应用肯定是有错误的.这是因为它根本找不到它所需要的库.在下面我们来尝试把我们的库打包到我们的项目中来.

我们首先在我们的项目中创建一个叫做libs的目录,并把我们的shared库考入到这个目录中.这样整个的项目的目录就像:

liuxg@liuxg:~/qml/testplugin$ tree -L 3
.
├── backend
│   ├── Testplugin
│   │   ├── backend.cpp
│   │   ├── backend.h
│   │   ├── mytype.cpp
│   │   ├── mytype.h
│   │   ├── qmldir
│   │   └── Testplugin.pro
│   └── tests
│       └── unit
├── libs
│   ├── libs.pro
│   ├── libtestStudent.so
│   └── Student.h
├── manifest.json.in
├── po
│   └── testplugin.liu-xiao-guo.pot
├── testplugin
│   ├── Main.qml
│   ├── testplugin.apparmor
│   ├── testplugin.desktop
│   ├── testplugin.png
│   ├── testplugin.pro
│   └── tests
│       ├── autopilot
│       └── unit
├── testplugin.pro
└── testplugin.pro.user

在上面的显示中,我们可以看到在libs目录中除了一个我们看到的那个libtestStudent.so及header文件外,还有一个叫做libs.pro的文件.它的内容如下:

libs.pro

TEMPLATE = lib

load(ubuntu-click)

filetypes = qml png svg js qmltheme jpg qmlproject desktop wav so

OTHER_FILES = filetypes

for(filetype, filetypes) {
  OTHER_FILES += *.$$filetype
}

other_files.path = $${UBUNTU_CLICK_PLUGIN_PATH}
other_files.files = $$OTHER_FILES

INSTALLS += other_files

message(The project1 will be installed in $${UBUNTU_CLICK_PLUGIN_PATH})

在上面的文件中,我们可以通过上面的方法把我们需要的.so文件拷入到我们所需要的目录中.

最后在我们的"testplugin.pro"文件中需要加入我们的目录"libs".

SUBDIRS += testplugin \
           backend/Testplugin \
           libs

在我们的"TestPlugin.pro"中,我们需要加入如下的句子:

LIBS += -L$$PWD/../../libs/ -ltestStudent
INCLUDEPATH += $$PWD/../../libs
DEPENDPATH += $$PWD/../../libs

在我们的QML文件中,我们是这样来调用的:

Main.qml

        ...
        Button {
            anchors.centerIn: parent
            text: "Test lib"

            onClicked: {
                myType.testlib();
            }
        }
        ...

最终,我们来编译并部署我们的应用到我们的手机上:



我们可以查看在我们手机中的安装文件.在我们的desktop中打入如下的命令:

$ adb shell

通过上面的命令进入到手机中,并进入到如下的目录:

/opt/click.ubuntu.com/testplugin.liu-xiao-guo/current/lib/arm-linux-gnueabihf/

我们可以看到我们所需要的文件已经被成功安装到该目录中:




当我们点击在应用中的按钮"Test lib"时,我们可以在我们的SDK IDE中看见输出:



上面输出的字符串就是我们利用我们的库来输出的:

     Student student("johnddfsfdfdfds");
     student.display();

整个项目的源码在https://github.com/liu-xiao-guo/testplugin


作者:UbuntuTouch 发表于2016/5/9 11:28:37 原文链接
阅读:1332 评论:0 查看评论

Read more
UbuntuTouch

在这里,我来展示一个使用QML来做单位转换的例程:


Main.qml


/*
 * Copyright 2012 Canonical Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; version 3.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

import QtQuick 2.4
import Ubuntu.Components 1.3
import "conversion.js" as Converter

/*!
  \brief Example unit converter application.

  The application demonstrates the usage of
    - i18n
    - units
    - Label
    - Tabs
    - Tab
    - Page
    - ToolbarActions
    - Action
    - TextField and
    - Button components

  The application converts length and weight units between several metrics.
  Related units are grouped in the same page (Tab) and conversion happens when
  pressing Enter/Return after entering a number in one of the input fields (i.e.
  accepting the entered text), or by pressing the "Convert" button.

  The navigation between converter pages is provided by the Tabs component.
*/

MainView {
    id: root
    // objectName for functional testing purposes (autopilot-qt5)
    objectName: "mainView"
    
    // Note! applicationName needs to match the .desktop filename
    applicationName: "unit-converter"
    
    /*
     This property enables the application to change orientation
     when the device is rotated. The default is false.
    */
    automaticOrientation: true
    
    width: units.gu(100)
    height: units.gu(75)

    property real margins: units.gu(2)
    property real labelWidth: units.gu(12)

    // Length conversion model; the unit is Mile
    property var lengthModel: [
        {"unit": "Inch", "rate": 63360.0},
        {"unit": "Meter", "rate": 1609.344},
        {"unit": "Miles", "rate": 1.0},
        {"unit": "Feets", "rate": 5280.0},
        {"unit": "Yards", "rate": 1760.0},
        {"unit": "Kilometers", "rate": 1.609344},
    ]

    // Weight conversion model; the base unit is Pound
    property var weightModel: [
        {"unit": "Pounds", "rate": 1.0},
        {"unit": "Kilograms", "rate": 0.45359237},
        {"unit": "Ounces", "rate": 16},
        {"unit": "Stones", "rate": 0.0714285714},
        {"unit": "US Tons", "rate": 0.0005},
        {"unit": "UK Tons", "rate": 0.000446428571},
    ]

    // converter page template
    Component {
        id: pageContent
        Page {
            // expose Repeater's model for reusability, so we can set it from
            // outside, when we build the tabs
            property alias model: converter.model

            // remove the input panel when pressed outside of any text input
            MouseArea {
                anchors.fill: parent
                onPressed: Qt.inputMethod.hide();
            }

            Flickable {
                id: flickable
                anchors {
                    fill: parent
                    margins: root.margins
                }
                flickableDirection: Flickable.VerticalFlick
                contentWidth: pageLayout.width
                contentHeight: pageLayout.height
                Column {
                    id: pageLayout
                    width: flickable.width
                    height: childrenRect.height

                    spacing: units.gu(1.2)
                    // show as many lines as many units we have in the model
                    // it is assumed that the model has "unit" and "rate" roles
                    Repeater {
                        id: converter
                        Row {
                            spacing: units.gu(1)
                            Label {
                                text: i18n.tr(modelData.unit)
                                textSize: Label.Large
                                width: root.labelWidth
                                height: input.height
                                verticalAlignment: Text.AlignVCenter
                            }
                            // input field performing conversion
                            TextField {
                                id: input
                                //errorHighlight: false
                                validator: DoubleValidator {notation: DoubleValidator.StandardNotation}
                                width: pageLayout.width - root.labelWidth - spacing
                                text: "0.0"
                                font.pixelSize: FontUtils.sizeToPixels("large")
                                height: units.gu(4)
                                // on-the-fly conversion
                                onTextChanged: if (activeFocus) Converter.convert(input, converter, index)
                                onAccepted: Qt.inputMethod.hide()
                            }
                        }
                    }
                }
            }

            head.actions: Action {
                objectName: "action"
                iconName: "clear"
                text: i18n.tr("Clear")
                onTriggered: Converter.clear(converter)
            }
        }
    }
    
    Tabs {
        id: tabs
        
        // First tab begins here
        Tab {
            objectName: "Tab1"
            
            title: i18n.tr("Lengths")
            
            // Tab content begins here
            page: Loader {
                sourceComponent: pageContent
                onStatusChanged: {
                    if (status === Loader.Ready && item) {
                        item.parent = parent;
                        item.model = lengthModel;
                    }
                }
            }
        }
        
        // Second tab begins here
        Tab {
            objectName: "Tab2"
            
            title: i18n.tr("Weights")
            page: Loader {
                sourceComponent: pageContent
                onStatusChanged: {
                    if (status === Loader.Ready && item) {
                        item.parent = parent;
                        item.model = weightModel;
                    }
                }
            }
        }
    }
}

运行我们的例程:

  

作者:UbuntuTouch 发表于2016/5/3 13:58:11 原文链接
阅读:264 评论:0 查看评论

Read more
UbuntuTouch

最近发现一个新的API叫做LayoutMirroring.运用这个API,我们可以在水平方向把我们的布局进行进行镜像显示.

我们还是先来看一个例子:


Main.qml


import QtQuick 2.4
import Ubuntu.Components 1.3

MainView {
    id: main
    // objectName for functional testing purposes (autopilot-qt5)
    objectName: "mainView"

    // Note! applicationName needs to match the "name" field of the click manifest
    applicationName: "layoutmirroring.liu-xiao-guo"

    width: units.gu(60)
    height: units.gu(85)

    LayoutMirroring.enabled: rtl
    LayoutMirroring.childrenInherit: true
    property bool rtl: Qt.application.layoutDirection == Qt.RightToLeft

    Page {
        id: page
        header: PageHeader {
            id: pageHeader
            title: i18n.tr("LayoutMirroring")
            StyleHints {
                foregroundColor: UbuntuColors.orange
                backgroundColor: UbuntuColors.porcelain
                dividerColor: UbuntuColors.slate
            }

            trailingActionBar.actions: [
                Action {
                    text: i18n.tr('Right to Left')
                    iconName: 'flash-on'
                    visible: !rtl
                    onTriggered: rtl = !rtl
                },
                Action {
                    text: i18n.tr('Left to Right')
                    iconName: 'flash-off'
                    visible: rtl
                    onTriggered: rtl = !rtl
                }
            ]
        }

        Row {
            anchors {
                left: parent.left
                right: parent.Right
                top: page.header.bottom
                bottom: parent.bottom
            }
            spacing: units.gu(1)

            Repeater {
                model: 5

                Rectangle {
                    color: "red"
                    opacity: (5 - index) / 5
                    width: units.gu(5); height: units.gu(5)

                    Text {
                        text: index + 1
                        anchors.centerIn: parent
                    }
                }
            }
        }

    }
}

在上面的例程中,我们在我们的MainView中使用了一个attached property: LayoutMirroring.当它的属性LayoutMirroring.enabled为真时,它使得我们的界面的UI布局将在在水平方向上从右向左布局.


运行我们的例程的效果:

 

当我们点击上面图中的闪电的图标时,我们会看见布局在水平方向发生改变,并变为从右侧开始的.当我们点击禁止闪电标志的图标时,就会恢复以前的布局.

作者:UbuntuTouch 发表于2016/5/4 10:08:01 原文链接
阅读:285 评论:0 查看评论

Read more
UbuntuTouch

细心的开发者可能在我先前的应用"Ubuntu文件浏览器 - 开发Scope/应用利器"已经看到过在我们应用的header的有上角位置上已经显示了一个ActionBar用来显示一排图标按钮供我们做出我们的选择.



事实上,我们也可以在我们的应用的其它位置也可以使用ActionBar.在今天的例程中,我们来展示如何利用ActionBar来实现我们所需要的一些功能.事实上,我们上面的Browser应用中,也可以在我们的"/"位置提供一个这样的ActionBar来选择不同的drive.当然这目前不在我们的考虑范围之内.

我们还是来看一下我们的例子:

Main.qml


import QtQuick 2.4
import Ubuntu.Components 1.3

MainView {
    // objectName for functional testing purposes (autopilot-qt5)
    objectName: "mainView"

    // Note! applicationName needs to match the "name" field of the click manifest
    applicationName: "actionbar.liu-xiao-guo"

    width: units.gu(60)
    height: units.gu(85)

    property list<Action> shortActionList: [
        Action {
            iconName: "share"
            text: "Share"
            onTriggered: {
                console.log("share is clicked")
            }
        },
        Action {
            iconName: "starred"
            text: "Favorite"
            onTriggered: {
                console.log("starred is clicked")
            }
        }
    ]

    property list<Action> actionList:  [
        Action {
            iconName: "alarm-clock"
            text: "Tick tock"
            onTriggered: {
                console.log("alarm-clock is clicked")
            }
        },
        Action {
            iconName: "appointment"
            text: "Date"
            onTriggered: {
                console.log("appointment is clicked")
            }
        },
        Action {
            iconName: "attachment"
            text: "Attach"
            onTriggered: {
                console.log("attachment is clicked")
            }
        },
        Action {
            iconName: "contact"
            text: "Contact"
            onTriggered: {
                console.log("contact is clicked")
            }
        },
        Action {
            iconName: "like"
            text: "Like"
            onTriggered: {
                console.log("like is clicked")
            }
        },
        Action {
            iconName: "lock"
            text: "Lock"
            onTriggered: {
                console.log("lock is clicked")
            }
        }
    ]

    Page {
        id: page
        header: PageHeader {
            id: pageHeader
            title: i18n.tr("actionbar")
            StyleHints {
                foregroundColor: UbuntuColors.orange
                backgroundColor: UbuntuColors.porcelain
                dividerColor: UbuntuColors.slate
            }
        }

        Column {
            anchors.centerIn: parent
            spacing: units.gu(3)

            ActionBar {
                // no numberOfSlots specified. Using default value.
                id: shortBar
                actions: shortActionList
            }

            ActionBar {
                id: bar
                numberOfSlots: 3
                actions: actionList
            }

            ActionBar {
                id: bar1
                actions: actionList

                StyleHints {
                    overflowIconName: "grip-large"
                    overflowText: "More"
                    defaultNumberOfSlots: 2
                }
            }
        }
    }
}
 
在这里我创建了三个ActionBar.第一个没有什么特别的.它显示连个并排的图标按钮.第二个ActionBar在图标比较多的情况下,它把多余的图标显示在一个Popup的菜单中.我们可以在ActionBar中定义可以最少显示的图标个数(numberOfSlots).在第三个ActionBar中,我们展示了如何去通过style的方式来修改/定制一个ActaionBar.运行我们的应用:

   


作者:UbuntuTouch 发表于2016/5/4 15:40:37 原文链接
阅读:333 评论:0 查看评论

Read more
UbuntuTouch

[原]Ubuntu SDK 安装介绍视频

最近我做了一个Ubuntu SDK的安装视频的介绍.如果有兴趣的朋友,请观看地址:


http://v.youku.com/v_show/id_XMTU1Nzg0NTI2NA==.html?from=s1.8-1-1.2

Ubuntu SDK安装

开发者也可以参阅我的文章"如何快速地安装Ubuntu SDK"得到更多的帮助.

作者:UbuntuTouch 发表于2016/5/5 9:46:13 原文链接
阅读:349 评论:0 查看评论

Read more