Search Results: "mitya57"

8 June 2023

Lisandro Dami n Nicanor P rez Meyer: Adventures in Debian's Qt land

Debian (I might as well say "we", this is the beauty of it) is about to release Debian 12 aka Bookworm. Let's take a quick look at what is new in Debian Qt land. Qt 5 Bookworm has Qt 5.15.8, which is nothing but great news. KDE will be switching to Qt 6 sooner than later and Qt 5 has been a fun ride, but Dmitry Shachnev and I needed a break, or at very least not handling two Qt versions. But in the end I need to be fair: you REALLY need to thank Dmitry for Qt 5. He has been the man power behind it in 99.5% of the cases. Qt 6 This will be the first Debian release to have official Qt 6 packages. NOTHING would have happened if it weren't for Patrick "Delta-One" Franz standing up to maintain it. BIG kudos to him! Well, there is a "little lie" in the paragraph above. Thanks to The Qt Company and ICS the current Qt 6 version, 6.4.2, is also available as Bullseye's backports. The Qt Company really also helped us here by providing us almost-to-be-released tarballs of Qt 6.4.2 so we were able to push them to unstable and do a transition in time for freeze, thanks a lot for that! So, what is the Qt 6 state? At the binary side all but OpenGL ES support should be there. Sadly this was discovered too late in the release process and we still might need help maintaining it (read the link to know why!). We are still not building the documentation. Properly building the whole documentation, as with Qt 5, would require all the Qt submodules' source code in one place, which we can't (easily?) do in Debian. So building the doc means hacking the build system and getting semi-linked documentation, much like with Qt 5. Now if you think you have an idea to solve this... we are happy to hear from you! Another great thing to know about Qt 6 is that, thanks to Helmut Grohne, pure Qt 6 applications should be able to cross compile. Applications using multi-arch enabled libraries ought to work too. Even more, many Qt submodules themselves should also cross compile! Not all of them, as we missed some patches in time, but hey, if you need to cross compile Qt, you surely can apply them yourselves! And finally tests, unit tests. In Qt 5 we had some of those, but none yet in Qt 6. This is one of the areas I would love to be able to put time... but time is scarce. The future? In my point of view the Debian 13 "Trixie" development cycle will see Qt 5 diminishing it's usage and Qt 6 becoming the major Qt version used, but from the Qt 4 experience I do not expect Qt 5 being dropped during this release cycle... let's see what the future brings us. Thanks! While I mentioned Dmitry and Patrick many more people helped us reach this place. I personally want to thank the people behind the KDE software, both upstream and, of course, the Debian maintainers. You should be thankful with them too, many hours of effort go into this. And thanks to you our dear users. We are normally overflowed with what we have in our hands and might not be up to the task sometimes, but hey, you are part of the reason we are doing this!

21 February 2021

Dmitry Shachnev: ReText turns 10 years

Exactly ten years ago, in February 2011, the first commit in ReText git repository was made. It was just a single 364 lines Python file back then (now the project has more than 6000 lines of Python code). Since 2011, the editor migrated from SourceForge to GitHub, gained a lot of new features, and most importantly now there is an active community around it, which includes both long-time contributors and newcomers who create their first issues or pull requests. I don t always have enough time to reply to issues or implement new features myself, but the community members help me with this. Earlier this month, I made a new release (7.2), which adds a side panel with directory tree (contributed by Xavier Gouchet), option to fully highlight wrapped lines (contributed by nihillum), ability to search in the preview mode and much more see the release page on GitHub. Side panel in ReText Also a new version of PyMarkups module was released, which contains all the code for processing various markup languages. It now supports markdown-extensions.yaml files which allow specifying complex extensions options and adds initial support for MathJax 3. Also check out the release notes for 7.1 which was not announced on this blog. Future plans include making at least one more release this year, adding support for Qt 6. Qt 5 support will last for at least one more year.

1 January 2021

Dmitry Shachnev: A review of endianness bugs in Qt, and how they were fixed

As you may know, I am Qt 5 maintainer in Debian. Maintaning Qt means not only bumping the version each time a new version is released, but also making sure Qt builds successfully on all architectures that are supported in Debian (and for some submodules, the automatic tests pass). An important sort of build failures are endianness specific failures. Most widely used architectures (x86_64, aarch64) are little endian. However, Debian officially supports one big endian architecture (s390x), and unofficially a few more ports are provided, such as ppc64 and sparc64. Unfortunately, Qt upstream does not have any big endian machine in their CI system, so endianness issues get noticed only when the packages fail to build on our build daemons. In the last years I have discovered and fixed some such issues in various parts of Qt, so I decided to write a post to illustrate how to write really cross-platform C/C++ code. Issue 1: the WebP image format handler (code review) The relevant code snippet is:
if (srcImage.format() != QImage::Format_ARGB32)
    srcImage = srcImage.convertToFormat(QImage::Format_ARGB32);
// ...
if (!WebPPictureImportBGRA(&picture, srcImage.bits(), srcImage.bytesPerLine()))  
    // ...
 
The code here is serializing the images into QImage::Format_ARGB32 format, and then passing the bytes into WebP s import function. With this format, the image is stored using a 32-bit ARGB format (0xAARRGGBB). This means that the bytes will be 0xBB, 0xGG, 0xRR, 0xAA or little endian and 0xAA, 0xRR, 0xGG, 0xBB on big endian. However, WebPPictureImportBGRA expects the first format on all architectures. The fix was to use QImage::Format_RGBA8888. As the QImage documentation says, with this format the order of the colors is the same on any architecture if read as bytes 0xRR, 0xGG, 0xBB, 0xAA. Issue 2: qimage_converter_map structure (code review) The code seems to already support big endian. But maybe you can spot the error?
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
        0,
        convert_ARGB_to_ARGB_PM,
#else
        0,
        0
#endif
It is the missing comma! It is present in the little endian block, but not in the big endian one. This was fixed trivially. Issue 3: QHandle, part of Qt 3D module (code review) QHandle class uses a union that is declared as follows:
struct Data  
    quint32 m_index : IndexBits;
    quint32 m_counter : CounterBits;
    quint32 m_unused : 2;
 ;
union  
    Data d;
    quint32 m_handle;
 ;
The sizes are declared such as IndexBits + CounterBits + 2 is always equal to 32 (four bytes). Then we have a constructor that sets the values of Data struct:
QHandle(quint32 i, quint32 count)
 
    d.m_index = i;
    d.m_counter = count;
    d.m_unused = 0;
 
The value of m_handle will be different depending on endianness! So the test that was expecting a particular value with given constructor arguments was failing. I fixed it by using the following macro:
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
#define GET_EXPECTED_HANDLE(qHandle) ((qHandle.index() << (qHandle.CounterBits + 2)) + (qHandle.counter() << 2))
#else /* Q_LITTLE_ENDIAN */
#define GET_EXPECTED_HANDLE(qHandle) (qHandle.index() + (qHandle.counter() << qHandle.IndexBits))
#endif
Issue 4: QML compiler (code review) The QML compiler used a helper class named LEUInt32 (based on QLEInteger) that always stored the numbers in little endian internally. This class can be safely mixed with native quint32 on little endian systems, but not on big endian. Usually the compiler would warn about type mismatch, but here the code used reinterpret_cast, such as:
quint32 *objectTable = reinterpret_cast<quint32*>(data + qmlUnit->offsetToObjects);
So this was not noticed on build time, but the compiler was crashing. The fix was trivial again, replacing quint32 with QLEUInt32. Issue 5: QModbusPdu, part of Qt Serial Bus module (code review) The code snippet is simple:
QModbusPdu::FunctionCode code = QModbusPdu::Invalid;
if (stream.readRawData((char *) (&code), sizeof(quint8)) != sizeof(quint8))
    return stream;
QModbusPdu::FunctionCode is an enum, so code is a multi-byte value (even if only one byte is significant). However, (char *) (&code) returns a pointer to the first byte of it. It is the needed byte on little endian systems, but it is the wrong byte on big endian ones! The correct fix was using a temporary one-byte variable:
quint8 codeByte = 0;
if (stream.readRawData((char *) (&codeByte), sizeof(quint8)) != sizeof(quint8))
    return stream;
QModbusPdu::FunctionCode code = (QModbusPdu::FunctionCode) codeByte;
Issue 6: qt_is_ascii (code review) This function, as the name says, checks whether a string is ASCII. It does that by splitting the string into 4-byte chunks:
while (ptr + 4 <= end)  
    quint32 data = qFromUnaligned<quint32>(ptr);
    if (data &= 0x80808080U)  
        uint idx = qCountTrailingZeroBits(data);
        ptr += idx / 8;
        return false;
     
    ptr += 4;
 
idx / 8 is the number of trailing zero bytes. However, the bytes which are trailing on little endian are actually leading on big endian! So we can use qCountLeadingZeroBits there. Issue 7: the bundled copy of tinycbor (upstream pull request) Similar to issue 5, the code was reading into the wrong byte:
if (bytesNeeded <= 2)  
    read_bytes_unchecked(it, &it->extra, 1, bytesNeeded);
    if (bytesNeeded == 2)
        it->extra = cbor_ntohs(it->extra);
 
extra has type uint16_t, so it has two bytes. When we need only one byte, we read into the wrong byte, so the resulting number is 256 times higher on big endian than it should be. Adding a temporary one-byte variable fixed it. Issue 8: perfparser, part of Qt Creator (code review) Here it is not trivial to find the issue just looking at the code:
qint32 dataStreamVersion = qToLittleEndian(QDataStream::Qt_DefaultCompiledVersion);
However the linker was producing an error:
undefined reference to QDataStream::Version qbswap(QDataStream::Version)'
On little endian systems, qToLittleEndian is a no-op, but on big endian systems, it is a template function defined for some known types. But it turns out we need to explicitly convert enum values to a simple type, so the fix was passing qint32(QDataStream::Qt_DefaultCompiledVersion) to that function. Issue 9: Qt Personal Information Management (code review) The code in test was trying to represent a number as a sequence of bytes, using reinterpret_cast:
static inline QContactId makeId(const QString &managerName, uint id)
 
    return QContactId(QStringLiteral("qtcontacts:basic%1:").arg(managerName), QByteArray(reinterpret_cast<const char *>(&id), sizeof(uint)));
 
The order of bytes will be different on little endian and big endian systems! The fix was adding this line to the beginning of the function:
id = qToLittleEndian(id);
This will cause the bytes to be reversed on big endian systems. What remains unfixed There are still some bugs, which require deeper investigation, for example: P.S. We are looking for new people to help with maintaining Qt 6. Join our team if you want to do some fun work like described above!

27 September 2017

Enrico Zini: Qt cross-architecture development in Debian

Use case: use Debian Stable as an environment to run amd64 development machines to develop Qt applications for Raspberry Pi or other smallish armhf devices. Qt Creator is used as Integrated Development Environment, and it supports cross-compiling, running the built source on the target system, and remote debugging. Debian Stable (vanilla or Raspbian) runs on both the host and the target systems, so libraries can be kept in sync, and both systems have access to a vast amount of libraries, with security support. On top of that, armhf libraries can be installed with multiarch also in the host machine, so cross-builders have access to the exact same libraries as the target system. This sounds like a dream system. But. We're not quite there yet. cross-compile attempts I tried cross compiling a few packages:
$ sudo debootstrap stretch cross
$ echo "strech_cross"   sudo tee cross/etc/debian_chroot
$ sudo systemd-nspawn -D cross
# dpkg --add-architecture armhf
# echo "deb-src http://deb.debian.org/debian stretch main" >> /etc/apt/sources.list
# apt update
# apt install --no-install-recommends build-essential crossbuild-essential-armhf
Some packages work:
# apt source bc
# cd bc-1.06.95/
# apt-get build-dep -a armhf .
# dpkg-buildpackage -aarmhf -j2 -b
 
dh_auto_configure -- --prefix=/usr --with-readline
        ./configure --build=x86_64-linux-gnu --prefix=/usr --includedir=\$ prefix /include --mandir=\$ prefix /share/man --infodir=\$ prefix /share/info --sysconfdir=/etc --localstatedir=/var --disable-silent-rules --libdir=\$ prefix /lib/arm-linux-gnueabihf --libexecdir=\$ prefix /lib/arm-linux-gnueabihf --disable-maintainer-mode --disable-dependency-tracking --host=arm-linux-gnueabihf --prefix=/usr --with-readline
 
dpkg-deb: building package 'dc-dbgsym' in '../dc-dbgsym_1.06.95-9_armhf.deb'.
dpkg-deb: building package 'bc-dbgsym' in '../bc-dbgsym_1.06.95-9_armhf.deb'.
dpkg-deb: building package 'dc' in '../dc_1.06.95-9_armhf.deb'.
dpkg-deb: building package 'bc' in '../bc_1.06.95-9_armhf.deb'.
 dpkg-genbuildinfo --build=binary
 dpkg-genchanges --build=binary >../bc_1.06.95-9_armhf.changes
dpkg-genchanges: info: binary-only upload (no source code included)
 dpkg-source --after-build bc-1.06.95
dpkg-buildpackage: info: binary-only upload (no source included)
With qmake based Qt packages, qmake is not configured for cross-building, probably because it is not currently supported:
# apt source pumpa
# cd pumpa-0.9.3/
# apt-get build-dep -a armhf .
# dpkg-buildpackage -aarmhf -j2 -b
 
        qmake -makefile -nocache "QMAKE_CFLAGS_RELEASE=-g -O2 -fdebug-prefix-map=/root/pumpa-0.9.3=.
          -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2"
          "QMAKE_CFLAGS_DEBUG=-g -O2 -fdebug-prefix-map=/root/pumpa-0.9.3=. -fstack-protector-strong
          -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2"
          "QMAKE_CXXFLAGS_RELEASE=-g -O2 -fdebug-prefix-map=/root/pumpa-0.9.3=. -fstack-protector-strong
          -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2"
          "QMAKE_CXXFLAGS_DEBUG=-g -O2 -fdebug-prefix-map=/root/pumpa-0.9.3=. -fstack-protector-strong
          -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2"
          "QMAKE_LFLAGS_RELEASE=-Wl,-z,relro -Wl,-z,now"
          "QMAKE_LFLAGS_DEBUG=-Wl,-z,relro -Wl,-z,now" QMAKE_STRIP=: PREFIX=/usr
qmake: could not exec '/usr/lib/x86_64-linux-gnu/qt5/bin/qmake': No such file or directory
 
debian/rules:19: recipe for target 'build' failed
make: *** [build] Error 2
dpkg-buildpackage: error: debian/rules build gave error exit status 2
With cmake based Qt packages it goes a little better in that it finds the cross compiler, pkg-config and some multiarch paths, but then it tries to run armhf moc, which fails:
# apt source caneda
# cd caneda-0.3.0/
# apt-get build-dep -a armhf .
# dpkg-buildpackage -aarmhf -j2 -b
 
        cmake .. -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_BUILD_TYPE=None
          -DCMAKE_INSTALL_SYSCONFDIR=/etc -DCMAKE_INSTALL_LOCALSTATEDIR=/var -DCMAKE_SYSTEM_NAME=Linux
          -DCMAKE_SYSTEM_PROCESSOR=arm -DCMAKE_C_COMPILER=arm-linux-gnueabihf-gcc
          -DCMAKE_CXX_COMPILER=arm-linux-gnueabihf-g\+\+
          -DPKG_CONFIG_EXECUTABLE=/usr/bin/arm-linux-gnueabihf-pkg-config
          -DCMAKE_INSTALL_LIBDIR=lib/arm-linux-gnueabihf
 
CMake Error at /usr/lib/arm-linux-gnueabihf/cmake/Qt5Core/Qt5CoreConfig.cmake:27 (message):
  The imported target "Qt5::Core" references the file
     "/usr/lib/arm-linux-gnueabihf/qt5/bin/moc"
  but this file does not exist.  Possible reasons include:
  * The file was deleted, renamed, or moved to another location.
  * An install or uninstall procedure did not complete successfully.
  * The installation package was faulty and contained
     "/usr/lib/arm-linux-gnueabihf/cmake/Qt5Core/Qt5CoreConfigExtras.cmake"
  but not all the files it references.
Note: Although I improvised a chroot to be able to fool around with it, I would use pbuilder or sbuild to do the actual builds. Helmut suggests pbuilder --host-arch or sbuild --host. Doing it the non-Debian way This guide in the meantime explains how to set up a cross-compiling Qt toolchain in a rather dirty way, by recompiling Qt pointing it at pieces of the Qt deployed on the Raspberry Pi. Following that guide, replacing the CROSS_COMPILE value with /usr/bin/arm-linux-gnueabihf- gave me a working qtbase, for which it is easy to create a Kit for Qt Creator that works, and supports linking applications with Debian development packages that do not use Qt. However, at that point I need to recompile all dependencies that use Qt myself, and I quickly got stuck at that monster of QtWebEngine, whose sources embed the whole of Chromium. Having a Qt based development environment in which I need to become the maintainer for the whole Qt toolchain is not a product I can offer to a customer. Cross compiling qmake based packages on stretch is not currently supported, so at the moment I had to suggest to postpone all plans for total world domination for at least two years. Cross-building Debian In the meantime, Helmut Grohne has been putting a lot of effort into making Debian packages cross-buildable:
helmut> enrico: yes, cross building is painful. we have ~26000 source packages. of those, ~13000 build arch-dep packages. of those, ~6000 have cross-satisfiable build-depends. of those, I tried cross building ~2300. of those 1300 cross built. so we are at about 10% working. helmut> enrico: plus there are some 607 source packages affected by some 326 bugs with patches. helmut> enrico: gogo nmu them helmut> enrico: I've filed some 1000 bugs (most of them with patches) now. around 600 are fixed :)
He is doing it mostly alone, and I would like people not to be alone when they do a lot of work in Debian, so Join Helmut in the effort of making Debian cross-buildable! Build any Debian package for any device right from the comfort of your own work computer! Have a single development environment seamlessly spanning architecture boundaries, with the power of all that there is in Debian! Join Helmut in the effort of making Debian cross-buildable! Apply here, or join #debian-bootstrap on OFTC! Cross-building Qt in Debian mitya57 summarised the situation on the KDE team side:
mitya57> we have cross-building stuff on our TODO list, but it will likely require a lot of time and neither Lisandro nor I have it currently. mitya57> see https://gobby.debian.org/export/Teams/KDE/qt-cross for a summary of what needs to be done. mitya57> Any help or patches are always welcome :))
qemu-user-static Helmut also suggested to use qemu-user-static to make the host system able to run binaries compiled for the target system, so that even if a non-cross-compiling Qt build tries to run moc and friends in their target architecture version, they would transparently succeed. At that point, it would just be a matter of replacing compiler paths to point to the native cross-compiling gcc, and the build would not be slowed down by much. Fixing bug #781226 would help in making it possible to configure a multiarch version of qmake as the qmake used for cross compiling. I have not had a chance of trying to cross-build in this way yet. In the meantime... Having qtcreator able to work on an amd64 devel machine and deploy/test/debug remotely on an arm target machine, where both machine run debian stable and have libraries in sync, would be a great thing to have even though packages do not cross-build yet. Helmut summarised the situation on IRC:
svuorela and others repeat that Qt upstream is not compatible with Debian's multiarch thinking, in that Qt upstream insists on having one toolchain for each pair of architectures, whereas the Debian way tends to be to make packages generic and split stuff such that it can be mixed and matched. An example being that you need to run qmake (thus you need qmake for the build architecture), but qmake also embeds the relevant paths and you need to query it for them (so you need qmake for the host architecture) Either you run it through qemu, or you have a particular cross qmake for your build/host pair, or you fix qt upstream to stop this madness
Building qmake in Debian for each host-target pair, even just limited to released architectures, would mean building Qt 100 times, and that's not going to scale. I wonder:

10 May 2016

Dmitry Shachnev: ReText 6.0 and PyMarkups 2.0 released

Today I have released the new major version of the ReText editor. This release would not be possible without Maurice van der Pot who was the author of the greatest features because of which the version number was bumped: Other news worth mentioning are: As usual, some bugs have been fixed (most of fixes have also been backported to 5.3.1 release), and some translations have been updated from Transifex. Please report any bugs you find to our issue tracker.

22 December 2015

Dmitry Shachnev: ReText 5.3 released

On Sunday I have released ReText 5.3, and here finally comes the official announcement. Highlights in this release are: Also, a week before ReText 5.3 a new version of PyMarkups was released, bringing enhanced support for the Textile markup. You can now edit Textile files in ReText too, provided that python-textile module for Python 3 is installed. As usual, you can get the latest release from PyPI or from the Debian/Ubuntu repositories. Please report any bugs you find to our issue tracker.

10 December 2015

Dmitry Shachnev: Magic infinite sequences for Python

Today I have released a small module for Python 3 that implements cached lazy infinite sequences. Here are some examples that demonstrate what this module can do:
>>> InfSequence(5, 6, ...)
<InfSequence: 5 6 7 8 9 10 ...>
>>> InfSequence.geometric_progression(9)
<InfSequence: 1 9 81 729 6561 59049 ...>
>>> InfSequence.cycle('foo', 'bar')
<InfSequence: 'foo' 'bar' 'foo' 'bar' 'foo' 'bar' ...>
>>> InfSequence.fibonacci()
<InfSequence: 0 1 1 2 3 5 ...>
Slicing works:
>>> InfSequence(5, 6, ...)[5:]
<InfSequence: 10 11 12 13 14 15 ...>
>>> InfSequence(5, 6, ...)[5::2]
<InfSequence: 10 12 14 16 18 20 ...>
A somewhat reverse operation:
>>> (2, 3, 4) + InfSequence(5, 6, ...)
<InfSequence: 2 3 4 5 6 7 ...>
Various arithmetic operations are supported:
>>> InfSequence(1, 2, ...) ** 2
<InfSequence: 1 4 9 16 25 36 ...>
>>> InfSequence(3, 5, ...) - InfSequence(1, 2, ...)
<InfSequence: 2 3 4 5 6 7 ...>
>>> InfSequence(1, 2, ...).partial_sum(10)
55
More magic methods:
>>> InfSequence(1, 2, ...).accumulate()
<InfSequence: 1 3 6 10 15 21 ...>
>>> InfSequence(0, 2, ...) @ InfSequence(1)
<InfSequence: 1 4 9 16 25 36 ...>
For the complete API overview, please look at the documentation. You can install the module from PyPI. It is licensed under 3-clause BSD license. The source code is available on GitHub.

Dmitry Shachnev: Magic infinite sequences for Python

Today I have released a small module for Python 3 that implements cached lazy infinite sequences. Here are some examples that demonstrate what this module can do:
>>> InfSequence(5, 6, ...)
<InfSequence: 5 6 7 8 9 10 ...>
>>> InfSequence.geometric_progression(9)
<InfSequence: 1 9 81 729 6561 59049 ...>
>>> InfSequence.cycle('foo', 'bar')
<InfSequence: 'foo' 'bar' 'foo' 'bar' 'foo' 'bar' ...>
>>> InfSequence.fibonacci()
<InfSequence: 0 1 1 2 3 5 ...>
Slicing works:
>>> InfSequence(5, 6, ...)[5:]
<InfSequence: 10 11 12 13 14 15 ...>
>>> InfSequence(5, 6, ...)[5::2]
<InfSequence: 10 12 14 16 18 20 ...>
A somewhat reverse operation:
>>> (2, 3, 4) + InfSequence(5, 6, ...)
<InfSequence: 2 3 4 5 6 7 ...>
Various arithmetic operations are supported:
>>> InfSequence(1, 2, ...) ** 2
<InfSequence: 1 4 9 16 25 36 ...>
>>> InfSequence(3, 5, ...) - InfSequence(1, 2, ...)
<InfSequence: 2 3 4 5 6 7 ...>
>>> InfSequence(1, 2, ...).partial_sum(10)
55
More magic methods:
>>> InfSequence(1, 2, ...).accumulate()
<InfSequence: 1 3 6 10 15 21 ...>
>>> InfSequence(0, 2, ...) @ InfSequence(1)
<InfSequence: 1 4 9 16 25 36 ...>
For the complete API overview, please look at the documentation. You can install the module from PyPI. It is licensed under 3-clause BSD license. The source code is available on GitHub.

21 July 2015

Dmitry Shachnev: GNOME Flashback 3.16 available in archive, needs your help

Some time ago GNOME Flashback 3.16/3.17 packages landed in Debian testing and Ubuntu wily. GNOME Flashback is the project which continues the development of components of classic GNOME session, including the GNOME Panel, the Metacity window manager, and so on. Screenshot The full changelog can be found in official announcement mail by Alberts and in changelog.gz files in each package, but I want to list the most imporant improvements in this release (compared to 3.14): Sounds interesting? Contribute! If you are interested in helping us, please write to our mailing list: gnome-flashback-list@gnome.org. The current TODO list is:
  1. Notification Daemon needs GTK notification support.
  2. GNOME Flashback needs screenshot, screencast, keyboard layout switching and bluetooth status icon.
  3. Fix/replace deprecated function usage in all modules.
  4. libstatus-notifier get it in usable state, create a new applet for gnome-panel.