https://community.kde.org/api.php?action=feedcontributions&user=Dfaure&feedformat=atomKDE Community Wiki - User contributions [en]2024-03-28T17:21:26ZUser contributionsMediaWiki 1.40.2https://community.kde.org/index.php?title=Guidelines_and_HOWTOs/Debugging/Debugging_IOSlaves&diff=94008Guidelines and HOWTOs/Debugging/Debugging IOSlaves2022-05-16T08:22:50Z<p>Dfaure: modernize</p>
<hr />
<div>This page describes how you can debug a KIO ioslave.<br />
<br />
==How to Get Debug Output==<br />
<br />
=== GUI (Qt5/KF5 instructions) ===<br />
<br />
# Launch the <code>kdebugsettings</code> tool, either from terminal or from KRunner (the latter can be invoked with Alt + F2)<br />
# Type the name of the KIO Slave (e.g. ftp, http, ...). (If it's not listed, it doesn't use categorized debug output, so either its output is always on, or commented out in the code, in which case it needs to be ported to qCDebug)<br />
# From the drop-down menu next to each KIO Slave you're interested in, select '''Full Debug'''<br />
# Press '''OK''' to close the dialog and the save your changes<br />
# You can either run <code>kdeinit5</code> in terminal, in which case the output from any IO slave that's started afterwards will show up in that terminal OR<br />
# Alternatively log out then log back in, and additional debug info will typically end up in ~/.X.err, ~/.xsession-errors or ~/.local/share/sddm/xorg-session.log<br />
<br />
Notes:<br />
* If you have rebuilt an IO Slave from source with some changes you'll need ensure that <code>kdeinit5</code> will pick it up; this works with KIO from the KDE repos:<br />
{{Input|1=<nowiki><br />
cd <path to build dir>/bin<br />
export LD_LIBRARY_PATH=$PWD<br />
export QT_PLUGIN_PATH=$PWD<br />
kdeinit5</nowiki>}}<br />
** in the first <code>cd</code> command you change to the directory containing the compiled binaries, in KIO case it's ''<build dir>/bin''.<br />
<br />
* Instead of using <code>kdebugsettings</code>, you can change the Qt logging categories rules temporarily, in terminal:<br />
{{Input|1=<nowiki><br />
export QT_LOGGING_RULES="*kio*=true"<br />
</nowiki>}} <br />
** for more information see [https://doc.qt.io/qt-5/qloggingcategory.html this]. <br />
=== GUI (Qt4/kdelibs4 instructions) ===<br />
<br />
# Press ALT+F2.<br />
# Enter 'kdebugdialog --fullmode' without the quotes and press enter.<br />
# Select the desired number in the "Debug area", e.g. 7103 for http.<br />
# In the [Information] box, select "File" as the output.<br />
# Enter the desired file name, e.g. /tmp/kio_http.log.<br />
# Press OK to close the dialog.<br />
# Press ALT+F2, type ''kdeinit4'' and press enter or alternatively log out of KDE and log back in.<br />
<br />
This will print additional debug info to the stderr of your kdeinit process, which typically ends up in ~/.X.err, ~/.xsession-errors or ~/.local/share/sddm/xorg-session.log<br />
<br />
===Manual (Qt4/kdelibs4 instructions)===<br />
It is useful to redirect the debug output of your particular slave to a file <br />
instead of stderr. E.g. I myself use the following lines in<br />
$KDEDIR/share/config/kdebugrc.<br />
<pre><br />
[7113]<br />
InfoOutput=0<br />
InfoFilename=/tmp/http<br />
[7103]<br />
InfoOutput=0<br />
InfoFilename=/tmp/http <br />
</pre><br />
This redirects all debug info for areas 7103 and 7113 (as used by kio_http) <br />
to the file /tmp/http.<br />
<br />
To get debug information from the SMB slave you can add the following to<br />
kioslaverc:<br />
<pre><br />
[SMB]<br />
DebugLevel=100<br />
</pre><br />
This will print additional debug info to the stderr of your kdeinit process,<br />
which typically ends up in ~/.X.err, ~/.xsession-errors or ~/.local/share/sddm/xorg-session.log<br />
<br />
==How does an io-slave get started?==<br />
<br />
Before KF 5.86: if <code>KDE_FORK_SLAVES</code> environment variable is ''not set'', your application requests 'klauncher' via DBus for a slave. If 'klauncher' does not have an idle slave ready, it will ask kdeinit to start a new one. kdeinit forks and dlopens the library that contains the io-slave. Then it calls a function called kdemain() in the library.<br />
<br />
Since 5.86 (or when setting <code>KDE_FORK_SLAVES</code> before that) the application simply starts the io-slave directly.<br />
<br />
Since 5.95, an io-slave can run in a thread (in the application process). Currently this only happens for kio_file. It can be disabled with <code>export KIO_ENABLE_WORKER_THREADS=0</code>.<br />
<br />
==Attaching gdb to an io-slave==<br />
===For slaves started via klauncher (before KF 5.86)===<br />
<br />
If <code>KDE_FORK_SLAVES</code> environment variable is ''not set'', your application asks <code>klauncher</code> via DBus for an io-slave. If <code>klauncher</code> does not have an idle io-slave ready, it will ask <code>kdeinit</code> to start a new one. <code>kdeinit</code> forks and dlopens the library that contains the requested io-slave.<br />
Then it calls a function called <code>kdemain()</code> in the library.<br />
<br />
Due to the above sequence it is rather hard to get an io-slave in your debugger. But wait there is hope! You can start </code>klauncher</code> in such a way that io-slaves for a certain protocol (the first parameter of KIO::SlaveBase() constructor of the Slave class) are started in debug mode.<br />
<br />
E.g. to start all 'http' slaves in debug mode, you type:<br />
<pre><br />
KDE_SLAVE_DEBUG_WAIT=http kdeinit5<br />
</pre><br />
<br />
This will restart 'kdeinit' and 'klauncher'.<br />
<br />
Note:<br />
The string after the equal signal designates the name of a service, not the name of the slave! E.g. if you want to debug the kio_imap4, you must use:<br />
<pre><br />
KDE_SLAVE_DEBUG_WAIT=imap kdeinit5<br />
</pre><br />
<br />
For example, these commands won't work:<br />
<pre><br />
KDE_SLAVE_DEBUG_WAIT=imap4 kdeinit5<br />
KDE_SLAVE_DEBUG_WAIT=143 kdeinit5<br />
</pre><br />
<br />
When your application now requests an http io-slave, the io-slave will be started kdeinit, but before it calls kdemain() (cq. main()) it will suspend the slave by sending it a SIGSTOP signal.<br />
<br />
In the terminal from which you started kdeinit you will get a message like this:<br />
<pre><br />
kdeinit: Suspending process<br />
kdeinit: 'gdb kdeinit 16779' to debug<br />
kdeinit: 'kill -SIGCONT 16779' to continue<br />
</pre><br />
<br />
You can now debug your slave by using <code>gdb kdeinit 16779</code> in a terminal.<br />
<br />
Note that modern Linux Kernels disable ptrace. If gdb says "ptrace: Operation not permitted." then you need to use a command like this:<br />
<pre><br />
echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope<br />
</pre><br />
<br />
If you don't want to debug a slave you can let it continue by sending it a SIGCONT, with e.g. <code>kill -SIGCONT 16779</code>. Be aware that slaves will not be killed while they are suspended.<br />
<br />
Once you have started gdb, you can set e.g. breakpoints and then resume the slave by typing <code>continue</code> (or <code>c</code> for short). The debugger will return immediate with a message that a "SIGSTOP has been received" so you will have to type <code>continue</code> a second time.<br />
<br />
See also [[Development/Tutorials/Debugging/Debugging_on_MS_Windows#Debugging_kioslaves|Windows-specific notes on debugging io-slaves]].<br />
<br />
===For slaves started directly by the application (forked)===<br />
<br />
The only difference between this section and the previous one is how the io-slave is started.<br />
<br />
When you start your application, a dedicated io-slave will be created in-process by the <code>kioslave</code> executable. To make the io-slave start then wait for debug, just like with the kdeinit/klauncher approach, you need to export <code>KDE_SLAVE_DEBUG_WAIT</code>, for example:<br />
<pre><br />
// Will start any io-slave then call `kill -SIGSTOP pid` to make it wait for debugging,<br />
// e.g. you can create a breakpoint ...etc<br />
export KDE_SLAVE_DEBUG_WAIT=all<br />
kioslave5: Suspending process to debug io slave(s): all<br />
kioslave5: 'gdb kioslave5 28008' to debug<br />
kioslave5: 'kill -SIGCONT 28008' to continue<br />
<br />
// This will do the same but only for kio_file<br />
export KDE_SLAVE_DEBUG_WAIT=file<br />
kioslave5: Suspending process to debug io slave(s): file<br />
kioslave5: 'gdb kioslave5 25208' to debug<br />
kioslave5: 'kill -SIGCONT 25208' to continue<br />
</pre><br />
<br />
then follow the same debugging steps from the previous section.<br />
<br />
===For slaves started in a thread (kio_file since KF 5.95)===<br />
<br />
Just put a breakpoint in <code>KIO::WorkerThread::WorkerThread</code><br />
<br />
==Debugging io-slaves with valgrind (for slaves started via klauncher)==<br />
KLauncher can be told to run certain io-slaves through valgrind. The following<br />
command can be used to let klauncher run all https io-slaves via valgrind:<br />
<pre><br />
KDE_SLAVE_VALGRIND=https kdeinit5<br />
</pre><br />
<br />
The valgrind output will appear as the stderr output of the kdeinit process.<br />
The $VALGRIND_OPTS environment variable can be used to pass options to valgrind.<br />
If you want to use a different skin:<br />
<pre><br />
KDE_SLAVE_VALGRIND_SKIN=callgrind ( for example )<br />
</pre><br />
<br />
== specific kioslaves ==<br />
* [[Guidelines_and_HOWTOs/Debugging/Debugging IOSlaves/Debugging kio_fish|kio_fish]]<br />
* [[Guidelines_and_HOWTOs/Debugging/Debugging IOSlaves/Debugging kio_sftp|kio_sftp]]<br />
* [[Guidelines_and_HOWTOs/Debugging/Debugging IOSlaves/Debugging kio_smb|kio_smb]]</div>Dfaurehttps://community.kde.org/index.php?title=Guidelines_and_HOWTOs/Debugging/Debugging_IOSlaves&diff=92273Guidelines and HOWTOs/Debugging/Debugging IOSlaves2021-06-24T10:06:53Z<p>Dfaure: add missing slash</p>
<hr />
<div>This page describes how you can debug a KIO ioslave.<br />
<br />
==How to Get Debug Output==<br />
<br />
=== GUI (Qt5/KF5 instructions) ===<br />
<br />
# Launch the <code>kdebugsettings</code> tool, either from terminal or from KRunner (the latter can be invoked with Alt + F2)<br />
# Type the name of the KIO Slave (e.g. ftp, http, ...). (If it's not listed, it doesn't use categorized debug output, so either its output is always on, or commented out in the code, in which case it needs to be ported to qCDebug)<br />
# From the drop-down menu next to each KIO Slave you're interested in, select '''Full Debug'''<br />
# Press '''OK''' to close the dialog and the save your changes<br />
# You can either run <code>kdeinit5</code> in terminal, in which case the output from any IO slave that's started afterwards will show up in that terminal OR<br />
# Alternatively log out then log back in, and additional debug info will typically end up in ~/.X.err, ~/.xsession-errors or ~/.local/share/sddm/xorg-session.log<br />
<br />
Notes:<br />
* If you have rebuilt an IO Slave from source with some changes you'll need ensure that <code>kdeinit5</code> will pick it up; this works with KIO from the KDE repos:<br />
{{Input|1=<nowiki><br />
cd <path to build dir>/bin<br />
export LD_LIBRARY_PATH=$PWD<br />
export QT_PLUGIN_PATH=$PWD<br />
kdeinit5</nowiki>}}<br />
** in the first <code>cd</code> command you change to the directory containing the compiled binaries, in KIO case it's ''<build dir>/bin''.<br />
<br />
* Instead of using <code>kdebugsettings</code>, you can change the Qt logging categories rules temporarily, in terminal:<br />
{{Input|1=<nowiki><br />
export QT_LOGGING_RULES="*kio*=true"<br />
</nowiki>}} <br />
** for more information see [https://doc.qt.io/qt-5/qloggingcategory.html this]. <br />
=== GUI (Qt4/kdelibs4 instructions) ===<br />
<br />
# Press ALT+F2.<br />
# Enter 'kdebugdialog --fullmode' without the quotes and press enter.<br />
# Select the desired number in the "Debug area", e.g. 7103 for http.<br />
# In the [Information] box, select "File" as the output.<br />
# Enter the desired file name, e.g. /tmp/kio_http.log.<br />
# Press OK to close the dialog.<br />
# Press ALT+F2, type ''kdeinit4'' and press enter or alternatively log out of KDE and log back in.<br />
<br />
This will print additional debug info to the stderr of your kdeinit process, which typically ends up in ~/.X.err, ~/.xsession-errors or ~/.local/share/sddm/xorg-session.log<br />
<br />
===Manual (Qt4/kdelibs4 instructions)===<br />
It is useful to redirect the debug output of your particular slave to a file <br />
instead of stderr. E.g. I myself use the following lines in<br />
$KDEDIR/share/config/kdebugrc.<br />
<pre><br />
[7113]<br />
InfoOutput=0<br />
InfoFilename=/tmp/http<br />
[7103]<br />
InfoOutput=0<br />
InfoFilename=/tmp/http <br />
</pre><br />
This redirects all debug info for areas 7103 and 7113 (as used by kio_http) <br />
to the file /tmp/http.<br />
<br />
To get debug information from the SMB slave you can add the following to<br />
kioslaverc:<br />
<pre><br />
[SMB]<br />
DebugLevel=100<br />
</pre><br />
This will print additional debug info to the stderr of your kdeinit process,<br />
which typically ends up in ~/.X.err, ~/.xsession-errors or ~/.local/share/sddm/xorg-session.log<br />
<br />
==How does an io-slave get started?==<br />
<br />
Your application requests 'klauncher' via DBus for a slave. If 'klauncher' does not have an idle slave ready, it will ask kdeinit to start a new one. kdeinit forks and dlopens the library that contains the io-slave.<br />
Then it calls a function called kdemain() in the library.<br />
<br />
==Attaching gdb to an io-slave==<br />
===If KDE_FORK_SLAVES is not set===<br />
<br />
If <code>KDE_FORK_SLAVES</code> environment variable is ''not set'', your application asks <code>klauncher</code> via DBus for an io-slave. If <code>klauncher</code> does not have an idle io-slave ready, it will ask <code>kdeinit</code> to start a new one. <code>kdeinit</code> forks and dlopens the library that contains the requested io-slave.<br />
Then it calls a function called <code>kdemain()</code> in the library.<br />
<br />
Due to the above sequence it is rather hard to get an io-slave in your debugger. But wait there is hope! You can start </code>klauncher</code> in such a way that io-slaves for a certain protocol (the first parameter of KIO::SlaveBase() constructor of the Slave class) are started in debug mode.<br />
<br />
E.g. to start all 'http' slaves in debug mode, you type:<br />
<pre><br />
KDE_SLAVE_DEBUG_WAIT=http kdeinit5<br />
</pre><br />
<br />
This will restart 'kdeinit' and 'klauncher'.<br />
<br />
Note:<br />
The string after the equal signal designates the name of a service, not the name of the slave! E.g. if you want to debug the kio_imap4, you must use:<br />
<pre><br />
KDE_SLAVE_DEBUG_WAIT=imap kdeinit5<br />
</pre><br />
<br />
For example, these commands won't work:<br />
<pre><br />
KDE_SLAVE_DEBUG_WAIT=imap4 kdeinit5<br />
KDE_SLAVE_DEBUG_WAIT=143 kdeinit5<br />
</pre><br />
<br />
When your application now requests an http io-slave, the io-slave will be started kdeinit, but before it calls kdemain() (cq. main()) it will suspend the slave by sending it a SIGSTOP signal.<br />
<br />
In the terminal from which you started kdeinit you will get a message like this:<br />
<pre><br />
kdeinit: Suspending process<br />
kdeinit: 'gdb kdeinit 16779' to debug<br />
kdeinit: 'kill -SIGCONT 16779' to continue<br />
</pre><br />
<br />
You can now debug your slave by using <code>gdb kdeinit 16779</code> in a terminal.<br />
<br />
Note that modern Linux Kernels disable ptrace. If gdb says "ptrace: Operation not permitted." then you need to use a command like this:<br />
<pre><br />
echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope<br />
</pre><br />
<br />
If you don't want to debug a slave you can let it continue by sending it a SIGCONT, with e.g. <code>kill -SIGCONT 16779</code>. Be aware that slaves will not be killed while they are suspended.<br />
<br />
Once you have started gdb, you can set e.g. breakpoints and then resume the slave by typing <code>continue</code> (or <code>c</code> for short). The debugger will return immediate with a message that a "SIGSTOP has been received" so you will have to type <code>continue</code> a second time.<br />
<br />
See also [[Development/Tutorials/Debugging/Debugging_on_MS_Windows#Debugging_kioslaves|Windows-specific notes on debugging io-slaves]].<br />
<br />
===If KDE_FORK_SLAVES is set===<br />
<br />
Read the previous section, because a lot of what it said applies here too, the only difference is how the io-slave is started.<br />
<br />
If you set the <code>KDE_FORK_SLAVES</code> environment variable:<br />
{{Input|1=<nowiki><br />
export KDE_FORK_SLAVES=1<br />
</nowiki>}}<br />
then start your application from that terminal, a dedicated io-slave will be created for your application in-process. In this case to attach gdb to the io-slave, first find the pid of the io-slave process, you can do that by examining the output of e.g.:<br />
<pre><br />
ps -ef | grep kdeinit<br />
</pre><br />
<br />
let's say you're trying to debug the Trash io-slave, the output should contain something like:<br />
<pre><br />
username 29333 29156 0 17:57 ? 00:00:00 trash.so [kdeinit5] trash local:/run/user/1000/klauncherJvaxHq.1.slave-socket local:/run/user/1000/<app-name>nUqbkc.4.slave-socket<br />
</pre><br />
or you could simply use:<br />
<pre><br />
ps -ef | grep trash.so<br />
</pre><br />
the pid is 29333 in this case. Note that you may need to examing the output before starting your application and after starting it, in case there are other io-slaves already running.<br />
<br />
To attch gdb to that io-slave process:<br />
<pre><br />
gdb --pid 29333<br />
</pre><br />
(if there is only one trash.so process running you can use <code>gdb --pid $(pidof trash.so)</code><br />
<br />
and then follow the same debugging steps from the previous section.<br />
<br />
==Debugging io-slaves with valgrind==<br />
KLauncher can be told to run certain io-slaves through valgrind. The following<br />
command can be used to let klauncher run all https io-slaves via valgrind:<br />
<pre><br />
KDE_SLAVE_VALGRIND=https kdeinit5<br />
</pre><br />
<br />
The valgrind output will appear as the stderr output of the kdeinit process.<br />
The $VALGRIND_OPTS environment variable can be used to pass options to valgrind.<br />
If you want to use a different skin:<br />
<pre><br />
KDE_SLAVE_VALGRIND_SKIN=callgrind ( for example )<br />
</pre><br />
<br />
== specific kioslaves ==<br />
* [[Guidelines_and_HOWTOs/Debugging/Debugging IOSlaves/Debugging kio_fish|kio_fish]]<br />
* [[Guidelines_and_HOWTOs/Debugging/Debugging IOSlaves/Debugging kio_sftp|kio_sftp]]<br />
* [[Guidelines_and_HOWTOs/Debugging/Debugging IOSlaves/Debugging kio_smb|kio_smb]]</div>Dfaurehttps://community.kde.org/index.php?title=Akademy/2021/Wednesday&diff=92258Akademy/2021/Wednesday2021-06-22T12:27:31Z<p>Dfaure: moved to thursday</p>
<hr />
<div>= BoF sessions on Wednesday, 23 June 2021 =<br />
<br />
[https://community.kde.org/Akademy/2021/AllBoF Back to all BoFs]<br />
<br />
Note: The [https://wiki.qt.io/Qt_Contributors_Summit_2021_-_Program Qt Contributors Summit sessions] are available on the [https://wiki.qt.io/Main Qt project wiki].<br />
<br />
=== Room 01 - 23rd June ===<br />
{| class="table table-striped"<br />
|-<br />
! [https://meet.kde.org/b/akademy-bof-1 Link to Room 1]<br />
!<br />
! <br />
|-<br />
! Time <br />
! Subject <br />
! Host/Notes<br />
|-<br />
| width="100pt" | 9:00 UTC<br />
| width="200pt" | '''Qt for Python :''' Cross Platform application development with Qt, Qml and Python<br />
| width="400pt" | Anupam Basak<br />
|-<br />
| 10:00 UTC<br />
| Kirigami and KF6<br />
| <br />
|-<br />
| 11:00 UTC<br />
| Plasma Mobile top drawer implementation<br />
| Marco Martin<br />
|-<br />
| 12:00 - 16:00 UTC <br />
| Break<br />
| <br />
|- <br />
| 16:00 UTC<br />
| Linux Virtual Desktop - Shells<br />
| Alex Lee<br />
|-<br />
| 17:00 UTC<br />
| KDE e.V. Board office hours<br />
| The KDE e.V. Board<br />
|-<br />
| 18:00 UTC<br />
| KDE Goal: All about the apps - Windows platform<br />
| Aleix Pol<br />
|-<br />
| 19:00 UTC<br />
| Prep for BoF Wrap Up<br />
| <br />
|-<br />
| 19:30 UTC<br />
| BoF Wrap Up<br />
|<br />
|}<br />
<br />
=== Room 02 - 23rd June ===<br />
{| class="table table-striped"<br />
|-<br />
! [https://meet.kde.org/b/akademy-bof-2 Link to Room 2]<br />
!<br />
! <br />
|-<br />
! Time <br />
! Subject <br />
! Host/Notes<br />
|-<br />
| width="100pt" | 9:00 UTC<br />
| width="200pt" | <br />
| width="400pt" | <br />
|-<br />
| 10:00 UTC<br />
|<br />
|<br />
|-<br />
| 11:00 UTC<br />
| <br />
| <br />
|-<br />
| 12:00 - 16:00 UTC <br />
| Break<br />
| <br />
|- <br />
| 16:00 UTC<br />
| Plasma<br />
| Marco Martin / David Edmundson https://share.kde.org/s/ixNaQxyybz2NHpE<br />
|-<br />
| 17:00 UTC<br />
| Plasma<br />
| Marco Martin / David Edmundson<br />
|-<br />
| 18:00 UTC<br />
| Plasma / LatteDock<br />
| Marco Martin / David Edmundson<br />
|-<br />
| 19:00 UTC<br />
| Prep for BoF Wrap Up<br />
| <br />
|-<br />
| 19:30 UTC<br />
| BoF Wrap Up<br />
| Go to Room 1<br />
|}<br />
<br />
=== Room 03 - 23rd June ===<br />
{| class="table table-striped"<br />
|-<br />
! [https://meet.kde.org/b/akademy-bof-3 Link to Room 3]<br />
!<br />
! <br />
|-<br />
! Time <br />
! Subject <br />
! Host/Notes<br />
|-<br />
| width="100pt" | 9:00 UTC<br />
| width="200pt" | Inqlude - Collecting everything Qt<br />
| width="400pt" | Cornelius Schumacher <schumacher@kde.org> (Where are we with [https://inqlude.org Inqlude], where do we want to go?)<br />
|-<br />
| 10:00 UTC<br />
|<br />
|<br />
|-<br />
| 11:00 UTC<br />
|<br />
|<br />
|-<br />
| 12:00 - 16:00 UTC <br />
| Break<br />
| <br />
|- <br />
| 16:00 UTC<br />
| I18n/Localization<br />
| Luigi Toscano<br />
|-<br />
| 17:00 UTC<br />
| <br />
| <br />
|-<br />
| 18:00 UTC<br />
| Frameworks Documentation<br />
| Carl and Frederik<br />
|-<br />
| 19:00 UTC<br />
| Prep for BoF Wrap Up<br />
| <br />
|-<br />
| 19:30 UTC<br />
| BoF Wrap Up<br />
| Go to Room 1<br />
|}</div>Dfaurehttps://community.kde.org/index.php?title=Akademy/2021/Thursday&diff=92257Akademy/2021/Thursday2021-06-22T12:26:56Z<p>Dfaure: add bof</p>
<hr />
<div>= BoF sessions on Thursday, 24 June 2021 =<br />
<br />
[https://community.kde.org/Akademy/2021/AllBoF Back to all BoFs]<br />
<br />
=== Room 01 - 24th June ===<br />
{| class="table table-striped"<br />
|-<br />
! [https://meet.kde.org/b/akademy-bof-1 Link to Room 1]<br />
!<br />
! <br />
|-<br />
! Time <br />
! Subject <br />
! Host/Notes<br />
|-<br />
| width="100pt" | 9:00 UTC<br />
| width="200pt" | KF6 board priorization<br />
| width="400pt" | David Faure / Nicolas Fella<br />
|-<br />
| 10:00 UTC<br />
|25 years of KDE<br />
|Allyson and Lydia - We'll talk about detailed plans for the 25th anniversary of KDE later this year and how to make it a memorable occasion.<br />
|-<br />
| 11:00 UTC<br />
|<br />
|<br />
|-<br />
| 12:00 - 16:00 UTC <br />
| Break<br />
| <br />
|- <br />
| 16:00 UTC<br />
| KDE Goal: Consistency<br />
| Niccolò Ve<br />
|-<br />
| 17:00 UTC<br />
| KDE Goal: All about the apps - MacOS platform<br />
| Aleix Pol<br />
|-<br />
| 18:00 UTC<br />
| User documentation (is offline documentation still needed?)<br />
| Carl and Frederik<br />
|-<br />
| 19:00 UTC<br />
| Prep for BoF Wrap Up<br />
| <br />
|-<br />
| 19:30 UTC<br />
| BoF Wrap Up<br />
|<br />
|}<br />
<br />
=== Room 02 - 24th June ===<br />
{| class="table table-striped"<br />
|-<br />
! [https://meet.kde.org/b/akademy-bof-2 Link to Room 2]<br />
!<br />
! <br />
|-<br />
! Time <br />
! Subject <br />
! Host/Notes<br />
|-<br />
| width="100pt" | 9:00 UTC<br />
| width="200pt" | <br />
| width="400pt" | <br />
|-<br />
| 10:00 UTC<br />
| Scene Graph Redesign and Effects<br />
| Vlad Zahorodnii<br />
|-<br />
| 11:00 UTC<br />
| <br />
| <br />
|-<br />
| 12:00 - 16:00 UTC <br />
| Break<br />
| <br />
|- <br />
| 16:00 UTC<br />
| Qt6 on the BSDs<br />
| ''[ade]'' on IRC in <code>#freebsd-desktop</code><br />
|-<br />
| 17:00 UTC<br />
| Promo & W11<br />
| Paul Brown & Aniqa Khokhar<br />
|-<br />
| 18:00 UTC<br />
| Make a living<br />
| Neofytos<br />
|-<br />
| 19:00 UTC<br />
| Prep for BoF Wrap Up<br />
| <br />
|-<br />
| 19:30 UTC<br />
| BoF Wrap Up<br />
| Go to Room 1<br />
|}<br />
<br />
=== Room 03 - 24th June ===<br />
{| class="table table-striped"<br />
|-<br />
! [https://meet.kde.org/b/akademy-bof-3 Link to Room 3]<br />
!<br />
! <br />
|-<br />
! Time <br />
! Subject <br />
! Host/Notes<br />
|-<br />
| width="100pt" | 9:00 UTC<br />
| width="200pt" | <br />
| width="400pt" | <br />
|-<br />
| 10:00 UTC<br />
|<br />
|<br />
|-<br />
| 11:00 UTC<br />
|<br />
|<br />
|-<br />
| 12:00 - 16:00 UTC <br />
| Break<br />
| <br />
|- <br />
| 16:00 UTC<br />
| Plasma Bigscreen<br />
| Aditya Mehra / Marco Martin<br />
|-<br />
| 17:00 UTC<br />
| <br />
| <br />
|-<br />
| 18:00 UTC<br />
| <br />
| <br />
|-<br />
| 19:00 UTC<br />
| Prep for BoF Wrap Up<br />
| <br />
|-<br />
| 19:30 UTC<br />
| BoF Wrap Up<br />
| Go to Room 1<br />
|}</div>Dfaurehttps://community.kde.org/index.php?title=Akademy/2021/Wednesday&diff=92231Akademy/2021/Wednesday2021-06-21T10:44:17Z<p>Dfaure: /* Room 02 - 23rd June */</p>
<hr />
<div>= BoF sessions on Wednesday, 23 June 2021 =<br />
<br />
[https://community.kde.org/Akademy/2021/AllBoF Back to all BoFs]<br />
<br />
Note: The [https://wiki.qt.io/Qt_Contributors_Summit_2021_-_Program Qt Contributors Summit sessions] are available on the [https://wiki.qt.io/Main Qt project wiki].<br />
<br />
=== Room 01 - 23rd June ===<br />
{| class="table table-striped"<br />
|-<br />
! [https://meet.kde.org/b/akademy-bof-1 Link to Room 1]<br />
!<br />
! <br />
|-<br />
! Time <br />
! Subject <br />
! Host/Notes<br />
|-<br />
| width="100pt" | 9:00 UTC<br />
| width="200pt" | '''Qt for Python :''' Cross Platform application development with Qt, Qml and Python<br />
| width="400pt" | Anupam Basak<br />
|-<br />
| 10:00 UTC<br />
| Kirigami and KF6<br />
| <br />
|-<br />
| 11:00 UTC<br />
| Plasma Mobile top drawer implementation<br />
| Marco Martin<br />
|-<br />
| 12:00 - 16:00 UTC <br />
| Break<br />
| <br />
|- <br />
| 16:00 UTC<br />
| Linux Virtual Desktop - Shells<br />
| Alex Lee<br />
|-<br />
| 17:00 UTC<br />
| KDE e.V. Board office hours<br />
| The KDE e.V. Board<br />
|-<br />
| 18:00 UTC<br />
| KDE Goal: All about the apps - Windows platform<br />
| Aleix Pol<br />
|-<br />
| 19:00 UTC<br />
| Prep for BoF Wrap Up<br />
| <br />
|-<br />
| 19:30 UTC<br />
| BoF Wrap Up<br />
|<br />
|}<br />
<br />
=== Room 02 - 23rd June ===<br />
{| class="table table-striped"<br />
|-<br />
! [https://meet.kde.org/b/akademy-bof-2 Link to Room 2]<br />
!<br />
! <br />
|-<br />
! Time <br />
! Subject <br />
! Host/Notes<br />
|-<br />
| width="100pt" | 9:00 UTC<br />
| width="200pt" | <br />
| width="400pt" | <br />
|-<br />
| 10:00 UTC<br />
|<br />
|<br />
|-<br />
| 11:00 UTC<br />
| KF6 board priorization<br />
| David Faure<br />
|-<br />
| 12:00 - 16:00 UTC <br />
| Break<br />
| <br />
|- <br />
| 16:00 UTC<br />
| Plasma<br />
| Marco Martin / David Edmundson https://share.kde.org/s/ixNaQxyybz2NHpE<br />
|-<br />
| 17:00 UTC<br />
| Plasma<br />
| Marco Martin / David Edmundson<br />
|-<br />
| 18:00 UTC<br />
| Plasma / LatteDock<br />
| Marco Martin / David Edmundson<br />
|-<br />
| 19:00 UTC<br />
| Prep for BoF Wrap Up<br />
| <br />
|-<br />
| 19:30 UTC<br />
| BoF Wrap Up<br />
| Go to Room 1<br />
|}<br />
<br />
=== Room 03 - 23rd June ===<br />
{| class="table table-striped"<br />
|-<br />
! [https://meet.kde.org/b/akademy-bof-3 Link to Room 3]<br />
!<br />
! <br />
|-<br />
! Time <br />
! Subject <br />
! Host/Notes<br />
|-<br />
| width="100pt" | 9:00 UTC<br />
| width="200pt" | Inqlude - Collecting everything Qt<br />
| width="400pt" | Cornelius Schumacher <schumacher@kde.org> (Where are we with [https://inqlude.org Inqlude], where do we want to go?)<br />
|-<br />
| 10:00 UTC<br />
|<br />
|<br />
|-<br />
| 11:00 UTC<br />
|<br />
|<br />
|-<br />
| 12:00 - 16:00 UTC <br />
| Break<br />
| <br />
|- <br />
| 16:00 UTC<br />
| I18n/Localization<br />
| Luigi Toscano<br />
|-<br />
| 17:00 UTC<br />
| <br />
| <br />
|-<br />
| 18:00 UTC<br />
| Frameworks Documentation<br />
| Carl and Frederik<br />
|-<br />
| 19:00 UTC<br />
| Prep for BoF Wrap Up<br />
| <br />
|-<br />
| 19:30 UTC<br />
| BoF Wrap Up<br />
| Go to Room 1<br />
|}</div>Dfaurehttps://community.kde.org/index.php?title=Akademy/2021/Monday&diff=92227Akademy/2021/Monday2021-06-20T16:54:56Z<p>Dfaure: shorten kf6 meeting to make room for lunch in Europe :)</p>
<hr />
<div>= BoF sessions on Monday, 21st June 2021 =<br />
<br />
<br />
Please put your name and email address in the Host/Notes section. There is no length limitation; text will wrap. <br />
<br />
'''KDE eV AGM'''<br />
Following on from the reports during the weekend the private part of the KDE eV AGM, for eV members only, will be held during 11:00 - 13:00 UTC in its own room.<br />
<br />
The Akademy team might reassign BoFs based on operational needs<br />
<br />
[https://community.kde.org/Akademy/2021/AllBoF Back to all BoFs]<br />
<br />
=== AGM ===<br />
{| class="table table-striped"<br />
|-<br />
! Private Room<br />
!<br />
!<br />
|-<br />
! Time<br />
! Subject<br />
! Host/Notes<br />
|-<br />
| 11:00 - 13:00 UTC<br />
| [https://ev.kde.org/generalassembly/ KDE eV AGM]<br />
| Only for KDE eV association members<br />
|}<br />
<br />
=== Room 01 - 21st June ===<br />
{| class="table table-striped"<br />
|-<br />
! [https://meet.kde.org/b/akademy-bof-1 Link to Room 1]<br />
!<br />
! <br />
|-<br />
! Time <br />
! Subject <br />
! Host/Notes<br />
|-<br />
| width="100pt" | 9:00 UTC<br />
| width="200pt" | KF6<br />
| width="400pt" | several Davids and Kévin<br />
|-<br />
| 10:00 - 10:30 UTC<br />
| KF6 (continued)<br />
|<br />
|-<br />
| 11:00 - 16:00 UTC <br />
| Break<br />
| <br />
|- <br />
| 16:00 UTC<br />
| KDE Goal: All about the apps - macOS / Homebrew platform<br />
| Yurii Kolesnykov<br />
|-<br />
| 17:00 UTC<br />
| KDE Goal: All about the apps - Linux platform<br />
| Aleix Pol<br />
|-<br />
| 18:00 UTC<br />
| KDE Goals - selecting the new Goals<br />
| Adam Szopa<br />
|-<br />
| 19:00 UTC<br />
| Prep for BoF Wrap Up<br />
| <br />
|-<br />
| 19:30 UTC<br />
| BoF Wrap Up<br />
|<br />
|}<br />
<br />
=== Room 02 - 21st June ===<br />
{| class="table table-striped"<br />
|-<br />
! [https://meet.kde.org/b/akademy-bof-2 Link to Room 2]<br />
!<br />
! <br />
|-<br />
! Time <br />
! Subject <br />
! Host/Notes<br />
|-<br />
| width="100pt" | 9:00 UTC<br />
| width="200pt" | <br />
| width="400pt" | <br />
|-<br />
| 10:00 UTC<br />
|<br />
|<br />
|-<br />
| 11:00 - 16:00 UTC <br />
| Break<br />
| <br />
|- <br />
| 16:00 UTC<br />
| LGBTQ+ community check-in and socialization hour<br />
| Host: Torrie Fischer <tdfischer@kde.org><br />
Matrix room: https://go.kde.org/matrix/#/#kde-lgbt:kde.org<br />
<br />
Come to say hi; stay for the warm fuzzies, camaraderie, and world-domination plotting.<br />
|-<br />
| 17:00 UTC<br />
| Shared chat components library<br />
| Janet Blackquill <uhhadd@gmail.com>; reduce duplication in KDE's chat apps using a shared library<br />
|-<br />
| 18:00 UTC<br />
| <br />
| <br />
|-<br />
| 19:00 UTC<br />
| Prep for BoF Wrap Up<br />
| <br />
|-<br />
| 19:30 UTC<br />
| BoF Wrap Up<br />
| Go to Room 1<br />
|}<br />
<br />
=== Room 03 - 21st June ===<br />
{| class="table table-striped"<br />
|-<br />
! [https://meet.kde.org/b/akademy-bof-3 Link to Room 3]<br />
!<br />
! <br />
|-<br />
! Time <br />
! Subject <br />
! Host/Notes<br />
|-<br />
| width="100pt" | 9:00 UTC<br />
| width="200pt" | <br />
| width="400pt" | <br />
|-<br />
| 10:00 UTC<br />
|<br />
|<br />
|-<br />
| 11:00 - 16:00 UTC <br />
| Break<br />
| <br />
|- <br />
| 16:00 UTC<br />
|<br />
| <br />
|-<br />
| 17:00 UTC<br />
| <br />
| <br />
|-<br />
| 18:00 UTC<br />
| <br />
| <br />
|-<br />
| 19:00 UTC<br />
| Prep for BoF Wrap Up<br />
| <br />
|-<br />
| 19:30 UTC<br />
| BoF Wrap Up<br />
| Go to Room 1<br />
|}</div>Dfaurehttps://community.kde.org/index.php?title=Akademy/2021/Monday&diff=92163Akademy/2021/Monday2021-06-18T13:46:11Z<p>Dfaure: /* Room 01 - 21st June */</p>
<hr />
<div>= BoF sessions on Monday, 21st June 2021 =<br />
<br />
<br />
Please put your name and email address in the Host/Notes section. There is no length limitation; text will wrap. <br />
<br />
'''KDE eV AGM'''<br />
Following on from the reports during the weekend the private part of the KDE eV AGM, for eV members only, will be held during 11:00 - 13:00 UTC in its own room.<br />
<br />
The Akademy team might reassign BoFs based on operational needs<br />
<br />
[https://community.kde.org/Akademy/2021/AllBoF Back to all BoFs]<br />
<br />
=== AGM ===<br />
{| class="table table-striped"<br />
|-<br />
! Private Room<br />
!<br />
!<br />
|-<br />
! Time<br />
! Subject<br />
! Host/Notes<br />
|-<br />
| 11:00 - 13:00 UTC<br />
| [https://ev.kde.org/generalassembly/ KDE eV AGM]<br />
| Only for KDE eV association members<br />
|}<br />
<br />
=== Room 01 - 21st June ===<br />
{| class="table table-striped"<br />
|-<br />
! [https://meet.kde.org/b/akademy-bof-1 Link to Room 1]<br />
!<br />
! <br />
|-<br />
! Time <br />
! Subject <br />
! Host/Notes<br />
|-<br />
| width="100pt" | 9:00 UTC<br />
| width="200pt" | KF6<br />
| width="400pt" | several Davids and Kévin<br />
|-<br />
| 10:00 UTC<br />
| KF6 (continued)<br />
|<br />
|-<br />
| 11:00 UTC<br />
| '''Qt for Python''' : Cross Platform application development with Qt, Qml and Python<br />
| Anupam Basak<br />
|-<br />
| 12:00 - 16:00 UTC <br />
| Break<br />
| <br />
|- <br />
| 16:00 UTC<br />
| KDE Goal: All about the apps - macOS / Homebrew platform<br />
| Yurii Kolesnykov<br />
|-<br />
| 17:00 UTC<br />
| KDE Goal: All about the apps - Linux platform<br />
| Aleix Pol<br />
|-<br />
| 18:00 UTC<br />
| KDE Goals - selecting the new Goals<br />
| Adam Szopa<br />
|-<br />
| 19:00 UTC<br />
| Prep for BoF Wrap Up<br />
| <br />
|-<br />
| 19:30 UTC<br />
| BoF Wrap Up<br />
|<br />
|}<br />
<br />
=== Room 02 - 21st June ===<br />
{| class="table table-striped"<br />
|-<br />
! [https://meet.kde.org/b/akademy-bof-2 Link to Room 2]<br />
!<br />
! <br />
|-<br />
! Time <br />
! Subject <br />
! Host/Notes<br />
|-<br />
| width="100pt" | 9:00 UTC<br />
| width="200pt" | <br />
| width="400pt" | <br />
|-<br />
| 10:00 UTC<br />
|<br />
|<br />
|-<br />
| 11:00 UTC<br />
|<br />
|<br />
|-<br />
| 12:00 - 16:00 UTC <br />
| Break<br />
| <br />
|- <br />
| 16:00 UTC<br />
| <br />
| <br />
|-<br />
| 17:00 UTC<br />
| <br />
| <br />
|-<br />
| 18:00 UTC<br />
| <br />
| <br />
|-<br />
| 19:00 UTC<br />
| Prep for BoF Wrap Up<br />
| <br />
|-<br />
| 19:30 UTC<br />
| BoF Wrap Up<br />
| Go to Room 1<br />
|}<br />
<br />
=== Room 03 - 21st June ===<br />
{| class="table table-striped"<br />
|-<br />
! [https://meet.kde.org/b/akademy-bof-3 Link to Room 3]<br />
!<br />
! <br />
|-<br />
! Time <br />
! Subject <br />
! Host/Notes<br />
|-<br />
| width="100pt" | 9:00 UTC<br />
| width="200pt" | <br />
| width="400pt" | <br />
|-<br />
| 10:00 UTC<br />
|<br />
|<br />
|-<br />
| 11:00 UTC<br />
|<br />
|<br />
|-<br />
| 12:00 - 16:00 UTC <br />
| Break<br />
| <br />
|- <br />
| 16:00 UTC<br />
|<br />
| <br />
|-<br />
| 17:00 UTC<br />
| <br />
| <br />
|-<br />
| 18:00 UTC<br />
| <br />
| <br />
|-<br />
| 19:00 UTC<br />
| Prep for BoF Wrap Up<br />
| <br />
|-<br />
| 19:30 UTC<br />
| BoF Wrap Up<br />
| Go to Room 1<br />
|}</div>Dfaurehttps://community.kde.org/index.php?title=Qt5PatchCollection&diff=91679Qt5PatchCollection2021-04-27T15:59:12Z<p>Dfaure: /* How do I get a patch merged? */</p>
<hr />
<div>=== What's this? ===<br />
<br />
This is a set of git repositories based on the last public commits available for Qt 5.15 branches with a curated collection of patches on top to ensure open source products can be used comfortably until users transition to their Qt 6-based ports.<br />
<br />
=== Which patches does it include?=== <br />
<br />
This collection of patches includes patches that fix at least one of the following:<br />
<br />
* Security issues<br />
* Crashes<br />
* Functional defects<br />
<br />
We only include patches that have been approved upstream in the Qt project. If a patch cannot be merged upstream for technical reasons (e.g. the class no longer exists), it can also be merged.<br />
<br />
The patches to merge will be decided based on their relevance towards Open Source products and their viability.<br />
<br />
=== How do I get a patch merged? === <br />
<br />
To get a patch merged you must open a Merge Request against the kde/5.15 branch on the corresponding repository in https://invent.kde.org/qt/qt, describing the change as well as the reason it should be merged (e.g. by referencing a relevant defect report in an open source product). Also required is a reference to where it was approved upstream within https://codereview.qt-project.org.<br />
<br />
Note that this is gitlab (not gerrit), but without the usual permissions for KDE developers. So everyone must fork the repo first.<br />
<br />
Also note that the repo is synced with upstream qt (several times a day), so the commit you want to backport will be in there already, in dev or a 6.x branch, you can just cherry-pick it (with the option "-x"). Then push to your fork, and create a merge request for branch kde/5.15.<br />
<br />
=== Who decides if a patch gets merged? ===<br />
<br />
There is a [https://invent.kde.org/groups/qt/qt/-/group_members group of curators] for this patch collection that will have the final say on whether a patch is merged or not.<br />
<br />
=== How does it work? === <br />
<br />
[https://invent.kde.org/qt/qt/qtbase Here] we have a version of Qt 5 that includes fixes for the issues we have found impacted the use of open source products. These patches can be obtained with the following command:<br />
git format-patch origin/5.15.2..origin/kde/5.15<br />
<br />
=== What is the license of the patches? === <br />
<br />
The patches will be licensed under the same licenses as the Qt Open Source edition module they apply against.<br />
<br />
=== How do I get this integrated in my distribution? === <br />
<br />
These patches can be obtained with the following command:<br />
git format-patch origin/5.15.2..origin/kde/5.15<br />
<br />
They can then be integrated using the tooling specific to your distribution.<br />
<br />
=== Will there be releases? === <br />
<br />
No, we will not make releases of the patch collection.<br />
<br />
=== Can I contribute new features? === <br />
<br />
No, this is strictly a stability patch collection.<br />
<br />
=== For how long will this be maintained? === <br />
<br />
We expect the patch collection to be maintained for as long as is required to serve users of Qt 5.15-based Open Source products, but to be ultimately made obsolete by the adoption of Qt 6 when Qt 6 enables superior Open Source product development.<br />
<br />
=== I do not want to sign the Qt Contribution Agreement, can i still contribute patches? === <br />
<br />
As mentioned, we generally only accept patches if they have been merged upstream first. The only circumstance in which we may accept a patch not covered by the Qt Contribution Agreement is if it does not apply upstream for technical reasons.<br />
<br />
=== I am a KDE developer, can I do direct pushes? === <br />
<br />
No, this project is a bit special and does not follow the same contribution rules the rest of KDE repositories.</div>Dfaurehttps://community.kde.org/index.php?title=Qt5PatchCollection&diff=91678Qt5PatchCollection2021-04-27T15:56:56Z<p>Dfaure: /* How do I get a patch merged? */</p>
<hr />
<div>=== What's this? ===<br />
<br />
This is a set of git repositories based on the last public commits available for Qt 5.15 branches with a curated collection of patches on top to ensure open source products can be used comfortably until users transition to their Qt 6-based ports.<br />
<br />
=== Which patches does it include?=== <br />
<br />
This collection of patches includes patches that fix at least one of the following:<br />
<br />
* Security issues<br />
* Crashes<br />
* Functional defects<br />
<br />
We only include patches that have been approved upstream in the Qt project. If a patch cannot be merged upstream for technical reasons (e.g. the class no longer exists), it can also be merged.<br />
<br />
The patches to merge will be decided based on their relevance towards Open Source products and their viability.<br />
<br />
=== How do I get a patch merged? === <br />
<br />
To get a patch merged you must open a Merge Request against the kde/5.15 branch on the corresponding repository in https://invent.kde.org/qt/qt, describing the change as well as the reason it should be merged (e.g. by referencing a relevant defect report in an open source product). Also required is a reference to where it was approved upstream within https://codereview.qt-project.org.<br />
<br />
Note that this is gitlab (not gerrit), but without the usual permissions for KDE developers. So everyone must fork the repo first.<br />
<br />
Also note that the repo is synced with upstream qt (several times a day), so the commit you want to backport will be in there already, in dev or a 6.x branch, you can just cherry-pick it. Then push to your fork, and create a merge request for branch kde/5.15.<br />
<br />
=== Who decides if a patch gets merged? ===<br />
<br />
There is a [https://invent.kde.org/groups/qt/qt/-/group_members group of curators] for this patch collection that will have the final say on whether a patch is merged or not.<br />
<br />
=== How does it work? === <br />
<br />
[https://invent.kde.org/qt/qt/qtbase Here] we have a version of Qt 5 that includes fixes for the issues we have found impacted the use of open source products. These patches can be obtained with the following command:<br />
git format-patch origin/5.15.2..origin/kde/5.15<br />
<br />
=== What is the license of the patches? === <br />
<br />
The patches will be licensed under the same licenses as the Qt Open Source edition module they apply against.<br />
<br />
=== How do I get this integrated in my distribution? === <br />
<br />
These patches can be obtained with the following command:<br />
git format-patch origin/5.15.2..origin/kde/5.15<br />
<br />
They can then be integrated using the tooling specific to your distribution.<br />
<br />
=== Will there be releases? === <br />
<br />
No, we will not make releases of the patch collection.<br />
<br />
=== Can I contribute new features? === <br />
<br />
No, this is strictly a stability patch collection.<br />
<br />
=== For how long will this be maintained? === <br />
<br />
We expect the patch collection to be maintained for as long as is required to serve users of Qt 5.15-based Open Source products, but to be ultimately made obsolete by the adoption of Qt 6 when Qt 6 enables superior Open Source product development.<br />
<br />
=== I do not want to sign the Qt Contribution Agreement, can i still contribute patches? === <br />
<br />
As mentioned, we generally only accept patches if they have been merged upstream first. The only circumstance in which we may accept a patch not covered by the Qt Contribution Agreement is if it does not apply upstream for technical reasons.<br />
<br />
=== I am a KDE developer, can I do direct pushes? === <br />
<br />
No, this project is a bit special and does not follow the same contribution rules the rest of KDE repositories.</div>Dfaurehttps://community.kde.org/index.php?title=Policies/Binary_Compatibility_Issues_With_C%2B%2B&diff=91558Policies/Binary Compatibility Issues With C++2021-04-16T10:19:42Z<p>Dfaure: Add item about QList/QVector iterators in public API, see "Crash when using KIdentityManagement::IdentityManager" on kde-pim.</p>
<hr />
<div><languages /><br />
<translate><br />
<br />
== Definition ==<br />
<br />
A library is '''binary compatible''', if a program linked dynamically to a former version of the library continues running with newer versions of the library without the need to recompile.<br />
<br />
If a program needs to be recompiled to run with a new version of library but doesn't require any further modifications, the library is '''source compatible'''.<br />
<br />
Binary compatibility saves a lot of trouble. It makes it much easier to distribute software for a certain platform. Without ensuring binary compatibility between releases, people will be forced to provide statically linked binaries. Static binaries are bad because they<br />
* waste resources (especially memory)<br />
* don't allow the program to benefit from bugfixes or extensions in the libraries<br />
<br />
In the KDE project, we will provide binary compatibility within the life-span of a major release for the core libraries (kdelibs, kdepimlibs).<br />
<br />
== Note about ABI ==<br />
<br />
This text applies to most C++ ABIs used by compilers which KDE can be built with. It is mostly based on the [https://itanium-cxx-abi.github.io/cxx-abi/abi.html Itanium C++ ABI Draft], which is used by the GCC C++ compiler since version 3.4 in all platforms it supports. Information about Microsoft Visual C++ mangling scheme mostly comes from [http://www.agner.org/optimize/calling_conventions.pdf this article on calling conventions] (it's the most complete information found so far on MSVC ABI and name mangling).<br />
<br />
Some of the constraints specified here may not apply to a given compiler. The goal here is to list the most restrictive set of conditions when writing cross-platform C++ code, meant to be compiled with several different compilers.<br />
<br />
This page is updated when new binary incompatibility issues are found.<br />
<br />
== The Do's and Don'ts ==<br />
<br />
You can...<br />
<br />
* add new non-virtual functions, including signals and slots and constructors, that do not overload non-overloaded functions.<br />
* add a new enum to a class.<br />
* append new enumerators to an existing enum.<br />
** Exception: if that leads to the compiler choosing a larger underlying type for the enum, that makes the change binary-incompatible. Unfortunately, compilers have some leeway to choose the underlying type, so from an API-design perspective it's recommended to add a '''Max....''' enumerator with an explicit large value ('''=255''', '''=1<<15''', etc) to create an interval of numeric enumerator values that is guaranteed to fit into the chosen underlying type, whatever that may be.<br />
* reimplement virtual functions defined in the primary base class hierarchy (that is, virtuals defined in the first non-virtual base class, or in that class's first non-virtual base class, and so forth) '''if''' it is safe that programs linked with the prior version of the library call the implementation in the base class rather than the derived one. ''This is tricky and might be dangerous. Think twice before doing it. Alternatively see below for a workaround.''<br />
** Exception: if the overriding function has a [http://en.wikipedia.org/wiki/Covariant_return_type covariant return type], it's only a binary-compatible change if the more-derived type has always the same pointer address as the less-derived one. ''If in doubt, do not override with a covariant return type.''<br />
* change an inline function or make an inline function non-inline '''if''' it is safe that programs linked with the prior version of the library call the old implementation. ''This is tricky and might be dangerous. Think twice before doing it.''<br />
* remove private non-virtual functions '''if''' they are not called by any inline functions (and have never been).<br />
* remove private static members '''if''' they are not called by any inline functions (and have never been).<br />
* add new '''static''' data members.<br />
* change the default arguments of a method. It requires recompilation to use the actual new default argument values, though.<br />
* add new classes.<br />
* export a class that was not previously exported.<br />
* add or remove friend declarations to classes.<br />
* rename reserved member types<br />
* extend reserved bit fields, provided this doesn't cause the bit field to cross the boundary of its underlying type (8 bits for char & bool, 16 bits for short, 32 bits for int, etc.)<br />
* add the Q_OBJECT macro to a class if the class already inherits from QObject<br />
* add a Q_PROPERTY, Q_ENUMS or Q_FLAGS macro as that only modifies the meta-object generated by moc and not the class itself<br />
<br />
You cannot...<br />
* For existing classes:<br />
** [[Policies/Binary_Compatibility_Examples#Unexport_or_remove_a_class|unexport or remove]] an exported class.<br />
** [[Policies/Binary_Compatibility_Examples#Change_the_class_hierarchy|change the class hierachy]] in any way (add, remove, or reorder base classes).<br />
** [[Policies/Binary_Compatibility_Examples#Remove_class_finality|Remove]] <code>final</code>ity<br />
* For template classes:<br />
** [[Policies/Binary_Compatibility_Examples#Change_the_template_arguments_of_a_template_class|change the template arguments]] in any way (add, remove or reorder).<br />
* For existing functions of any type:<br />
** [[Policies/Binary_Compatibility_Examples#Unexport_a_function|unexport]] it.<br />
** remove it.<br />
*** remove the implementation of existing declared functions. The symbol comes from the implementation of the function, so this is effectively the function.<br />
** [[Policies/Binary_Compatibility_Examples#Inline_a_function|inline]] it (this includes moving a member function's body to the class definition, even without the inline keyword).<br />
** add an overload (binary compatible, but not source compatible: it makes <code>&func</code> ambiguous). Adding overloads to already overloaded functions is ok (since any use of <code>&func</code> already needed a cast).<br />
** change its signature. This includes:<br />
*** changing any of the types of the arguments in the [[Policies/Binary_Compatibility_Examples#Change_the_parameters_of_a_function|parameter list]], including changing the <code>const</code>/<code>volatile</code> qualifiers of the existing parameters (instead, add a new method)<br />
*** changing the <code>const</code>/<code>volatile</code> qualifiers of the function<br />
*** changing the [[Policies/Binary_Compatibility_Examples#Change_the_access_rights|access rights]] to some functions or data members, for example from <tt>private</tt> to <tt>public</tt>. With some compilers, this information may be part of the signature. If you need to make a private function protected or even public, you have to add a new function that calls the private one.<br />
*** changing the [[Policies/Binary_Compatibility_Examples#Change_the_CV-qualifiers_of_a_member_function|CV-qualifiers of a member function]]: the <code>const</code> and/or <code>volatile</code> that apply to the function itself.<br />
*** extending a function with another parameter, even if this parameter has a default argument. ''See below for a suggestion on how to avoid this issue''<br />
*** changing the [[Policies/Binary_Compatibility_Examples#Change_the_return_type|return type]] in any way<br />
*** Exception: non-member functions declared with <code>extern "C"</code> can change parameter types ('''be very careful''').<br />
* For virtual member functions:<br />
** [[Policies/Binary_Compatibility_Examples#Add_a_virtual_member_function_to_a_class_without_any|add a virtual function]] to a class that doesn't have any virtual functions or virtual bases.<br />
** [[Policies/Binary_Compatibility_Examples#Add_new_virtuals_to_a_non-leaf_class|add new virtual functions]] to non-leaf classes as this will break subclasses. Note that a class designed to be sub-classed by applications is '''always''' a non-leaf class. ''See below for some workarounds or ask on mailing lists.''<br />
** add new virtual functions for any reason, even to leaf classes, ''if the class is intended to remain binary compatible on Windows''. Doing so may [http://lists.kde.org/?l=kde-core-devel&m=139744177410091&w=2 reorder existing virtual functions] and break binary compatibility.<br />
** [[Policies/Binary_Compatibility_Examples#Change_the_order_of_the_declaration_of_virtual_functions|change the order]] of virtual functions in the class declaration.<br />
** [[Policies/Binary_Compatibility_Examples#Override_a_virtual_that_doesn.27t_come_from_a_primary_base|override an existing virtual function if that function is not in the primary base class]] (the first non-virtual base class, or the primary base class's primary base class and upwards).<br />
** [[Policies/Binary_Compatibility_Examples#Override_a_virtual_with_a_covariant_return_with_different_top_address|override an existing virtual function]] if the overriding function has a [http://en.wikipedia.org/wiki/Covariant_return_type covariant return type] for which the more-derived type has a pointer address different from the less-derived one (usually happens when, between the less-derived and the more-derived ones, there's multiple inheritance or virtual inheritance).<br />
** Remove a virtual function, even if it is a reimplementation of a virtual function from the base class<br />
* For static non-private members or for non-static non-member public data:<br />
** Remove or unexport it<br />
** Change its [[Policies/Binary_Compatibility_Examples#Change_the_type_of_global_data|type]]<br />
** Change its [[Policies/Binary_Compatibility_Examples#Change_the_CV-qualifiers_of_global_data|CV-qualifiers]]<br />
* For non-static members:<br />
** add new data members to an existing class.<br />
** change the order of non-static data members in a class.<br />
** change the type of the member, except for signedness (or more generally if the types are guaranteed to have the same size, and the member is not used by any inline method)<br />
** remove existing non-static data members from an existing class.<br />
* return (or take as parameter) an iterator to a Qt container, in public API. This is not binary compatible if the library doing that is compiled with QT_STRICT_ITERATORS and the lib/app using that API isn't, or vice-versa. Return a reference to (or a copy of) the container instead.<br />
<br />
If you need to add extend/modify the parameter list of an existing function, you need to add a new function instead with the new parameters. In that case, you may want to add a short note that the two functions shall be merged with a default argument in later versions of the library:<br />
<br />
<source lang="cpp-qt"><br />
void functionname( int a );<br />
void functionname( int a, int b ); //BCI: merge with int b = 0<br />
</source><br />
<br />
You should...<br />
<br />
In order to make a class to extend in the future you should follow these rules:<br />
* add d-pointer. ''See below''.<br />
* add non-inline virtual destructor even if the body is empty.<br />
* reimplement <code>event</code> in QObject-derived classes, even if the body for the function is just calling the base class' implementation. This is specifically to avoid problems caused by adding a reimplemented virtual function as discussed below.<br />
* make all constructors non-inline.<br />
* write non-inline implementations of the copy constructor and assignment operator unless the class cannot be copied by value. (E.g. classes inherited from QObject can't be.)<br />
<br />
== Techniques for Library Programmers ==<br />
<br />
The biggest problem when writing libraries is, that one cannot safely add data members since this would change the size and layout of every class, struct, or array containing objects of the type, including subclasses.<br />
<br />
=== Bitflags ===<br />
One exception are bitflags. If you use bitflags for enums or bools, you can safely round up to at least the next byte minus 1. A class with members<br />
<br />
<source lang="cpp-qt"><br />
uint m1 : 1;<br />
uint m2 : 3;<br />
uint m3 : 1;<br />
</source><br />
<source lang="cpp-qt"><br />
uint m1 : 1;<br />
uint m2 : 3;<br />
uint m3 : 1;<br />
uint m4 : 2; // new member<br />
</source><br />
without breaking binary compatibility. Please round up to a maxmimum of 7 bits (or 15 if the bitfield was already larger than 8). Using the very last bit may cause problems on some compilers.<br />
<br />
=== Using a d-Pointer===<br />
Bitflags and predefined reserved variables are nice, but far from being sufficient. This is where the d-pointer technique comes into play. The name "d-pointer" stems from Trolltech's Arnt Gulbrandsen, who first introduced the technique into Qt, making it one of the first C++ GUI libraries to maintain binary compatibility even between bigger release. The technique was quickly adapted as general programming pattern for the KDE libraries by everyone who saw it. It's a great trick to be able to add new private data members to a class without breaking binary compatibility.<br />
<br />
'''Remark:''' The d-pointer pattern has been described many<br />
times in computer science history under various names, e.g. as pimpl,<br />
as handle/body or as cheshire cat. Google helps finding online papers<br />
for any of these, just add C++ to the search terms.<br />
<br />
In your class definition for class Foo, define a forward declaration<br />
<source lang="cpp-qt"><br />
class FooPrivate;<br />
</source><br />
and the d-pointer in the private section:<br />
<source lang="cpp-qt"><br />
private:<br />
FooPrivate* d;<br />
</source><br />
The FooPrivate class itself is purely defined in the class implementation file (usually *.cpp ), for example:<br />
<source lang="cpp-qt"><br />
class FooPrivate {<br />
public:<br />
FooPrivate()<br />
: m1(0), m2(0)<br />
{}<br />
int m1;<br />
int m2;<br />
QString s;<br />
};<br />
</source><br />
<br />
All you have to do now is to create the private data in your constructors or your init function with<br />
<source lang="cpp-qt"><br />
d = new FooPrivate;<br />
</source><br />
and to delete it again in your destructor with<br />
<source lang="cpp-qt"><br />
delete d;<br />
</source><br />
<br />
In most circumstances you will want to make the dpointer constant to catch situations where it's accidentally getting modified or copied over so you'd lose ownership of the private object and create a memory leak:<br />
<source lang="cpp-qt"><br />
private:<br />
FooPrivate* const d;<br />
</source><br />
This allows you to modify the object pointed to by d but not the value of the pointer after it has been initialized.<br />
<br />
You may not want all member variables to live in the private data object, though. For very often used members, it's faster to put them directly in the class, since inline functions cannot access the d-pointer data. Also note that all data covered by the d-pointer is "private", despite being declared public in the d-pointer itself. For public or protected access, provide both a set and a get function. Example<br />
<source lang="cpp-qt"><br />
QString Foo::string() const<br />
{<br />
return d->s;<br />
}<br />
<br />
void Foo::setString( const QString& s )<br />
{<br />
d->s = s;<br />
}<br />
</source><br />
<br />
It is also possible (but not recommended) to declare the private class for the d-pointer as a nested private class (e.g. Foo::Private). If you use this technique, remember that the nested private class will inherit the public symbol visibility of the containing exported class. This will cause the functions of the private class to be named in the dynamic library's symbol table. You can use <code>Q_DECL_HIDDEN</code> in the implementation of the nested private class to manually re-hide the symbols. (For an existing class, this is technically an ABI change, but does not impact the public ABI supported by the KDE developers, so private symbols mistaken exposed may be re-hidden without further warning.). Other downsides of the nested private class include the lack of consistency with Qt and its Q_D/Q_Q macros, and the fact that it can't be forward-declared in unrelated headers anymore (which can be useful to declare it as a friend class). For all these reasons, prefer FooPrivate.<br />
<br />
<h2>Trouble shooting</h2><br />
<br />
=== Adding new data members to classes without d-pointer === <br />
<br />
If you don't have free bitflags, reserved variables and no d-pointer either, but you absolutely have to add a new private member variable, there are still some possibilities left. If your class inherits {{qt|QObject}}, you can for example place the additional data in a special child and find it by traversing over the list of children. You can access the list of children with QObject::children(). However, a fancier and usually faster approach is to use a hashtable to store a<br />
mapping between your object and the extra data. For this purpose, Qt provides a pointer-based dictionary called {{qt|QHash}} (or {{qt3|QPtrDict}} in Qt3).<br />
<br />
The basic trick in your class implementation of class Foo is:<br />
* Create a private data class FooPrivate.<br />
* Create a static QHash&lt;Foo *, FooPrivate *&gt;.<br />
*Note that some compilers/linkers (almost all, unfortunately) do not manage to create static objects in shared libraries. They simply forget to call the constructor. Therefore you should use the <tt>Q_GLOBAL_STATIC</tt> macro to create and access the object:<br />
<br />
<source lang="cpp-qt"><br />
// BCI: Add a real d-pointer<br />
typedef QHash<Foo *, FooPrivate *> FooPrivateHash;<br />
Q_GLOBAL_STATIC(FooPrivateHash, d_func)<br />
static FooPrivate *d(const Foo *foo)<br />
{<br />
FooPrivate *ret = d_func()->value(foo);<br />
if ( ! ret ) {<br />
ret = new FooPrivate;<br />
d_func()->insert(foo, ret);<br />
}<br />
return ret;<br />
}<br />
static void delete_d(const Foo *foo)<br />
{<br />
FooPrivate *ret = d_func()->value(foo);<br />
delete ret;<br />
d_func()->remove(foo);<br />
}<br />
</source><br />
<br />
* Now you can use the d-pointer in your class almost as simple as in the code before, just with a function call to d(this). For example:<br />
<br />
<source lang="cpp-qt"><br />
d(this)->m1 = 5;<br />
</source><br />
<br />
* Add a line to your destructor:<br />
<source lang="cpp-qt"><br />
delete_d(this);<br />
</source><br />
* Do not forget to add a BCI remark, so that the hack can be removed in the next version of the library.<br />
* Do not forget to add a d-pointer to your next class.<br />
<br />
=== Adding a reimplemented virtual function ===<br />
<br />
As already explained, you can safely reimplement a virtual function defined in one of the base classes only if it is safe that the programs linked with the prior version call the implementation in the base class rather than the derived one. This is because the compiler sometimes calls virtual functions directly if it can determine which one to call. For example, if you have <br />
<source lang="cpp-qt"><br />
void C::foo()<br />
{<br />
B::foo();<br />
}<br />
</source><br />
<br />
then B::foo() is called directly. If class B inherits from class A which implements foo() and B itself doesn't reimplement it, then C::foo() will in fact call A::foo(). If a newer version of the library adds B::foo(), C::foo() will call it only after a recompilation.<br />
<br />
Another more common example is:<br />
<source lang="cpp-qt"><br />
B b; // B derives from A<br />
b.foo();<br />
</source><br />
then the call to foo() will not use the virtual table. That means that<br />
if B::foo() didn't exist in the library but now does, code that was<br />
compiled with the earlier version will still call A::foo().<br />
<br />
If you can't guarantee things will continue to work without a recompilation, move functionality from A::foo() to a new protected function A::foo2() and use this code:<br />
<source lang="cpp-qt"><br />
void A::foo()<br />
{<br />
if( B* b = dynamic_cast< B* >( this ))<br />
b->B::foo(); // B:: is important<br />
else<br />
foo2();<br />
}<br />
void B::foo()<br />
{<br />
// added functionality<br />
A::foo2(); // call base function with real functionality<br />
}<br />
</source><br />
All calls to A::foo() for objects of type B (or inherited) will result in calling B::foo(). The only case that will not work as expected are calls to A::foo() that explicitly specify A::foo(), but B::foo() calls A::foo2() instead and there should not be other places doing so.<br />
<br />
=== Using a new class ===<br />
<br />
A relatively simple method of "extending" a class can be writing a replacement class that will include also the new functionality (and that may inherit from the old class to reuse the code). This of course requires adapting and recompiling applications using the library, so it is not possible this way to fix or extend functionality of classes that are used by applications compiled against an older version of the library. However, especially with small and/or performance-critical classes it may be simpler to write them without making sure they'll be simple to extend in the future and if the need arises later write a new replacement class that will provide new features or better performance.<br />
<br />
=== Adding new virtual functions to leaf classes ===<br />
This technique is one of cases of using a new class that can help if there's a need to add new virtual functions to a class that should stay binary compatible and there is no class inheriting from it that should also stay binary compatible (i.e. all classes inheriting from it are in applications). In such case it's possible to add a new class inheriting from the original one that will add them. Applications using the new functionality will of course have to be modified to use the new class.<br />
<source lang="cpp-qt"><br />
class A {<br />
public:<br />
virtual void foo();<br />
};<br />
class B : public A { // newly added class<br />
public:<br />
virtual void bar(); // newly added virtual function<br />
};<br />
void A::foo()<br />
{<br />
// here it's needed to call a new virtual function<br />
if( B* this2 = dynamic_cast< B* >( this ))<br />
this2->bar();<br />
}<br />
</source><br />
It is not possible to use this technique when there are other inherited classes that should also stay binary compatible because they'd have to inherit from the new class.<br />
<br />
=== Using signals instead of virtual functions ===<br />
Qt's signals and slots are invoked using a special virtual method created by the Q_OBJECT macro and it exists in every class inherited from {{qt|QObject}}. Therefore adding new signals and slots doesn't affect binary compatibility and the signals/slots mechanism can be used to emulate virtual functions.<br />
<br />
<source lang="cpp-qt"><br />
class A : public QObject {<br />
Q_OBJECT<br />
public:<br />
A();<br />
virtual void foo();<br />
signals:<br />
void bar( int* ); // added new "virtual" function<br />
protected slots:<br />
// implementation of the virtual function in A<br />
void barslot( int* );<br />
};<br />
<br />
A::A()<br />
{<br />
connect(this, SIGNAL( bar(int*)), this, SLOT( barslot(int*)));<br />
}<br />
<br />
void A::foo()<br />
{<br />
int ret;<br />
emit bar( &ret );<br />
}<br />
<br />
void A::barslot( int* ret )<br />
{<br />
*ret = 10;<br />
}<br />
</source><br />
<br />
Function bar() will act like a virtual function, barslot() implements the actual functionality of it. Since signals have void return value, data must be returned using arguments. As there will be only one slot connected to the signal returning data from the slot this way will work without problems. Note that with Qt4 for this to work the connection type will have to be Qt::DirectConnection.<br />
<br />
If an inherited class will want to re-implement the functionality of bar() it will have to provide its own slot:<br />
<source lang="cpp-qt"><br />
class B : public A {<br />
Q_OBJECT<br />
public:<br />
B();<br />
protected slots: // necessary to specify as a slot again<br />
void barslot( int* ); // reimplemented functionality of bar()<br />
};<br />
<br />
B::B()<br />
{<br />
disconnect(this, SIGNAL(bar(int*)), this, SLOT(barslot(int*)));<br />
connect(this, SIGNAL(bar(int*)), this, SLOT(barslot(int*)));<br />
}<br />
<br />
void B::barslot( int* ret )<br />
{<br />
*ret = 20;<br />
}<br />
</source><br />
<br />
Now B::barslot() will act like virtual reimplementation of A::bar(). Note that it is necessary to specify barslot() again as a slot in B and that in the constructor it is necessary to first disconnect and then connect again, that will disconnect A::barslot() and connect B::barslot() instead.<br />
<br />
Note: the same can be accomplished by implementing a virtual slot.<br />
<br />
[[Category:Policies]] [[Category:C++]]<br />
</translate></div>Dfaurehttps://community.kde.org/index.php?title=Frameworks/Policies&diff=91438Frameworks/Policies2021-04-04T11:58:07Z<p>Dfaure: /* Frameworks compiler requirements and C++11 */</p>
<hr />
<div><br />
== Frameworks have a Tier and a Type ==<br />
Each framework has a clear position in the Tier/Type matrix, its position forces a set of rules on its possible dependencies. This matrix and its rules are summarized in the [http://files.kde.org/frameworks/kde-frameworks-matrix.pdf Frameworks matrix document].<br />
<br />
<br />
The constraints from Tiers are the following:<br />
* Tier 1 Frameworks can depend only on Qt official frameworks or other system libraries;<br />
* Tier 2 Frameworks can depend only on Tier 1 Frameworks, Qt official frameworks, or other system libraries;<br />
* Tier 3 Frameworks can depend only on other Tier 3 Frameworks, Tier 2 Frameworks, Tier 1 Frameworks, Qt official frameworks, or other system libraries.<br />
<br />
<br />
The constraints from Types are the following:<br />
* Functional Qt Addons cannot have runtime dependencies;<br />
* Integration Qt Addons can have an optional runtime dependencies and aim at integrating with the underlying OS/Platform;<br />
* Solutions have mandatory runtime dependencies, it is part of their design and where their added value comes from (think scalability, resource sharing, resilience, etc.).<br />
<br />
== Framework directory structure ==<br />
All the frameworks will have the same directory structure which will follow some rules:<br />
* The containing directory has the name of the technology (plasma, kio, itemmodels, etc.);<br />
* At the top level we find the common files like README.md, metainfo.yaml...<br />
* More comprehensive documentation go into a '''docs''' subdirectory<br />
* The source code for the targets go into '''src''' subdirectory, if several payloads are built (like a core lib and a gui layer on top) then src will contain one subdirectory per library: core, gui, widgets, etc.<br />
* All license texts go into a '''LICENSES''' subdirectory (following the [https://reuse.software/spec/ REUSE.software specification])<br />
* Code examples go into an '''examples''' subdirectory<br />
* Automatic tests go into an '''autotests''' subdirectory<br />
* Test applications go into a '''tests''' subdirectory<br />
* CMake modules (FindFoo.cmake etc.) or CMake macro files go into '''cmake''' subdirectory<br />
<br />
== Frameworks have automatic unit tests ==<br />
Enough said really... They must be unit tested with automatic unit tests.<br />
<br />
Corollary: When fixing a bug in a framework, the auto-test proving the bug and the fix should come in the same commit.<br />
<br />
== Frameworks maintain binary compatibility ==<br />
Just like we did in kdelibs, KDE Frameworks maintain the binary compatibility through their lifetime, for more details see the [[Policies/Binary_Compatibility_Issues_With_C++| binary compatibility policy]].<br />
<br />
Note however that this policy is lifted during major version transition, corresponding epics of milestones will be marked as such.<br />
<br />
== Frameworks are documented ==<br />
<br />
The API exposed by frameworks are documented using Doxygen. Documentation follows the [[Frameworks/Frameworks_Documentation_Policy|Frameworks Documentation Policy]].<br />
<br />
== Frameworks are localized ==<br />
<br />
Frameworks adapt to the user language and locale settings. This is described in the [[Frameworks/Frameworks_Localization_Policy|Frameworks Localization Policy]].<br />
<br />
== Frameworks use Qt's categorized logging ==<br />
<br />
Frameworks make use of [https://doc.qt.io/qt-5/qloggingcategory.html Qt's categorized logging system]. with standardized logging categories. This is described in the [[Frameworks/Frameworks_Logging_Policy|Frameworks Logging Policy]].<br />
<br />
== Frameworks buildsystem is consistent ==<br />
<br />
* each framework should install a CMake configuration file for itself. This includes:<br />
** a FooConfig.cmake file<br />
** a FooConfigVersion.cmake file<br />
** usually a FooTargets.cmake file<br />
** optionally a file containing macros/functions for using the package<br />
* no framework should install any other CMake files than mentioned above. Find-modules useful for multiple packages should be upstreamed into extra-cmake-modules if they are generally useful. <br />
* For especially exotic packages which are not suitable for extra-cmake-modules, it is ok for a framework to have extra find modules, but they should not be installed.<br />
* Library names are in CamelCase<br />
* All dependencies between frameworks are documented in the CMakeLists.txt (see for instance kio/src/core/CMakeLists.txt)<br />
<br />
For an example, see the [http://quickgit.kde.org/?p=kdeexamples.git&a=tree&f=framework-template framework-template] directory in the kdeexamples repository (you can use setup.sh to create a template that matches the name of your framework).<br />
<br />
== Frameworks commits are reviewed ==<br />
Make sure all commits in the master branch of a repository part of the KDE Frameworks got a proper review. As such commits must contain either a "Reviewed by:" (for quick pastebin reviews) or a "REVIEW:" (for more formal reviewboard reviews).<br />
<br />
== Frameworks CI failures are treated as stop the line events ==<br />
When a commit causes a regression in the CI for one of the frameworks, then all work on the corresponding framework should stop. The only commits allowed in are those working toward a resolution of the problem. Only once the framework is green again that regular work can be resumed.<br />
<br />
== Frameworks Qt requirements ==<br />
KDE Frameworks are tested and working with the last 3 minor Qt releases. For instance, once Qt 5.11 was released, the minimum required Qt version changed from Qt 5.8 to Qt 5.9, i.e. the three supported Qt versions became 5.9, 5.10 and 5.11.<br />
<br />
In addition, a Qt LTS release remains supported until the next Qt release after the next Qt LTS release.<br />
For instance, when Qt 5.12 is released, Qt 5.9 remains supported until Qt 5.13, to give time for people to migrate from Qt 5.9 LTS to Qt 5.12 LTS. When Qt 5.13 is released, both Qt 5.9 LTS and Qt 5.10 are dropped, to go back to "last 3 minor Qt releases".<br />
<br />
With Qt6 this changes a little bit again. We interpolate "as if" more Qt 5 versions would be released:<br />
* Qt 5.13 will be the minimum required version 6 months after Qt 5.15, i.e. on 26 Nov 2020<br />
* Qt 5.14 would be the minimum required version 12 months after Qt 5.15, i.e. on 26 May 2021. With no-one known to stick with Qt 5.13 at the time, the date was moved to earlier mid-December 2020 (see [https://mail.kde.org/pipermail/kde-frameworks-devel/2020-December/114832.html discussion])<br />
* Qt 5.15 LTS was planned to be the minimum required version 18 months after its release, i.e. on 26 Nov 2021. To help preparing for Qt 6, the date was moved to beginning of April 2021, as discussed in the KF6 sprint, and [https://mail.kde.org/pipermail/kde-frameworks-devel/2021-April/116818.html] confirmed in the next meeting.<br />
<br />
The bumping of the minimum required version in the code is done at the begin of the release cycle of the next KF version affected, right after the release of the previous one.<br />
<br />
== Frameworks compiler requirements and Modern C++ ==<br />
The following minimal compiler versions are supported by KDE Frameworks (starting from version 5.82) :<br />
* GCC 8<br />
* Clang 6<br />
* MSVC 2017<br />
<br />
This means all of the C++11 and C++14 standards can be used, as well as most of C++17 (not std::filesystem).</div>Dfaurehttps://community.kde.org/index.php?title=Frameworks/Policies&diff=91437Frameworks/Policies2021-04-04T11:56:05Z<p>Dfaure: Qt 5.15</p>
<hr />
<div><br />
== Frameworks have a Tier and a Type ==<br />
Each framework has a clear position in the Tier/Type matrix, its position forces a set of rules on its possible dependencies. This matrix and its rules are summarized in the [http://files.kde.org/frameworks/kde-frameworks-matrix.pdf Frameworks matrix document].<br />
<br />
<br />
The constraints from Tiers are the following:<br />
* Tier 1 Frameworks can depend only on Qt official frameworks or other system libraries;<br />
* Tier 2 Frameworks can depend only on Tier 1 Frameworks, Qt official frameworks, or other system libraries;<br />
* Tier 3 Frameworks can depend only on other Tier 3 Frameworks, Tier 2 Frameworks, Tier 1 Frameworks, Qt official frameworks, or other system libraries.<br />
<br />
<br />
The constraints from Types are the following:<br />
* Functional Qt Addons cannot have runtime dependencies;<br />
* Integration Qt Addons can have an optional runtime dependencies and aim at integrating with the underlying OS/Platform;<br />
* Solutions have mandatory runtime dependencies, it is part of their design and where their added value comes from (think scalability, resource sharing, resilience, etc.).<br />
<br />
== Framework directory structure ==<br />
All the frameworks will have the same directory structure which will follow some rules:<br />
* The containing directory has the name of the technology (plasma, kio, itemmodels, etc.);<br />
* At the top level we find the common files like README.md, metainfo.yaml...<br />
* More comprehensive documentation go into a '''docs''' subdirectory<br />
* The source code for the targets go into '''src''' subdirectory, if several payloads are built (like a core lib and a gui layer on top) then src will contain one subdirectory per library: core, gui, widgets, etc.<br />
* All license texts go into a '''LICENSES''' subdirectory (following the [https://reuse.software/spec/ REUSE.software specification])<br />
* Code examples go into an '''examples''' subdirectory<br />
* Automatic tests go into an '''autotests''' subdirectory<br />
* Test applications go into a '''tests''' subdirectory<br />
* CMake modules (FindFoo.cmake etc.) or CMake macro files go into '''cmake''' subdirectory<br />
<br />
== Frameworks have automatic unit tests ==<br />
Enough said really... They must be unit tested with automatic unit tests.<br />
<br />
Corollary: When fixing a bug in a framework, the auto-test proving the bug and the fix should come in the same commit.<br />
<br />
== Frameworks maintain binary compatibility ==<br />
Just like we did in kdelibs, KDE Frameworks maintain the binary compatibility through their lifetime, for more details see the [[Policies/Binary_Compatibility_Issues_With_C++| binary compatibility policy]].<br />
<br />
Note however that this policy is lifted during major version transition, corresponding epics of milestones will be marked as such.<br />
<br />
== Frameworks are documented ==<br />
<br />
The API exposed by frameworks are documented using Doxygen. Documentation follows the [[Frameworks/Frameworks_Documentation_Policy|Frameworks Documentation Policy]].<br />
<br />
== Frameworks are localized ==<br />
<br />
Frameworks adapt to the user language and locale settings. This is described in the [[Frameworks/Frameworks_Localization_Policy|Frameworks Localization Policy]].<br />
<br />
== Frameworks use Qt's categorized logging ==<br />
<br />
Frameworks make use of [https://doc.qt.io/qt-5/qloggingcategory.html Qt's categorized logging system]. with standardized logging categories. This is described in the [[Frameworks/Frameworks_Logging_Policy|Frameworks Logging Policy]].<br />
<br />
== Frameworks buildsystem is consistent ==<br />
<br />
* each framework should install a CMake configuration file for itself. This includes:<br />
** a FooConfig.cmake file<br />
** a FooConfigVersion.cmake file<br />
** usually a FooTargets.cmake file<br />
** optionally a file containing macros/functions for using the package<br />
* no framework should install any other CMake files than mentioned above. Find-modules useful for multiple packages should be upstreamed into extra-cmake-modules if they are generally useful. <br />
* For especially exotic packages which are not suitable for extra-cmake-modules, it is ok for a framework to have extra find modules, but they should not be installed.<br />
* Library names are in CamelCase<br />
* All dependencies between frameworks are documented in the CMakeLists.txt (see for instance kio/src/core/CMakeLists.txt)<br />
<br />
For an example, see the [http://quickgit.kde.org/?p=kdeexamples.git&a=tree&f=framework-template framework-template] directory in the kdeexamples repository (you can use setup.sh to create a template that matches the name of your framework).<br />
<br />
== Frameworks commits are reviewed ==<br />
Make sure all commits in the master branch of a repository part of the KDE Frameworks got a proper review. As such commits must contain either a "Reviewed by:" (for quick pastebin reviews) or a "REVIEW:" (for more formal reviewboard reviews).<br />
<br />
== Frameworks CI failures are treated as stop the line events ==<br />
When a commit causes a regression in the CI for one of the frameworks, then all work on the corresponding framework should stop. The only commits allowed in are those working toward a resolution of the problem. Only once the framework is green again that regular work can be resumed.<br />
<br />
== Frameworks Qt requirements ==<br />
KDE Frameworks are tested and working with the last 3 minor Qt releases. For instance, once Qt 5.11 was released, the minimum required Qt version changed from Qt 5.8 to Qt 5.9, i.e. the three supported Qt versions became 5.9, 5.10 and 5.11.<br />
<br />
In addition, a Qt LTS release remains supported until the next Qt release after the next Qt LTS release.<br />
For instance, when Qt 5.12 is released, Qt 5.9 remains supported until Qt 5.13, to give time for people to migrate from Qt 5.9 LTS to Qt 5.12 LTS. When Qt 5.13 is released, both Qt 5.9 LTS and Qt 5.10 are dropped, to go back to "last 3 minor Qt releases".<br />
<br />
With Qt6 this changes a little bit again. We interpolate "as if" more Qt 5 versions would be released:<br />
* Qt 5.13 will be the minimum required version 6 months after Qt 5.15, i.e. on 26 Nov 2020<br />
* Qt 5.14 would be the minimum required version 12 months after Qt 5.15, i.e. on 26 May 2021. With no-one known to stick with Qt 5.13 at the time, the date was moved to earlier mid-December 2020 (see [https://mail.kde.org/pipermail/kde-frameworks-devel/2020-December/114832.html discussion])<br />
* Qt 5.15 LTS was planned to be the minimum required version 18 months after its release, i.e. on 26 Nov 2021. To help preparing for Qt 6, the date was moved to beginning of April 2021, as discussed in the KF6 sprint, and [https://mail.kde.org/pipermail/kde-frameworks-devel/2021-April/116818.html] confirmed in the next meeting.<br />
<br />
The bumping of the minimum required version in the code is done at the begin of the release cycle of the next KF version affected, right after the release of the previous one.<br />
<br />
== Frameworks compiler requirements and C++11 ==<br />
The following minimal compiler versions are supported by KDE Frameworks:<br />
* GCC 5 (4.8 for KF < 5.78)<br />
* Clang 4.0 (? Qt does not specify a version, assume what FreeBSD & on macOS XCode have)<br />
* MSVC 2015<br />
<br />
This means all of the C++11 standards can be used.<br />
<br />
These requirements come from https://doc.qt.io/qt-5.14/supported-platforms.html</div>Dfaurehttps://community.kde.org/index.php?title=Sprints/KF6/2021Virtual&diff=91388Sprints/KF6/2021Virtual2021-03-27T18:56:26Z<p>Dfaure: Add UTC time slots</p>
<hr />
<div>==KF6 Sprint 2021==<br />
<br />
'''Where''': Online!<br />
<br />
'''When''': March 27-28<br />
<br />
'''Main BigBlueButton room''': https://meet.kde.org/b/ada-mi8-aem<br />
* If you want to discuss a smaller topic with smaller group of people, you can ask to create a breakout room inside this room.<br />
<br />
'''Discussion on Matrix''': [https://matrix.to/#/#kf6:kde.org #kf6:kde.org]<br />
<br />
'''Discussion on IRC''': [irc://chat.freenode.net/#kde-sprints-kf6 #kde-sprints-kf6]<br />
<br />
<br />
==Attendance==<br />
<br />
Poll to select the weekend:<br />
https://framadate.org/LGvewKljewnW6836<br />
<br />
== Program ==<br />
<br />
Example topics. Feel free to edit and add yours (you can also add your name if you'd like to drive the topic/discussion/workshop)<br />
<br />
* Reviewing the KF6 board (https://phabricator.kde.org/project/board/310/):<br />
** Clean up<br />
** Tagging Junior Jobs<br />
* Working out a structure/process for handling:<br />
** "Stuck" tasks<br />
** Unit test regressions<br />
* Decide the 5.15 minimum requirement bump timeline<br />
* Decide on a 6 branching strategy and timeline<br />
* Decide if/how ECM should support multiple Qt versions<br />
<br />
'''Times are in Europe/Berlin'''.<br />
<br />
Note that most European countries move their clocks forward between the night of Saturday and Sunday https://www.timeanddate.com/news/time/europe-starts-dst-2021.html<br />
<br />
{| class="wikitable"<br />
|-<br />
! Time slot (Berlin time) !! Saturday !! Sunday !! Sunday Time slot (UTC)<br />
|-<br />
| 10:00 - 11:00 || sleeping || ''free slot'' || 08:00 - 09:00<br />
|-<br />
| 11:00 - 12:00 || Welcome & planning || ''free slot'' || 09:00 - 10:00<br />
|-<br />
| 12:00 - 14:00 || Break || Break || 10:00 - 12:00<br />
|-<br />
| 14:00 - 15:00 || ''free slot'' || ''free slot'' || 12:00 - 13:00<br />
|-<br />
| 15:00 - 16:00 || ''free slot'' || ''free slot'' || 13:00 - 14:00<br />
|-<br />
| 16:00 - 17:00 || ''free slot'' || ''free slot'' || 14:00 - 15:00<br />
|-<br />
| 17:00 - 18:00 || ''free slot'' || ''free slot'' || 15:00 - 16:00<br />
|-<br />
| 18:00 - 20:00 || Social Event || Social Event || 16:00 - 18:00<br />
|-<br />
|}<br />
<br />
Social events will happen in [https://play.workadventu.re/@/ipsquad/virtual_drinks/kf6_social_event_at_6pm "the KF6 virtual pub"]. Bring your finger food and drinks!<br />
<br />
== Notes ==<br />
<br />
Shared notes: https://share.kde.org/s/BD9B9RDM2SEMK59</div>Dfaurehttps://community.kde.org/index.php?title=Policies/Binary_Compatibility_Issues_With_C%2B%2B&diff=90803Policies/Binary Compatibility Issues With C++2021-01-02T18:24:34Z<p>Dfaure: expand "changing the type of a member"</p>
<hr />
<div><languages /><br />
<translate><br />
<br />
== Definition ==<br />
<br />
A library is '''binary compatible''', if a program linked dynamically to a former version of the library continues running with newer versions of the library without the need to recompile.<br />
<br />
If a program needs to be recompiled to run with a new version of library but doesn't require any further modifications, the library is '''source compatible'''.<br />
<br />
Binary compatibility saves a lot of trouble. It makes it much easier to distribute software for a certain platform. Without ensuring binary compatibility between releases, people will be forced to provide statically linked binaries. Static binaries are bad because they<br />
* waste resources (especially memory)<br />
* don't allow the program to benefit from bugfixes or extensions in the libraries<br />
<br />
In the KDE project, we will provide binary compatibility within the life-span of a major release for the core libraries (kdelibs, kdepimlibs).<br />
<br />
== Note about ABI ==<br />
<br />
This text applies to most C++ ABIs used by compilers which KDE can be built with. It is mostly based on the [https://itanium-cxx-abi.github.io/cxx-abi/abi.html Itanium C++ ABI Draft], which is used by the GCC C++ compiler since version 3.4 in all platforms it supports. Information about Microsoft Visual C++ mangling scheme mostly comes from [http://www.agner.org/optimize/calling_conventions.pdf this article on calling conventions] (it's the most complete information found so far on MSVC ABI and name mangling).<br />
<br />
Some of the constraints specified here may not apply to a given compiler. The goal here is to list the most restrictive set of conditions when writing cross-platform C++ code, meant to be compiled with several different compilers.<br />
<br />
This page is updated when new binary incompatibility issues are found.<br />
<br />
== The Do's and Don'ts ==<br />
<br />
You can...<br />
<br />
* add new non-virtual functions including signals and slots and constructors.<br />
* add a new enum to a class.<br />
* append new enumerators to an existing enum.<br />
** Exeption: if that leads to the compiler choosing a larger underlying type for the enum, that makes the change binary-incompatible. Unfortunately, compilers have some leeway to choose the underlying type, so from an API-design perspective it's recommended to add a '''Max....''' enumerator with an explicit large value ('''=255''', '''=1<<15''', etc) to create an interval of numeric enumerator values that is guaranteed to fit into the chosen underlying type, whatever that may be.<br />
* reimplement virtual functions defined in the primary base class hierarchy (that is, virtuals defined in the first non-virtual base class, or in that class's first non-virtual base class, and so forth) '''if''' it is safe that programs linked with the prior version of the library call the implementation in the base class rather than the derived one. ''This is tricky and might be dangerous. Think twice before doing it. Alternatively see below for a workaround.''<br />
** Exception: if the overriding function has a [http://en.wikipedia.org/wiki/Covariant_return_type covariant return type], it's only a binary-compatible change if the more-derived type has always the same pointer address as the less-derived one. ''If in doubt, do not override with a covariant return type.''<br />
* change an inline function or make an inline function non-inline '''if''' it is safe that programs linked with the prior version of the library call the old implementation. ''This is tricky and might be dangerous. Think twice before doing it.''<br />
* remove private non-virtual functions '''if''' they are not called by any inline functions (and have never been).<br />
* remove private static members '''if''' they are not called by any inline functions (and have never been).<br />
* add new '''static''' data members.<br />
* change the default arguments of a method. It requires recompilation to use the actual new default argument values, though.<br />
* add new classes.<br />
* export a class that was not previously exported.<br />
* add or remove friend declarations to classes.<br />
* rename reserved member types<br />
* extend reserved bit fields, provided this doesn't cause the bit field to cross the boundary of its underlying type (8 bits for char & bool, 16 bits for short, 32 bits for int, etc.)<br />
* add the Q_OBJECT macro to a class if the class already inherits from QObject<br />
* add a Q_PROPERTY, Q_ENUMS or Q_FLAGS macro as that only modifies the meta-object generated by moc and not the class itself<br />
<br />
You cannot...<br />
* For existing classes:<br />
** [[Policies/Binary_Compatibility_Examples#Unexport_or_remove_a_class|unexport or remove]] an exported class.<br />
** [[Policies/Binary_Compatibility_Examples#Change_the_class_hierarchy|change the class hierachy]] in any way (add, remove, or reorder base classes).<br />
** [[Policies/Binary_Compatibility_Examples#Remove_class_finality|Remove]] <code>final</code>ity<br />
* For template classes:<br />
** [[Policies/Binary_Compatibility_Examples#Change_the_template_arguments_of_a_template_class|change the template arguments]] in any way (add, remove or reorder).<br />
* For existing functions of any type:<br />
** [[Policies/Binary_Compatibility_Examples#Unexport_a_function|unexport]] it.<br />
** remove it.<br />
*** Remove the implementation of existing declared functions. The symbol comes from the implementation of the function, so this is effectively the function.<br />
** [[Policies/Binary_Compatibility_Examples#Inline_a_function|inline]] it (this includes moving a member function's body to the class definition, even without the inline keyword).<br />
** add an overload (BC, but not SC: makes <tt>&func</tt> ambiguous), adding overloads to already overloaded functions is ok (any use of <tt>&func</tt> already needed a cast).<br />
** change its signature. This includes:<br />
*** changing any of the types of the arguments in the [[Policies/Binary_Compatibility_Examples#Change_the_parameters_of_a_function|parameter list]], including changing the const/volatile qualifiers of the existing parameters (instead, add a new method)<br />
*** changing the const/volatile qualifiers of the function<br />
*** changing the [[Policies/Binary_Compatibility_Examples#Change_the_access_rights|access rights]] to some functions or data members, for example from <tt>private</tt> to <tt>public</tt>. With some compilers, this information may be part of the signature. If you need to make a private function protected or even public, you have to add a new function that calls the private one.<br />
*** changing the [[Policies/Binary_Compatibility_Examples#Change_the_CV-qualifiers_of_a_member_function|CV-qualifiers of a member function]]: the const and/or volatile that apply to the function itself.<br />
*** extending a function with another parameter, even if this parameter has a default argument. ''See below for a suggestion on how to avoid this issue''<br />
*** changing the [[Policies/Binary_Compatibility_Examples#Change_the_return_type|return type]] in any way<br />
*** Exception: non-member functions declared with extern "C" can change parameter types (be very careful).<br />
* For virtual member functions:<br />
** [[Policies/Binary_Compatibility_Examples#Add_a_virtual_member_function_to_a_class_without_any|add a virtual function]] to a class that doesn't have any virtual functions or virtual bases.<br />
** [[Policies/Binary_Compatibility_Examples#Add_new_virtuals_to_a_non-leaf_class|add new virtual functions]] to non-leaf classes as this will break subclasses. Note that a class designed to be subclassed by applications is '''always''' a non-leaf class. ''See below for some workarounds or ask on mailing lists.''<br />
** add new virtual functions for any reason, even to leaf classes, ''if the class is intended to remain binary compatible on Windows''. Doing so may [http://lists.kde.org/?l=kde-core-devel&m=139744177410091&w=2 reorder existing virtual functions] and break binary compatibility.<br />
** [[Policies/Binary_Compatibility_Examples#Change_the_order_of_the_declaration_of_virtual_functions|change the order]] of virtual functions in the class declaration.<br />
** [[Policies/Binary_Compatibility_Examples#Override_a_virtual_that_doesn.27t_come_from_a_primary_base|override an existing virtual function if that function is not in the primary base class]] (first non-virtual base class, or the primary base class's primary base class and upwards).<br />
** [[Policies/Binary_Compatibility_Examples#Override_a_virtual_with_a_covariant_return_with_different_top_address|override an existing virtual function]] if the overriding function has a [http://en.wikipedia.org/wiki/Covariant_return_type covariant return type] for which the more-derived type has a pointer address different from the less-derived one (usually happens when, between the less-derived and the more-derived ones, there's multiple inheritance or virtual inheritance).<br />
** Remove a virtual function, even if it is a reimplementation of a virtual function from the base class<br />
* For static non-private members or for non-static non-member public data:<br />
** Remove or unexport it<br />
** Change its [[Policies/Binary_Compatibility_Examples#Change_the_type_of_global_data|type]]<br />
** Change its [[Policies/Binary_Compatibility_Examples#Change_the_CV-qualifiers_of_global_data|CV-qualifiers]]<br />
* For non-static members:<br />
** add new, data members to an existing class.<br />
** change the order of non-static data members in a class.<br />
** change the type of the member, except for signedness (or more generally if the types are guaranteed to have the same size, and the member is not used by any inline method)<br />
** remove existing non-static data members from an existing class.<br />
<br />
If you need to add extend/modify the parameter list of an existing function, you need to add a new function instead with the new parameters. In that case, you may want to add a short note that the two functions shall be merged with a default argument in later versions of the library:<br />
<br />
<source lang="cpp-qt"><br />
void functionname( int a );<br />
void functionname( int a, int b ); //BCI: merge with int b = 0<br />
</source><br />
<br />
You should...<br />
<br />
In order to make a class to extend in the future you should follow these rules:<br />
* add d-pointer. ''See below''.<br />
* add non-inline virtual destructor even if the body is empty.<br />
* reimplement <tt>event</tt> in QObject-derived classes, even if the body for the function is just calling the base class' implementation. This is specifically to avoid problems caused by adding a reimplemented virtual function as discussed below.<br />
* make all constructors non-inline.<br />
* write non-inline implementations of the copy constructor and assignment operator unless the class cannot be copied by value (e.g. classes inherited from QObject can't be)<br />
<br />
== Techniques for Library Programmers ==<br />
<br />
The biggest problem when writing libraries is, that one cannot safely add data members since this would change the size and layout of every class, struct, or array containing objects of the type, including subclasses.<br />
<br />
=== Bitflags ===<br />
One exception are bitflags. If you use bitflags for enums or bools, you can safely round up to at least the next byte minus 1. A class with members<br />
<br />
<source lang="cpp-qt"><br />
uint m1 : 1;<br />
uint m2 : 3;<br />
uint m3 : 1;<br />
</source><br />
<source lang="cpp-qt"><br />
uint m1 : 1;<br />
uint m2 : 3;<br />
uint m3 : 1;<br />
uint m4 : 2; // new member<br />
</source><br />
without breaking binary compatibility. Please round up to a maxmimum of 7 bits (or 15 if the bitfield was already larger than 8). Using the very last bit may cause problems on some compilers.<br />
<br />
=== Using a d-Pointer===<br />
Bitflags and predefined reserved variables are nice, but far from being sufficient. This is where the d-pointer technique comes into play. The name "d-pointer" stems from Trolltech's Arnt Gulbrandsen, who first introduced the technique into Qt, making it one of the first C++ GUI libraries to maintain binary compatibility even between bigger release. The technique was quickly adapted as general programming pattern for the KDE libraries by everyone who saw it. It's a great trick to be able to add new private data members to a class without breaking binary compatibility.<br />
<br />
'''Remark:''' The d-pointer pattern has been described many<br />
times in computer science history under various names, e.g. as pimpl,<br />
as handle/body or as cheshire cat. Google helps finding online papers<br />
for any of these, just add C++ to the search terms.<br />
<br />
In your class definition for class Foo, define a forward declaration<br />
<source lang="cpp-qt"><br />
class FooPrivate;<br />
</source><br />
and the d-pointer in the private section:<br />
<source lang="cpp-qt"><br />
private:<br />
FooPrivate* d;<br />
</source><br />
The FooPrivate class itself is purely defined in the class implementation file (usually *.cpp ), for example:<br />
<source lang="cpp-qt"><br />
class FooPrivate {<br />
public:<br />
FooPrivate()<br />
: m1(0), m2(0)<br />
{}<br />
int m1;<br />
int m2;<br />
QString s;<br />
};<br />
</source><br />
<br />
All you have to do now is to create the private data in your constructors or your init function with<br />
<source lang="cpp-qt"><br />
d = new FooPrivate;<br />
</source><br />
and to delete it again in your destructor with<br />
<source lang="cpp-qt"><br />
delete d;<br />
</source><br />
<br />
In most circumstances you will want to make the dpointer constant to catch situations where it's accidentally getting modified or copied over so you'd lose ownership of the private object and create a memory leak:<br />
<source lang="cpp-qt"><br />
private:<br />
FooPrivate* const d;<br />
</source><br />
This allows you to modify the object pointed to by d but not the value of the pointer after it has been initialized.<br />
<br />
You may not want all member variables to live in the private data object, though. For very often used members, it's faster to put them directly in the class, since inline functions cannot access the d-pointer data. Also note that all data covered by the d-pointer is "private", despite being declared public in the d-pointer itself. For public or protected access, provide both a set and a get function. Example<br />
<source lang="cpp-qt"><br />
QString Foo::string() const<br />
{<br />
return d->s;<br />
}<br />
<br />
void Foo::setString( const QString& s )<br />
{<br />
d->s = s;<br />
}<br />
</source><br />
<br />
It is also possible (but not recommended) to declare the private class for the d-pointer as a nested private class (e.g. Foo::Private). If you use this technique, remember that the nested private class will inherit the public symbol visibility of the containing exported class. This will cause the functions of the private class to be named in the dynamic library's symbol table. You can use <code>Q_DECL_HIDDEN</code> in the implementation of the nested private class to manually re-hide the symbols. (For an existing class, this is technically an ABI change, but does not impact the public ABI supported by the KDE developers, so private symbols mistaken exposed may be re-hidden without further warning.). Other downsides of the nested private class include the lack of consistency with Qt and its Q_D/Q_Q macros, and the fact that it can't be forward-declared in unrelated headers anymore (which can be useful to declare it as a friend class). For all these reasons, prefer FooPrivate.<br />
<br />
<h2>Trouble shooting</h2><br />
<br />
=== Adding new data members to classes without d-pointer === <br />
<br />
If you don't have free bitflags, reserved variables and no d-pointer either, but you absolutely have to add a new private member variable, there are still some possibilities left. If your class inherits {{qt|QObject}}, you can for example place the additional data in a special child and find it by traversing over the list of children. You can access the list of children with QObject::children(). However, a fancier and usually faster approach is to use a hashtable to store a<br />
mapping between your object and the extra data. For this purpose, Qt provides a pointer-based dictionary called {{qt|QHash}} (or {{qt3|QPtrDict}} in Qt3).<br />
<br />
The basic trick in your class implementation of class Foo is:<br />
* Create a private data class FooPrivate.<br />
* Create a static QHash&lt;Foo *, FooPrivate *&gt;.<br />
*Note that some compilers/linkers (almost all, unfortunately) do not manage to create static objects in shared libraries. They simply forget to call the constructor. Therefore you should use the <tt>Q_GLOBAL_STATIC</tt> macro to create and access the object:<br />
<br />
<source lang="cpp-qt"><br />
// BCI: Add a real d-pointer<br />
typedef QHash<Foo *, FooPrivate *> FooPrivateHash;<br />
Q_GLOBAL_STATIC(FooPrivateHash, d_func)<br />
static FooPrivate *d(const Foo *foo)<br />
{<br />
FooPrivate *ret = d_func()->value(foo);<br />
if ( ! ret ) {<br />
ret = new FooPrivate;<br />
d_func()->insert(foo, ret);<br />
}<br />
return ret;<br />
}<br />
static void delete_d(const Foo *foo)<br />
{<br />
FooPrivate *ret = d_func()->value(foo);<br />
delete ret;<br />
d_func()->remove(foo);<br />
}<br />
</source><br />
<br />
* Now you can use the d-pointer in your class almost as simple as in the code before, just with a function call to d(this). For example:<br />
<br />
<source lang="cpp-qt"><br />
d(this)->m1 = 5;<br />
</source><br />
<br />
* Add a line to your destructor:<br />
<source lang="cpp-qt"><br />
delete_d(this);<br />
</source><br />
* Do not forget to add a BCI remark, so that the hack can be removed in the next version of the library.<br />
* Do not forget to add a d-pointer to your next class.<br />
<br />
=== Adding a reimplemented virtual function ===<br />
<br />
As already explained, you can safely reimplement a virtual function defined in one of the base classes only if it is safe that the programs linked with the prior version call the implementation in the base class rather than the derived one. This is because the compiler sometimes calls virtual functions directly if it can determine which one to call. For example, if you have <br />
<source lang="cpp-qt"><br />
void C::foo()<br />
{<br />
B::foo();<br />
}<br />
</source><br />
<br />
then B::foo() is called directly. If class B inherits from class A which implements foo() and B itself doesn't reimplement it, then C::foo() will in fact call A::foo(). If a newer version of the library adds B::foo(), C::foo() will call it only after a recompilation.<br />
<br />
Another more common example is:<br />
<source lang="cpp-qt"><br />
B b; // B derives from A<br />
b.foo();<br />
</source><br />
then the call to foo() will not use the virtual table. That means that<br />
if B::foo() didn't exist in the library but now does, code that was<br />
compiled with the earlier version will still call A::foo().<br />
<br />
If you can't guarantee things will continue to work without a recompilation, move functionality from A::foo() to a new protected function A::foo2() and use this code:<br />
<source lang="cpp-qt"><br />
void A::foo()<br />
{<br />
if( B* b = dynamic_cast< B* >( this ))<br />
b->B::foo(); // B:: is important<br />
else<br />
foo2();<br />
}<br />
void B::foo()<br />
{<br />
// added functionality<br />
A::foo2(); // call base function with real functionality<br />
}<br />
</source><br />
All calls to A::foo() for objects of type B (or inherited) will result in calling B::foo(). The only case that will not work as expected are calls to A::foo() that explicitly specify A::foo(), but B::foo() calls A::foo2() instead and there should not be other places doing so.<br />
<br />
=== Using a new class ===<br />
<br />
A relatively simple method of "extending" a class can be writing a replacement class that will include also the new functionality (and that may inherit from the old class to reuse the code). This of course requires adapting and recompiling applications using the library, so it is not possible this way to fix or extend functionality of classes that are used by applications compiled against an older version of the library. However, especially with small and/or performance-critical classes it may be simpler to write them without making sure they'll be simple to extend in the future and if the need arises later write a new replacement class that will provide new features or better performance.<br />
<br />
=== Adding new virtual functions to leaf classes ===<br />
This technique is one of cases of using a new class that can help if there's a need to add new virtual functions to a class that should stay binary compatible and there is no class inheriting from it that should also stay binary compatible (i.e. all classes inheriting from it are in applications). In such case it's possible to add a new class inheriting from the original one that will add them. Applications using the new functionality will of course have to be modified to use the new class.<br />
<source lang="cpp-qt"><br />
class A {<br />
public:<br />
virtual void foo();<br />
};<br />
class B : public A { // newly added class<br />
public:<br />
virtual void bar(); // newly added virtual function<br />
};<br />
void A::foo()<br />
{<br />
// here it's needed to call a new virtual function<br />
if( B* this2 = dynamic_cast< B* >( this ))<br />
this2->bar();<br />
}<br />
</source><br />
It is not possible to use this technique when there are other inherited classes that should also stay binary compatible because they'd have to inherit from the new class.<br />
<br />
=== Using signals instead of virtual functions ===<br />
Qt's signals and slots are invoked using a special virtual method created by the Q_OBJECT macro and it exists in every class inherited from {{qt|QObject}}. Therefore adding new signals and slots doesn't affect binary compatibility and the signals/slots mechanism can be used to emulate virtual functions.<br />
<br />
<source lang="cpp-qt"><br />
class A : public QObject {<br />
Q_OBJECT<br />
public:<br />
A();<br />
virtual void foo();<br />
signals:<br />
void bar( int* ); // added new "virtual" function<br />
protected slots:<br />
// implementation of the virtual function in A<br />
void barslot( int* );<br />
};<br />
<br />
A::A()<br />
{<br />
connect(this, SIGNAL( bar(int*)), this, SLOT( barslot(int*)));<br />
}<br />
<br />
void A::foo()<br />
{<br />
int ret;<br />
emit bar( &ret );<br />
}<br />
<br />
void A::barslot( int* ret )<br />
{<br />
*ret = 10;<br />
}<br />
</source><br />
<br />
Function bar() will act like a virtual function, barslot() implements the actual functionality of it. Since signals have void return value, data must be returned using arguments. As there will be only one slot connected to the signal returning data from the slot this way will work without problems. Note that with Qt4 for this to work the connection type will have to be Qt::DirectConnection.<br />
<br />
If an inherited class will want to re-implement the functionality of bar() it will have to provide its own slot:<br />
<source lang="cpp-qt"><br />
class B : public A {<br />
Q_OBJECT<br />
public:<br />
B();<br />
protected slots: // necessary to specify as a slot again<br />
void barslot( int* ); // reimplemented functionality of bar()<br />
};<br />
<br />
B::B()<br />
{<br />
disconnect(this, SIGNAL(bar(int*)), this, SLOT(barslot(int*)));<br />
connect(this, SIGNAL(bar(int*)), this, SLOT(barslot(int*)));<br />
}<br />
<br />
void B::barslot( int* ret )<br />
{<br />
*ret = 20;<br />
}<br />
</source><br />
<br />
Now B::barslot() will act like virtual reimplementation of A::bar(). Note that it is necessary to specify barslot() again as a slot in B and that in the constructor it is necessary to first disconnect and then connect again, that will disconnect A::barslot() and connect B::barslot() instead.<br />
<br />
Note: the same can be accomplished by implementing a virtual slot.<br />
<br />
[[Category:Policies]] [[Category:C++]]<br />
</translate></div>Dfaurehttps://community.kde.org/index.php?title=Frameworks/Epics&diff=90141Frameworks/Epics2020-09-08T18:15:00Z<p>Dfaure: /* Road to KF 5.0 */</p>
<hr />
<div>= KDE Frameworks Epics Dashboard =<br />
<br />
This section main intent is to track the KDE Frameworks transversal on going efforts (Epics ;-) ). They are grouped by overall goal. No more than three goals should be actively pursued at a time.<br />
<br />
== Battle for quality ==<br />
{| class="sortable" border="1" cellpadding="5" cellspacing="0" style="border: gray solid 1px; border-collapse: collapse; text-align: left; width:100%;"<br />
|- style="background: #ececec; white-space:nowrap;"<br />
! Status<br />
! Description<br />
! width=120 | Coordination<br />
{{FeatureInProgress|[[Frameworks/Epics/Continuous_Integration]]|Scarlett Clark}}<br />
{{FeatureTodo|[[Frameworks/Epics/Automated_ABI_Validation]]|??}}<br />
|}<br />
<br />
== Absorbing PIM ==<br />
{| class="sortable" border="1" cellpadding="5" cellspacing="0" style="border: gray solid 1px; border-collapse: collapse; text-align: left; width:100%;"<br />
|- style="background: #ececec; white-space:nowrap;"<br />
! Status<br />
! Description<br />
! width=120 | Coordination<br />
{{FeatureTodo|[[Frameworks/Epics/Contributions_to_Qt5_for_KF5.1]]|??}}<br />
{{FeatureInProgress|[[Frameworks/Epics/Splitting_kdepimlibs]] [[Frameworks/Epics/kdepimlibs]]|??}}<br />
|}<br />
<br />
== Developer story ==<br />
{| class="sortable" border="1" cellpadding="5" cellspacing="0" style="border: gray solid 1px; border-collapse: collapse; text-align: left; width:100%;"<br />
|- style="background: #ececec; white-space:nowrap;"<br />
! Status<br />
! Description<br />
! width=120 | Coordination<br />
{{FeatureTodo|[[Frameworks/Epics/inqlude_in_production]]|Cornelius Schumacher}}<br />
{{FeatureTodo|[[Frameworks/Epics/KDevelop_based_SDK]]|Aleix Pol}}<br />
{{FeatureTodo|[[Frameworks/Epics/QtCreator_based_SDK]]|??}}<br />
{{FeatureTodo|[[Frameworks/Epics/Reorganize_Techbase]]|??}}<br />
{{FeatureInProgress|[[Frameworks/Epics/Apidox_refresh]]|Alex Merry}}<br />
|}<br />
<br />
== Road to KF 5.0 ==<br />
<br />
The release schedule is available at the [[Schedules/Frameworks | here on community]].<br />
<br />
<br />
{| class="sortable" border="1" cellpadding="5" cellspacing="0" style="border: gray solid 1px; border-collapse: collapse; text-align: left; width:100%;"<br />
|- style="background: #ececec; white-space:nowrap;"<br />
! Status<br />
! Description<br />
! width=120 | Coordination<br />
|-<br />
{{FeatureDone|[[Frameworks/Epics/Contributions_to_Qt5]]|David Faure}}<br />
{{FeatureDone|[[Frameworks/Epics/KDEUI_Crumble]]|Kevin Ottens}}<br />
{{FeatureDone|[[Frameworks/Epics/Splitting_kdelibs]]|Kevin Ottens}}<br />
{{FeatureDone|[[Frameworks/Epics/CMake]] (remains don't apply anymore, even untracked)|Alexander Neundorf}}<br />
{{FeatureDone|[[Frameworks/Epics/KF5.0_Initial_Communication]]|Kevin Ottens}}<br />
{{FeatureDone|[[Frameworks/Epics/kdelibs_cleanups]]|David Faure}}<br />
{{FeatureDone|[[Frameworks/Epics/Reduce_class_duplication]]|Stephen Kelly}}<br />
{{FeatureDone|[[Frameworks/Epics/Modularization]]|Aurélien Gâteau}}<br />
{{FeatureDone|[[Frameworks/Epics/KTextEditor]]|Cullmann, Haumann}}<br />
{{FeatureDone|[[Frameworks/Epics/New_Runtime_Organization]]|Aaron Seigo}}<br />
{{FeatureDone|[[Frameworks/Epics/KF5.0_Release_Preparation]]|Kevin Ottens}}<br />
{{FeatureDone|[[Frameworks/Epics/StandardPathsMigration]]|David Faure}}<br />
|}</div>Dfaurehttps://community.kde.org/index.php?title=Frameworks/Epics&diff=90140Frameworks/Epics2020-09-08T18:14:42Z<p>Dfaure: /* Backlog */</p>
<hr />
<div>= KDE Frameworks Epics Dashboard =<br />
<br />
This section main intent is to track the KDE Frameworks transversal on going efforts (Epics ;-) ). They are grouped by overall goal. No more than three goals should be actively pursued at a time.<br />
<br />
== Battle for quality ==<br />
{| class="sortable" border="1" cellpadding="5" cellspacing="0" style="border: gray solid 1px; border-collapse: collapse; text-align: left; width:100%;"<br />
|- style="background: #ececec; white-space:nowrap;"<br />
! Status<br />
! Description<br />
! width=120 | Coordination<br />
{{FeatureInProgress|[[Frameworks/Epics/Continuous_Integration]]|Scarlett Clark}}<br />
{{FeatureTodo|[[Frameworks/Epics/Automated_ABI_Validation]]|??}}<br />
|}<br />
<br />
== Absorbing PIM ==<br />
{| class="sortable" border="1" cellpadding="5" cellspacing="0" style="border: gray solid 1px; border-collapse: collapse; text-align: left; width:100%;"<br />
|- style="background: #ececec; white-space:nowrap;"<br />
! Status<br />
! Description<br />
! width=120 | Coordination<br />
{{FeatureTodo|[[Frameworks/Epics/Contributions_to_Qt5_for_KF5.1]]|??}}<br />
{{FeatureInProgress|[[Frameworks/Epics/Splitting_kdepimlibs]] [[Frameworks/Epics/kdepimlibs]]|??}}<br />
|}<br />
<br />
== Developer story ==<br />
{| class="sortable" border="1" cellpadding="5" cellspacing="0" style="border: gray solid 1px; border-collapse: collapse; text-align: left; width:100%;"<br />
|- style="background: #ececec; white-space:nowrap;"<br />
! Status<br />
! Description<br />
! width=120 | Coordination<br />
{{FeatureTodo|[[Frameworks/Epics/inqlude_in_production]]|Cornelius Schumacher}}<br />
{{FeatureTodo|[[Frameworks/Epics/KDevelop_based_SDK]]|Aleix Pol}}<br />
{{FeatureTodo|[[Frameworks/Epics/QtCreator_based_SDK]]|??}}<br />
{{FeatureTodo|[[Frameworks/Epics/Reorganize_Techbase]]|??}}<br />
{{FeatureInProgress|[[Frameworks/Epics/Apidox_refresh]]|Alex Merry}}<br />
|}<br />
<br />
== Road to KF 5.0 ==<br />
<br />
The release schedule is available at the [[Schedules/Frameworks | here on community]].<br />
<br />
<br />
{| class="sortable" border="1" cellpadding="5" cellspacing="0" style="border: gray solid 1px; border-collapse: collapse; text-align: left; width:100%;"<br />
|- style="background: #ececec; white-space:nowrap;"<br />
! Status<br />
! Description<br />
! width=120 | Coordination<br />
|-<br />
{{FeatureDone|[[Frameworks/Epics/Contributions_to_Qt5]]|David Faure}}<br />
{{FeatureDone|[[Frameworks/Epics/KDEUI_Crumble]]|Kevin Ottens}}<br />
{{FeatureDone|[[Frameworks/Epics/Splitting_kdelibs]]|Kevin Ottens}}<br />
{{FeatureDone|[[Frameworks/Epics/CMake]] (remains don't apply anymore, even untracked)|Alexander Neundorf}}<br />
{{FeatureDone|[[Frameworks/Epics/KF5.0_Initial_Communication]]|Kevin Ottens}}<br />
{{FeatureDone|[[Frameworks/Epics/kdelibs_cleanups]]|David Faure}}<br />
{{FeatureDone|[[Frameworks/Epics/Reduce_class_duplication]]|Stephen Kelly}}<br />
{{FeatureDone|[[Frameworks/Epics/Modularization]]|Aurélien Gâteau}}<br />
{{FeatureDone|[[Frameworks/Epics/KTextEditor]]|Cullmann, Haumann}}<br />
{{FeatureDone|[[Frameworks/Epics/New_Runtime_Organization]]|Aaron Seigo}}<br />
{{FeatureDone|[[Frameworks/Epics/KF5.0_Release_Preparation]]|Kevin Ottens}}<br />
|}</div>Dfaurehttps://community.kde.org/index.php?title=Frameworks/Epics&diff=90139Frameworks/Epics2020-09-08T18:14:11Z<p>Dfaure: /* Backlog */</p>
<hr />
<div>= KDE Frameworks Epics Dashboard =<br />
<br />
This section main intent is to track the KDE Frameworks transversal on going efforts (Epics ;-) ). They are grouped by overall goal. No more than three goals should be actively pursued at a time.<br />
<br />
== Battle for quality ==<br />
{| class="sortable" border="1" cellpadding="5" cellspacing="0" style="border: gray solid 1px; border-collapse: collapse; text-align: left; width:100%;"<br />
|- style="background: #ececec; white-space:nowrap;"<br />
! Status<br />
! Description<br />
! width=120 | Coordination<br />
{{FeatureInProgress|[[Frameworks/Epics/Continuous_Integration]]|Scarlett Clark}}<br />
{{FeatureTodo|[[Frameworks/Epics/Automated_ABI_Validation]]|??}}<br />
|}<br />
<br />
== Absorbing PIM ==<br />
{| class="sortable" border="1" cellpadding="5" cellspacing="0" style="border: gray solid 1px; border-collapse: collapse; text-align: left; width:100%;"<br />
|- style="background: #ececec; white-space:nowrap;"<br />
! Status<br />
! Description<br />
! width=120 | Coordination<br />
{{FeatureTodo|[[Frameworks/Epics/Contributions_to_Qt5_for_KF5.1]]|??}}<br />
{{FeatureInProgress|[[Frameworks/Epics/Splitting_kdepimlibs]] [[Frameworks/Epics/kdepimlibs]]|??}}<br />
|}<br />
<br />
== Developer story ==<br />
{| class="sortable" border="1" cellpadding="5" cellspacing="0" style="border: gray solid 1px; border-collapse: collapse; text-align: left; width:100%;"<br />
|- style="background: #ececec; white-space:nowrap;"<br />
! Status<br />
! Description<br />
! width=120 | Coordination<br />
{{FeatureTodo|[[Frameworks/Epics/inqlude_in_production]]|Cornelius Schumacher}}<br />
{{FeatureTodo|[[Frameworks/Epics/KDevelop_based_SDK]]|Aleix Pol}}<br />
{{FeatureTodo|[[Frameworks/Epics/QtCreator_based_SDK]]|??}}<br />
{{FeatureTodo|[[Frameworks/Epics/Reorganize_Techbase]]|??}}<br />
{{FeatureInProgress|[[Frameworks/Epics/Apidox_refresh]]|Alex Merry}}<br />
|}<br />
<br />
== Road to KF 5.0 ==<br />
<br />
The release schedule is available at the [[Schedules/Frameworks | here on community]].<br />
<br />
<br />
{| class="sortable" border="1" cellpadding="5" cellspacing="0" style="border: gray solid 1px; border-collapse: collapse; text-align: left; width:100%;"<br />
|- style="background: #ececec; white-space:nowrap;"<br />
! Status<br />
! Description<br />
! width=120 | Coordination<br />
|-<br />
{{FeatureDone|[[Frameworks/Epics/Contributions_to_Qt5]]|David Faure}}<br />
{{FeatureDone|[[Frameworks/Epics/KDEUI_Crumble]]|Kevin Ottens}}<br />
{{FeatureDone|[[Frameworks/Epics/Splitting_kdelibs]]|Kevin Ottens}}<br />
{{FeatureDone|[[Frameworks/Epics/CMake]] (remains don't apply anymore, even untracked)|Alexander Neundorf}}<br />
{{FeatureDone|[[Frameworks/Epics/KF5.0_Initial_Communication]]|Kevin Ottens}}<br />
{{FeatureDone|[[Frameworks/Epics/kdelibs_cleanups]]|David Faure}}<br />
{{FeatureDone|[[Frameworks/Epics/Reduce_class_duplication]]|Stephen Kelly}}<br />
{{FeatureDone|[[Frameworks/Epics/Modularization]]|Aurélien Gâteau}}<br />
{{FeatureDone|[[Frameworks/Epics/KTextEditor]]|Cullmann, Haumann}}<br />
{{FeatureDone|[[Frameworks/Epics/New_Runtime_Organization]]|Aaron Seigo}}<br />
{{FeatureDone|[[Frameworks/Epics/KF5.0_Release_Preparation]]|Kevin Ottens}}<br />
|}<br />
<br />
== Backlog ==<br />
<br />
'''Important''': As part of the process of refining any of the epics in this list, it is advised to check the [[KDE_Core/Platform_11|Platform 11 notes]] for useful content.<br />
<br />
<br />
{| class="sortable" border="1" cellpadding="5" cellspacing="0" style="border: gray solid 1px; border-collapse: collapse; text-align: left; width:100%;"<br />
|- style="background: #ececec; white-space:nowrap;"<br />
! Status<br />
! Description<br />
! width=120 | Coordination<br />
|-<br />
{{FeatureTodo|[[Frameworks/Epics/KDE_at_Home]]|??}}<br />
{{FeatureTodo|[[Frameworks/Epics/Shared_Service_Framework]]|??}}<br />
{{FeatureDone|[[Frameworks/Epics/StandardPathsMigration]]|??}}<br />
|}</div>Dfaurehttps://community.kde.org/index.php?title=Frameworks/Epics/Contributions_to_Qt5_for_KF5.1&diff=90138Frameworks/Epics/Contributions to Qt5 for KF5.12020-09-08T18:13:24Z<p>Dfaure: /* Contributing to Qt 5 for KF 5.1 epic */</p>
<hr />
<div>= Contributing to Qt 5 for KF 5.1 epic =<br />
<br />
Quite some effort goes into Qt 5 in order to push into Qt some of the features which should be in Qt and not in KDE Frameworks. Usually because all Qt apps would benefit from them even outside the KDE world, and because this cuts dependencies between the KDE frameworks.<br />
<br />
{| class="sortable" border="1" cellpadding="5" cellspacing="0" style="border: gray solid 1px; border-collapse: collapse; text-align: left; width:100%;"<br />
|- style="background: #ececec; white-space:nowrap;"<br />
! Status<br />
! Description<br />
! width=120 | Contact<br />
|-<br />
{{FeatureTodo|QSqueezedTextLabel, or squeezing in QLabel|null}}<br />
{{FeatureTodo|QFileSystemWatcher: support for watching non-existing files. Reviving an old Qt patch for this might work: https://codereview.qt-project.org/#change,19274|David Faure, Mark Gaiser}}<br />
{{FeatureTodo|QCompleter: many missing features compared to KCompletion. Look at the completion model in http://qt-project.org/wiki/Qt-5-Ui-Helpers as a possible replacement which would also work for QML.|?}}<br />
{{FeatureInProgress|QLocalSocket/QLocalServer: support for abstract unix sockets. See https://codereview.qt-project.org/#change,73977 for the work in progress|Rich Moore}}<br />
{{FeatureTodo|KProcess::setShellCommand (see also KShell) features in Qt. Ossi says: look at importing QtcProcess from QtCreator to replace QProcess|?}}<br />
{{FeatureTodo|KProcess ForwardOnlyStdErr/ForwardOnlyStdOut features in Qt (Ossi has 7 years old unfinished patches, someone needs to take over that)|?}}<br />
{{FeatureTodo|QCursor: auto-hide support (see KCursor API), plus styleHint to enable this in QLineEdit/QTextEdit (and let users turn this on/off in KConfig)|?}}<br />
{{FeatureTodo|QCursor: theme support|?}}<br />
{{FeatureTodo|QSystemTray: support for the new dbus protocol (see KStatusNotifierItem)|?}}<br />
{{FeatureDone|recursive filtering in QSortFilterProxyModel|Filipe Azevedo}}<br />
{{FeatureTodo|QPoTranslator (support for .po files, and locating them with QStandardPaths, so that libs can load them?)|??}}<br />
{{FeatureInProgress|QTimeZone|John Layt}}<br />
{{FeatureDone|qDebug with categories (qCDebug)|Kai Koehne}}<br />
{{FeatureTodo|QLocale|John Layt}}<br />
{{FeatureTodo|Printing|John Layt}}<br />
{{FeatureTodo|Merge KStandardShortcut and QKeySequence::StandardKey|??}}<br />
{{FeatureDone|Make sure we have a QAction independent of QtWidgets in QtGui|Qt6}}<br />
{{FeatureTodo|Support for timer-based auto-selection in QAbstractItemView (triggered by styleHint, like QStyle::SH_ItemView_ActivateItemOnSingleClick triggers single-click mode)|??}}<br />
{{FeatureTodo|Make sure QTextBrowser automatically follows KDE settings for the wheel button behavior (scroll vs zoom) via backend|??}}<br />
{{FeatureTodo|KSsl*/QSsl* merge|Richard Moore}}<br />
{{FeatureTodo|Make it possible to create plugins for handling url's for QDesktopServices::openUrl|?}}<br />
{{FeatureDone |Methods for associating mimetypes with imageformats in QImageReader/Writer (replacing last bits of KImageIO)|Allan Sandfeld Jensen}}<br />
{{FeatureTodo|Add plugin version to QPluginLoader (see KPluginLoader::version())|}}<br />
{{FeatureTodo|QPluginLoader::findPlugin(), like KPluginLoader::findPlugin()|}}</div>Dfaurehttps://community.kde.org/index.php?title=Akademy/2020/Tuesday&diff=90092Akademy/2020/Tuesday2020-09-08T08:58:00Z<p>Dfaure: /* Room 01 - 8th September */</p>
<hr />
<div>= BoF sessions on Tuesday, 8th September 2020 =<br />
<br />
<br />
Please put your name and email address in the Host/Notes section. There is no length limitation; text will wrap. <br />
<br />
The Akademy team might reassign BoFs based on operational needs<br />
<br />
=== Room 01 - 8th September ===<br />
{| class="table table-striped"<br />
|-<br />
! [https://meet.kde.org/b/ken-gtb-gz3 Link to Room 01]<br />
!<br />
! <br />
|-<br />
! Time <br />
! Subject <br />
! Host/Notes<br />
|-<br />
| width="100pt" | 9:00 UTC<br />
| width="200pt" | KDE Frameworks 6<br />
| width="400pt" | David Faure; notes: https://share.kde.org/apps/files/?dir=/Community%20Notes/Akademy&fileid=1718700<br />
|-<br />
| 10:00 UTC<br />
| KF6 (continued)<br />
| David Faure<br />
|-<br />
| 11:00 UTC<br />
| SPDX & Licensing<br />
| Andreas Cord-Landwehr: let's plan how to proceed the the SPDX/REUSE introduction in KDE: next steps, documentation, open discussion points, tooling Q&A, next focus areas (translations, ...); notes: https://share.kde.org/s/PZSZ7agPjYM6qHC<br />
|-<br />
| 12:00 UTC<br />
| Break<br />
|<br />
|-<br />
| 16:00 UTC<br />
| KDE Sysadmin documentation BoF<br />
| Sysadmin team<br />
|-<br />
| 17:00 UTC<br />
| KDE Connect Design Discussion (with KDE VDG)<br />
| KDE Connect Team<br />
|-<br />
| 18:00 UTC<br />
| Plasma Discover<br />
| Aleix Pol<br />
|-<br />
| 19:00 UTC<br />
| <br />
| <br />
|-<br />
| 19:30 UTC<br />
| Bof Wrap Up<br />
|<br />
|}<br />
<br />
=== Room 02 - 8th September ===<br />
{| class="table table-striped"<br />
|-<br />
! [https://meet.kde.org/b/ken-bse-uz6 Link to Room 02]<br />
!<br />
! <br />
|-<br />
! Time <br />
! Subject <br />
! Host/Notes<br />
|-<br />
| width="100pt" | 9:00 UTC<br />
| width="200pt" |<br />
| width="400pt" |<br />
|-<br />
| 10:00 UTC<br />
| <br />
| <br />
|-<br />
| 11:00 UTC<br />
| Plasma Bigscreen: Writing Mycroft skills, QML and key navigation<br />
| Aditya Merha, Marco Martin<br />
|-<br />
| 12:00 UTC<br />
| Break<br />
|<br />
|-<br />
| 16:00 UTC<br />
| <br />
|<br />
|-<br />
| 17:00 UTC<br />
| Mailing List owner policy proposal discussion<br />
| Albert Astals Cid https://share.kde.org/s/PeFRH82FmFgDrep<br />
|-<br />
| 18:00 UTC<br />
| Dolphin<br />
| Elvis Angelaccio <br/> Write-access notes: https://share.kde.org/f/1917715 <br/> Read-only notes: https://share.kde.org/s/YXNs8dgDHGA6HMo<br />
|-<br />
| 19:00 UTC<br />
| <br />
| <br />
|}<br />
<br />
=== Room 03 - 8th September ===<br />
{| class="table table-striped"<br />
|-<br />
! [https://meet.kde.org/b/ken-o7f-ikm Link to Room 03]<br />
!<br />
! <br />
|-<br />
! Time <br />
! Subject <br />
! Host/Notes<br />
|-<br />
| width="100pt" | 9:00 UTC<br />
| width="200pt" |<br />
| width="400pt" |<br />
|-<br />
| 10:00 UTC<br />
| <br />
| <br />
|-<br />
| 11:00 UTC<br />
| <br />
| <br />
|-<br />
| 12:00 UTC<br />
| Break<br />
|<br />
|-<br />
| 16:00 UTC<br />
| KDE PIM<br />
| Dan Vrátil<br />
|-<br />
| 17:00 UTC<br />
| KDE PIM<br />
| Dan Vrátil<br />
|-<br />
| 18:00 UTC<br />
| <br />
|-<br />
| 19:00 UTC<br />
| <br />
| <br />
|}<br />
<br />
=== Room 04 - 8th September ===<br />
{| class="table table-striped"<br />
|-<br />
! [https://meet.kde.org/b/ken-ul4-aro Link to Room 04]<br />
!<br />
! <br />
|-<br />
! Time <br />
! Subject <br />
! Host/Notes<br />
|-<br />
| width="100pt" | 9:00 UTC<br />
| width="200pt" |<br />
| width="400pt" |<br />
|-<br />
| 10:00 UTC<br />
| <br />
| <br />
|-<br />
| 11:00 UTC<br />
| <br />
| <br />
|-<br />
| 12:00 UTC<br />
| Break<br />
|<br />
|-<br />
| 16:00 UTC<br />
| Plasma on Wayland<br />
| Meeting for Plasma/Wayland devs - David Edmundson<br />
|-<br />
| 17:00 UTC<br />
| Test your app on wayland<br />
| Got an issue with your app on wayland? Come along to an open session to investigate what you need to change<br />
|-<br />
| 18:00 UTC<br />
| Continuation as above<br />
|-<br />
| 19:00 UTC<br />
| <br />
| <br />
|}</div>Dfaurehttps://community.kde.org/index.php?title=Frameworks/Policies&diff=89011Frameworks/Policies2020-07-19T11:51:07Z<p>Dfaure: /* Frameworks Qt requirements */</p>
<hr />
<div><br />
== Frameworks have a Tier and a Type ==<br />
Each framework has a clear position in the Tier/Type matrix, its position forces a set of rules on its possible dependencies. This matrix and its rules are summarized in the [http://files.kde.org/frameworks/kde-frameworks-matrix.pdf Frameworks matrix document].<br />
<br />
<br />
The constraints from Tiers are the following:<br />
* Tier 1 Frameworks can depend only on Qt official frameworks or other system libraries;<br />
* Tier 2 Frameworks can depend only on Tier 1 Frameworks, Qt official frameworks, or other system libraries;<br />
* Tier 3 Frameworks can depend only on other Tier 3 Frameworks, Tier 2 Frameworks, Tier 1 Frameworks, Qt official frameworks, or other system libraries.<br />
<br />
<br />
The constraints from Types are the following:<br />
* Functional Qt Addons cannot have runtime dependencies;<br />
* Integration Qt Addons can have an optional runtime dependencies and aim at integrating with the underlying OS/Platform;<br />
* Solutions have mandatory runtime dependencies, it is part of their design and where their added value comes from (think scalability, resource sharing, resilience, etc.).<br />
<br />
== Framework directory structure ==<br />
All the frameworks will have the same directory structure which will follow some rules:<br />
* The containing directory has the name of the technology (plasma, kio, itemmodels, etc.);<br />
* At the top level we find the common files like README.md, COPYING.LIB, metainfo.yaml...<br />
* More comprehensive documentation go into a '''docs''' subdirectory<br />
* The source code for the targets go into '''src''' subdirectory, if several payloads are built (like a core lib and a gui layer on top) then src will contain one subdirectory per library: core, gui, widgets, etc.<br />
* Code examples go into an '''examples''' subdirectory<br />
* Automatic tests go into an '''autotests''' subdirectory<br />
* Test applications go into a '''tests''' subdirectory<br />
* CMake modules (FindFoo.cmake etc.) or CMake macro files go into '''cmake''' subdirectory<br />
<br />
== Frameworks have automatic unit tests ==<br />
Enough said really... They must be unit tested with automatic unit tests.<br />
<br />
Corollary: When fixing a bug in a framework, the auto-test proving the bug and the fix should come in the same commit.<br />
<br />
== Frameworks maintain binary compatibility ==<br />
Just like we did in kdelibs, KDE Frameworks maintain the binary compatibility through their lifetime, for more details see the [[Policies/Binary_Compatibility_Issues_With_C++| binary compatibility policy]].<br />
<br />
Note however that this policy is lifted during major version transition, corresponding epics of milestones will be marked as such.<br />
<br />
== Frameworks are documented ==<br />
<br />
The API exposed by frameworks are documented using Doxygen. Documentation follows the [[Frameworks/Frameworks_Documentation_Policy|Frameworks Documentation Policy]].<br />
<br />
== Frameworks are localized ==<br />
<br />
Frameworks adapt to the user language and locale settings. This is described in the [[Frameworks/Frameworks_Localization_Policy|Frameworks Localization Policy]].<br />
<br />
== Frameworks use Qt's categorized logging ==<br />
<br />
Frameworks make use of [https://doc.qt.io/qt-5/qloggingcategory.html Qt's categorized logging system]. with standardized logging categories. This is described in the [[Frameworks/Frameworks_Logging_Policy|Frameworks Logging Policy]].<br />
<br />
== Frameworks buildsystem is consistent ==<br />
<br />
* each framework should install a CMake configuration file for itself. This includes:<br />
** a FooConfig.cmake file<br />
** a FooConfigVersion.cmake file<br />
** usually a FooTargets.cmake file<br />
** optionally a file containing macros/functions for using the package<br />
* no framework should install any other CMake files than mentioned above. Find-modules useful for multiple packages should be upstreamed into extra-cmake-modules if they are generally useful. <br />
* For especially exotic packages which are not suitable for extra-cmake-modules, it is ok for a framework to have extra find modules, but they should not be installed.<br />
* Library names are in CamelCase<br />
* All dependencies between frameworks are documented in the CMakeLists.txt (see for instance kio/src/core/CMakeLists.txt)<br />
<br />
For an example, see the [http://quickgit.kde.org/?p=kdeexamples.git&a=tree&f=framework-template framework-template] directory in the kdeexamples repository (you can use setup.sh to create a template that matches the name of your framework).<br />
<br />
== Frameworks commits are reviewed ==<br />
Make sure all commits in the master branch of a repository part of the KDE Frameworks got a proper review. As such commits must contain either a "Reviewed by:" (for quick pastebin reviews) or a "REVIEW:" (for more formal reviewboard reviews).<br />
<br />
== Frameworks CI failures are treated as stop the line events ==<br />
When a commit causes a regression in the CI for one of the frameworks, then all work on the corresponding framework should stop. The only commits allowed in are those working toward a resolution of the problem. Only once the framework is green again that regular work can be resumed.<br />
<br />
== Frameworks Qt requirements ==<br />
KDE Frameworks are tested and working with the last 3 minor Qt releases. For instance, once Qt 5.11 was released, the minimum required Qt version changed from Qt 5.8 to Qt 5.9, i.e. the three supported Qt versions became 5.9, 5.10 and 5.11.<br />
<br />
In addition, a Qt LTS release remains supported until the next Qt release after the next Qt LTS release.<br />
For instance, when Qt 5.12 is released, Qt 5.9 remains supported until Qt 5.13, to give time for people to migrate from Qt 5.9 LTS to Qt 5.12 LTS. When Qt 5.13 is released, both Qt 5.9 LTS and Qt 5.10 are dropped, to go back to "last 3 minor Qt releases".<br />
<br />
With Qt6 this changes a little bit again. We interpolate "as if" more Qt 5 versions would be released:<br />
* Qt 5.13 will be the minimum required version 6 months after Qt 5.15, i.e. on 26 Nov 2020<br />
* Qt 5.14 will be the minimum required version 12 months after Qt 5.15, i.e. on 26 May 2021<br />
* Qt 5.15 LTS will be the minimum required version 18 months after its release, i.e. on 26 Nov 2021<br />
<br />
== Frameworks compiler requirements and C++11 ==<br />
The following minimal compiler versions are supported by KDE Frameworks:<br />
* GCC 4.8<br />
* Clang 3.3<br />
* VS2013 (MSVC12)<br />
<br />
This means all of the C++11 standards can be used.<br />
<br />
These requirements come from https://doc.qt.io/qt-5.12/supported-platforms.html</div>Dfaurehttps://community.kde.org/index.php?title=Akademy/2020/Tuesday&diff=89010Akademy/2020/Tuesday2020-07-18T18:54:19Z<p>Dfaure: /* Room 01 - 8th September */</p>
<hr />
<div>= BoF sessions on Tuesday, 8th September 2020 =<br />
<br />
<br />
Please put your name and email address in the Host/Notes section. There is no length limitation; text will wrap. <br />
<br />
The Akademy team might reassign BoFs based on operational needs<br />
<br />
=== Room 01 - 8th September ===<br />
{| class="wikitable" border="1"<br />
|-<br />
! TODO Link to Room 01<br />
!<br />
! <br />
|-<br />
! Time <br />
! Subject <br />
! Host/Notes<br />
|-<br />
| width="100pt" | 9:00 UTC<br />
| width="200pt" | KDE Frameworks 6<br />
| width="400pt" | David Faure<br />
|-<br />
| 10:00 UTC<br />
| KF6 (continued)<br />
| David Faure<br />
|-<br />
| 11:00 UTC<br />
| <br />
| <br />
|-<br />
| 12:00 UTC<br />
| Break<br />
|<br />
|-<br />
| 16:00 UTC<br />
|<br />
|<br />
|-<br />
| 17:00 UTC<br />
| (Tentative) KDE Connect Design Discussion (with KDE VDG)<br />
| KDE Connect Team<br />
|-<br />
| 18:00 UTC<br />
| Plasma Discover<br />
| Aleix Pol<br />
|-<br />
| 19:00 UTC<br />
| <br />
| <br />
|-<br />
| 19:30 UTC<br />
| Bof Wrap Up<br />
|<br />
|}<br />
<br />
=== Room 02 - 8th September ===<br />
{| class="wikitable" border="1"<br />
|-<br />
! TODO Link to Room 01<br />
!<br />
! <br />
|-<br />
! Time <br />
! Subject <br />
! Host/Notes<br />
|-<br />
| width="100pt" | 9:00 UTC<br />
| width="200pt" |<br />
| width="400pt" |<br />
|-<br />
| 10:00 UTC<br />
| <br />
| <br />
|-<br />
| 11:00 UTC<br />
| <br />
| <br />
|-<br />
| 12:00 UTC<br />
| Break<br />
|<br />
|-<br />
| 16:00 UTC<br />
| Web<br />
| Carl and Web team<br />
|-<br />
| 17:00 UTC<br />
| <br />
| <br />
|-<br />
| 18:00 UTC<br />
| Dolphin<br />
| Elvis Angelaccio<br />
|-<br />
| 19:00 UTC<br />
| <br />
| <br />
|}<br />
<br />
=== Room 03 - 8th September ===<br />
{| class="wikitable" border="1"<br />
|-<br />
! TODO Link to Room 01<br />
!<br />
! <br />
|-<br />
! Time <br />
! Subject <br />
! Host/Notes<br />
|-<br />
| width="100pt" | 9:00 UTC<br />
| width="200pt" |<br />
| width="400pt" |<br />
|-<br />
| 10:00 UTC<br />
| <br />
| <br />
|-<br />
| 11:00 UTC<br />
| <br />
| <br />
|-<br />
| 12:00 UTC<br />
| Break<br />
|<br />
|-<br />
| 16:00 UTC<br />
| <br />
| <br />
|-<br />
| 17:00 UTC<br />
| <br />
| <br />
|-<br />
| 18:00 UTC<br />
| <br />
|-<br />
| 19:00 UTC<br />
| <br />
| <br />
|}<br />
<br />
=== Room 04 - 8th September ===<br />
{| class="wikitable" border="1"<br />
|-<br />
! TODO Link to Room 04<br />
!<br />
! <br />
|-<br />
! Time <br />
! Subject <br />
! Host/Notes<br />
|-<br />
| width="100pt" | 9:00 UTC<br />
| width="200pt" |<br />
| width="400pt" |<br />
|-<br />
| 10:00 UTC<br />
| <br />
| <br />
|-<br />
| 11:00 UTC<br />
| <br />
| <br />
|-<br />
| 12:00 UTC<br />
| Break<br />
|<br />
|-<br />
| 16:00 UTC<br />
| <br />
| <br />
|-<br />
| 17:00 UTC<br />
| <br />
| <br />
|-<br />
| 18:00 UTC<br />
| <br />
|-<br />
| 19:00 UTC<br />
| <br />
| <br />
|}</div>Dfaurehttps://community.kde.org/index.php?title=Akademy/2020/Tuesday&diff=89009Akademy/2020/Tuesday2020-07-18T18:34:49Z<p>Dfaure: /* Room 01 - 8th September */</p>
<hr />
<div>= BoF sessions on Tuesday, 8th September 2020 =<br />
<br />
<br />
Please put your name and email address in the Host/Notes section. There is no length limitation; text will wrap. <br />
<br />
The Akademy team might reassign BoFs based on operational needs<br />
<br />
=== Room 01 - 8th September ===<br />
{| class="wikitable" border="1"<br />
|-<br />
! TODO Link to Room 01<br />
!<br />
! <br />
|-<br />
! Time <br />
! Subject <br />
! Host/Notes<br />
|-<br />
| width="100pt" | 9:00 UTC<br />
| width="200pt" | KDE Frameworks 6<br />
| width="400pt" |<br />
|-<br />
| 10:00 UTC<br />
| <br />
| <br />
|-<br />
| 11:00 UTC<br />
| <br />
| <br />
|-<br />
| 12:00 UTC<br />
| Break<br />
|<br />
|-<br />
| 16:00 UTC<br />
|<br />
|<br />
|-<br />
| 17:00 UTC<br />
| (Tentative) KDE Connect Design Discussion (with KDE VDG)<br />
| KDE Connect Team<br />
|-<br />
| 18:00 UTC<br />
| Plasma Discover<br />
| Aleix Pol<br />
|-<br />
| 19:00 UTC<br />
| <br />
| <br />
|-<br />
| 19:30 UTC<br />
| Bof Wrap Up<br />
|<br />
|}<br />
<br />
=== Room 02 - 8th September ===<br />
{| class="wikitable" border="1"<br />
|-<br />
! TODO Link to Room 01<br />
!<br />
! <br />
|-<br />
! Time <br />
! Subject <br />
! Host/Notes<br />
|-<br />
| width="100pt" | 9:00 UTC<br />
| width="200pt" |<br />
| width="400pt" |<br />
|-<br />
| 10:00 UTC<br />
| <br />
| <br />
|-<br />
| 11:00 UTC<br />
| <br />
| <br />
|-<br />
| 12:00 UTC<br />
| Break<br />
|<br />
|-<br />
| 16:00 UTC<br />
| Web<br />
| Carl and Web team<br />
|-<br />
| 17:00 UTC<br />
| <br />
| <br />
|-<br />
| 18:00 UTC<br />
| Dolphin<br />
| Elvis Angelaccio<br />
|-<br />
| 19:00 UTC<br />
| <br />
| <br />
|}<br />
<br />
=== Room 03 - 8th September ===<br />
{| class="wikitable" border="1"<br />
|-<br />
! TODO Link to Room 01<br />
!<br />
! <br />
|-<br />
! Time <br />
! Subject <br />
! Host/Notes<br />
|-<br />
| width="100pt" | 9:00 UTC<br />
| width="200pt" |<br />
| width="400pt" |<br />
|-<br />
| 10:00 UTC<br />
| <br />
| <br />
|-<br />
| 11:00 UTC<br />
| <br />
| <br />
|-<br />
| 12:00 UTC<br />
| Break<br />
|<br />
|-<br />
| 16:00 UTC<br />
| <br />
| <br />
|-<br />
| 17:00 UTC<br />
| <br />
| <br />
|-<br />
| 18:00 UTC<br />
| <br />
|-<br />
| 19:00 UTC<br />
| <br />
| <br />
|}<br />
<br />
=== Room 04 - 8th September ===<br />
{| class="wikitable" border="1"<br />
|-<br />
! TODO Link to Room 04<br />
!<br />
! <br />
|-<br />
! Time <br />
! Subject <br />
! Host/Notes<br />
|-<br />
| width="100pt" | 9:00 UTC<br />
| width="200pt" |<br />
| width="400pt" |<br />
|-<br />
| 10:00 UTC<br />
| <br />
| <br />
|-<br />
| 11:00 UTC<br />
| <br />
| <br />
|-<br />
| 12:00 UTC<br />
| Break<br />
|<br />
|-<br />
| 16:00 UTC<br />
| <br />
| <br />
|-<br />
| 17:00 UTC<br />
| <br />
| <br />
|-<br />
| 18:00 UTC<br />
| <br />
|-<br />
| 19:00 UTC<br />
| <br />
| <br />
|}</div>Dfaurehttps://community.kde.org/index.php?title=Frameworks/Policies&diff=88107Frameworks/Policies2020-04-26T15:12:27Z<p>Dfaure: /* Frameworks compiler requirements and C++11 */</p>
<hr />
<div><br />
== Frameworks have a Tier and a Type ==<br />
Each framework has a clear position in the Tier/Type matrix, its position forces a set of rules on its possible dependencies. This matrix and its rules are summarized in the [http://files.kde.org/frameworks/kde-frameworks-matrix.pdf Frameworks matrix document].<br />
<br />
<br />
The constraints from Tiers are the following:<br />
* Tier 1 Frameworks can depend only on Qt official frameworks or other system libraries;<br />
* Tier 2 Frameworks can depend only on Tier 1 Frameworks, Qt official frameworks, or other system libraries;<br />
* Tier 3 Frameworks can depend only on other Tier 3 Frameworks, Tier 2 Frameworks, Tier 1 Frameworks, Qt official frameworks, or other system libraries.<br />
<br />
<br />
The constraints from Types are the following:<br />
* Functional Qt Addons cannot have runtime dependencies;<br />
* Integration Qt Addons can have an optional runtime dependencies and aim at integrating with the underlying OS/Platform;<br />
* Solutions have mandatory runtime dependencies, it is part of their design and where their added value comes from (think scalability, resource sharing, resilience, etc.).<br />
<br />
== Framework directory structure ==<br />
All the frameworks will have the same directory structure which will follow some rules:<br />
* The containing directory has the name of the technology (plasma, kio, itemmodels, etc.);<br />
* At the top level we find the common files like README.md, COPYING.LIB, metainfo.yaml...<br />
* More comprehensive documentation go into a '''docs''' subdirectory<br />
* The source code for the targets go into '''src''' subdirectory, if several payloads are built (like a core lib and a gui layer on top) then src will contain one subdirectory per library: core, gui, widgets, etc.<br />
* Code examples go into an '''examples''' subdirectory<br />
* Automatic tests go into an '''autotests''' subdirectory<br />
* Test applications go into a '''tests''' subdirectory<br />
* CMake modules (FindFoo.cmake etc.) or CMake macro files go into '''cmake''' subdirectory<br />
<br />
== Frameworks have automatic unit tests ==<br />
Enough said really... They must be unit tested with automatic unit tests.<br />
<br />
Corollary: When fixing a bug in a framework, the auto-test proving the bug and the fix should come in the same commit.<br />
<br />
== Frameworks maintain binary compatibility ==<br />
Just like we did in kdelibs, KDE Frameworks maintain the binary compatibility through their lifetime, for more details see the [[Policies/Binary_Compatibility_Issues_With_C++| binary compatibility policy]].<br />
<br />
Note however that this policy is lifted during major version transition, corresponding epics of milestones will be marked as such.<br />
<br />
== Frameworks are documented ==<br />
<br />
The API exposed by frameworks are documented using Doxygen. Documentation follows the [[Frameworks/Frameworks_Documentation_Policy|Frameworks Documentation Policy]].<br />
<br />
== Frameworks are localized ==<br />
<br />
Frameworks adapt to the user language and locale settings. This is described in the [[Frameworks/Frameworks_Localization_Policy|Frameworks Localization Policy]].<br />
<br />
== Frameworks buildsystem is consistent ==<br />
<br />
* each framework should install a CMake configuration file for itself. This includes:<br />
** a FooConfig.cmake file<br />
** a FooConfigVersion.cmake file<br />
** usually a FooTargets.cmake file<br />
** optionally a file containing macros/functions for using the package<br />
* no framework should install any other CMake files than mentioned above. Find-modules useful for multiple packages should be upstreamed into extra-cmake-modules if they are generally useful. <br />
* For especially exotic packages which are not suitable for extra-cmake-modules, it is ok for a framework to have extra find modules, but they should not be installed.<br />
* Library names are in CamelCase<br />
* All dependencies between frameworks are documented in the CMakeLists.txt (see for instance kio/src/core/CMakeLists.txt)<br />
<br />
For an example, see the [http://quickgit.kde.org/?p=kdeexamples.git&a=tree&f=framework-template framework-template] directory in the kdeexamples repository (you can use setup.sh to create a template that matches the name of your framework).<br />
<br />
== Frameworks commits are reviewed ==<br />
Make sure all commits in the master branch of a repository part of the KDE Frameworks got a proper review. As such commits must contain either a "Reviewed by:" (for quick pastebin reviews) or a "REVIEW:" (for more formal reviewboard reviews).<br />
<br />
== Frameworks CI failures are treated as stop the line events ==<br />
When a commit causes a regression in the CI for one of the frameworks, then all work on the corresponding framework should stop. The only commits allowed in are those working toward a resolution of the problem. Only once the framework is green again that regular work can be resumed.<br />
<br />
== Frameworks Qt requirements ==<br />
KDE Frameworks are tested and working with the last 3 minor Qt releases. For instance, once Qt 5.11 was released, the minimum required Qt version changed from Qt 5.8 to Qt 5.9, i.e. the three supported Qt versions became 5.9, 5.10 and 5.11.<br />
<br />
In addition, a Qt LTS release remains supported until the next Qt release after the next Qt LTS release.<br />
For instance, when Qt 5.12 is released, Qt 5.9 remains supported until Qt 5.13, to give time for people to migrate from Qt 5.9 LTS to Qt 5.12 LTS. When Qt 5.13 is released, both Qt 5.9 LTS and Qt 5.10 are dropped, to go back to "last 3 minor Qt releases".<br />
<br />
With Qt6 this changes a little bit again. To avoid supporting 5.12 LTS and 5.15 LTS for ever, 5.15 LTS will be the minimum required version 18 months after its release.<br />
<br />
== Frameworks compiler requirements and C++11 ==<br />
The following minimal compiler versions are supported by KDE Frameworks:<br />
* GCC 4.8<br />
* Clang 3.3<br />
* VS2013 (MSVC12)<br />
<br />
This means all of the C++11 standards can be used.<br />
<br />
These requirements come from https://doc.qt.io/qt-5.12/supported-platforms.html</div>Dfaurehttps://community.kde.org/index.php?title=Frameworks/Policies&diff=88070Frameworks/Policies2020-04-19T22:03:46Z<p>Dfaure: /* Frameworks Qt requirements */</p>
<hr />
<div><br />
== Frameworks have a Tier and a Type ==<br />
Each framework has a clear position in the Tier/Type matrix, its position forces a set of rules on its possible dependencies. This matrix and its rules are summarized in the [http://files.kde.org/frameworks/kde-frameworks-matrix.pdf Frameworks matrix document].<br />
<br />
<br />
The constraints from Tiers are the following:<br />
* Tier 1 Frameworks can depend only on Qt official frameworks or other system libraries;<br />
* Tier 2 Frameworks can depend only on Tier 1 Frameworks, Qt official frameworks, or other system libraries;<br />
* Tier 3 Frameworks can depend only on other Tier 3 Frameworks, Tier 2 Frameworks, Tier 1 Frameworks, Qt official frameworks, or other system libraries.<br />
<br />
<br />
The constraints from Types are the following:<br />
* Functional Qt Addons cannot have runtime dependencies;<br />
* Integration Qt Addons can have an optional runtime dependencies and aim at integrating with the underlying OS/Platform;<br />
* Solutions have mandatory runtime dependencies, it is part of their design and where their added value comes from (think scalability, resource sharing, resilience, etc.).<br />
<br />
== Framework directory structure ==<br />
All the frameworks will have the same directory structure which will follow some rules:<br />
* The containing directory has the name of the technology (plasma, kio, itemmodels, etc.);<br />
* At the top level we find the common files like README.md, COPYING.LIB, metainfo.yaml...<br />
* More comprehensive documentation go into a '''docs''' subdirectory<br />
* The source code for the targets go into '''src''' subdirectory, if several payloads are built (like a core lib and a gui layer on top) then src will contain one subdirectory per library: core, gui, widgets, etc.<br />
* Code examples go into an '''examples''' subdirectory<br />
* Automatic tests go into an '''autotests''' subdirectory<br />
* Test applications go into a '''tests''' subdirectory<br />
* CMake modules (FindFoo.cmake etc.) or CMake macro files go into '''cmake''' subdirectory<br />
<br />
== Frameworks have automatic unit tests ==<br />
Enough said really... They must be unit tested with automatic unit tests.<br />
<br />
Corollary: When fixing a bug in a framework, the auto-test proving the bug and the fix should come in the same commit.<br />
<br />
== Frameworks maintain binary compatibility ==<br />
Just like we did in kdelibs, KDE Frameworks maintain the binary compatibility through their lifetime, for more details see the [[Policies/Binary_Compatibility_Issues_With_C++| binary compatibility policy]].<br />
<br />
Note however that this policy is lifted during major version transition, corresponding epics of milestones will be marked as such.<br />
<br />
== Frameworks are documented ==<br />
<br />
The API exposed by frameworks are documented using Doxygen. Documentation follows the [[Frameworks/Frameworks_Documentation_Policy|Frameworks Documentation Policy]].<br />
<br />
== Frameworks are localized ==<br />
<br />
Frameworks adapt to the user language and locale settings. This is described in the [[Frameworks/Frameworks_Localization_Policy|Frameworks Localization Policy]].<br />
<br />
== Frameworks buildsystem is consistent ==<br />
<br />
* each framework should install a CMake configuration file for itself. This includes:<br />
** a FooConfig.cmake file<br />
** a FooConfigVersion.cmake file<br />
** usually a FooTargets.cmake file<br />
** optionally a file containing macros/functions for using the package<br />
* no framework should install any other CMake files than mentioned above. Find-modules useful for multiple packages should be upstreamed into extra-cmake-modules if they are generally useful. <br />
* For especially exotic packages which are not suitable for extra-cmake-modules, it is ok for a framework to have extra find modules, but they should not be installed.<br />
* Library names are in CamelCase<br />
* All dependencies between frameworks are documented in the CMakeLists.txt (see for instance kio/src/core/CMakeLists.txt)<br />
<br />
For an example, see the [http://quickgit.kde.org/?p=kdeexamples.git&a=tree&f=framework-template framework-template] directory in the kdeexamples repository (you can use setup.sh to create a template that matches the name of your framework).<br />
<br />
== Frameworks commits are reviewed ==<br />
Make sure all commits in the master branch of a repository part of the KDE Frameworks got a proper review. As such commits must contain either a "Reviewed by:" (for quick pastebin reviews) or a "REVIEW:" (for more formal reviewboard reviews).<br />
<br />
== Frameworks CI failures are treated as stop the line events ==<br />
When a commit causes a regression in the CI for one of the frameworks, then all work on the corresponding framework should stop. The only commits allowed in are those working toward a resolution of the problem. Only once the framework is green again that regular work can be resumed.<br />
<br />
== Frameworks Qt requirements ==<br />
KDE Frameworks are tested and working with the last 3 minor Qt releases. For instance, once Qt 5.11 was released, the minimum required Qt version changed from Qt 5.8 to Qt 5.9, i.e. the three supported Qt versions became 5.9, 5.10 and 5.11.<br />
<br />
In addition, a Qt LTS release remains supported until the next Qt release after the next Qt LTS release.<br />
For instance, when Qt 5.12 is released, Qt 5.9 remains supported until Qt 5.13, to give time for people to migrate from Qt 5.9 LTS to Qt 5.12 LTS. When Qt 5.13 is released, both Qt 5.9 LTS and Qt 5.10 are dropped, to go back to "last 3 minor Qt releases".<br />
<br />
With Qt6 this changes a little bit again. To avoid supporting 5.12 LTS and 5.15 LTS for ever, 5.15 LTS will be the minimum required version 18 months after its release.<br />
<br />
== Frameworks compiler requirements and C++11 ==<br />
The following minimal compiler versions are supported by KDE Frameworks:<br />
* GCC 4.8<br />
* Clang 3.3<br />
* VS2013 (MSVC12)<br />
<br />
This means all of the C++11 standards can be used.</div>Dfaurehttps://community.kde.org/index.php?title=Frameworks/Policies&diff=88069Frameworks/Policies2020-04-19T22:00:46Z<p>Dfaure: /* Frameworks Qt requirements */</p>
<hr />
<div><br />
== Frameworks have a Tier and a Type ==<br />
Each framework has a clear position in the Tier/Type matrix, its position forces a set of rules on its possible dependencies. This matrix and its rules are summarized in the [http://files.kde.org/frameworks/kde-frameworks-matrix.pdf Frameworks matrix document].<br />
<br />
<br />
The constraints from Tiers are the following:<br />
* Tier 1 Frameworks can depend only on Qt official frameworks or other system libraries;<br />
* Tier 2 Frameworks can depend only on Tier 1 Frameworks, Qt official frameworks, or other system libraries;<br />
* Tier 3 Frameworks can depend only on other Tier 3 Frameworks, Tier 2 Frameworks, Tier 1 Frameworks, Qt official frameworks, or other system libraries.<br />
<br />
<br />
The constraints from Types are the following:<br />
* Functional Qt Addons cannot have runtime dependencies;<br />
* Integration Qt Addons can have an optional runtime dependencies and aim at integrating with the underlying OS/Platform;<br />
* Solutions have mandatory runtime dependencies, it is part of their design and where their added value comes from (think scalability, resource sharing, resilience, etc.).<br />
<br />
== Framework directory structure ==<br />
All the frameworks will have the same directory structure which will follow some rules:<br />
* The containing directory has the name of the technology (plasma, kio, itemmodels, etc.);<br />
* At the top level we find the common files like README.md, COPYING.LIB, metainfo.yaml...<br />
* More comprehensive documentation go into a '''docs''' subdirectory<br />
* The source code for the targets go into '''src''' subdirectory, if several payloads are built (like a core lib and a gui layer on top) then src will contain one subdirectory per library: core, gui, widgets, etc.<br />
* Code examples go into an '''examples''' subdirectory<br />
* Automatic tests go into an '''autotests''' subdirectory<br />
* Test applications go into a '''tests''' subdirectory<br />
* CMake modules (FindFoo.cmake etc.) or CMake macro files go into '''cmake''' subdirectory<br />
<br />
== Frameworks have automatic unit tests ==<br />
Enough said really... They must be unit tested with automatic unit tests.<br />
<br />
Corollary: When fixing a bug in a framework, the auto-test proving the bug and the fix should come in the same commit.<br />
<br />
== Frameworks maintain binary compatibility ==<br />
Just like we did in kdelibs, KDE Frameworks maintain the binary compatibility through their lifetime, for more details see the [[Policies/Binary_Compatibility_Issues_With_C++| binary compatibility policy]].<br />
<br />
Note however that this policy is lifted during major version transition, corresponding epics of milestones will be marked as such.<br />
<br />
== Frameworks are documented ==<br />
<br />
The API exposed by frameworks are documented using Doxygen. Documentation follows the [[Frameworks/Frameworks_Documentation_Policy|Frameworks Documentation Policy]].<br />
<br />
== Frameworks are localized ==<br />
<br />
Frameworks adapt to the user language and locale settings. This is described in the [[Frameworks/Frameworks_Localization_Policy|Frameworks Localization Policy]].<br />
<br />
== Frameworks buildsystem is consistent ==<br />
<br />
* each framework should install a CMake configuration file for itself. This includes:<br />
** a FooConfig.cmake file<br />
** a FooConfigVersion.cmake file<br />
** usually a FooTargets.cmake file<br />
** optionally a file containing macros/functions for using the package<br />
* no framework should install any other CMake files than mentioned above. Find-modules useful for multiple packages should be upstreamed into extra-cmake-modules if they are generally useful. <br />
* For especially exotic packages which are not suitable for extra-cmake-modules, it is ok for a framework to have extra find modules, but they should not be installed.<br />
* Library names are in CamelCase<br />
* All dependencies between frameworks are documented in the CMakeLists.txt (see for instance kio/src/core/CMakeLists.txt)<br />
<br />
For an example, see the [http://quickgit.kde.org/?p=kdeexamples.git&a=tree&f=framework-template framework-template] directory in the kdeexamples repository (you can use setup.sh to create a template that matches the name of your framework).<br />
<br />
== Frameworks commits are reviewed ==<br />
Make sure all commits in the master branch of a repository part of the KDE Frameworks got a proper review. As such commits must contain either a "Reviewed by:" (for quick pastebin reviews) or a "REVIEW:" (for more formal reviewboard reviews).<br />
<br />
== Frameworks CI failures are treated as stop the line events ==<br />
When a commit causes a regression in the CI for one of the frameworks, then all work on the corresponding framework should stop. The only commits allowed in are those working toward a resolution of the problem. Only once the framework is green again that regular work can be resumed.<br />
<br />
== Frameworks Qt requirements ==<br />
KDE Frameworks are tested and working with the last 3 minor Qt releases. For instance, once Qt 5.11 was released, the minimum required Qt version changed from Qt 5.8 to Qt 5.9, i.e. the three supported Qt versions became 5.9, 5.10 and 5.11.<br />
<br />
In addition, a Qt LTS release remains supported until the next Qt release after the next Qt LTS release.<br />
For instance, when Qt 5.12 is released, Qt 5.9 remains supported until Qt 5.13, to give time for people to migrate from Qt 5.9 LTS to Qt 5.12 LTS. When Qt 5.13 is released, both Qt 5.15 LTS and Qt 5.16 are dropped, to go back to "last 3 minor Qt releases".<br />
<br />
With Qt6 this changes a little bit again. To avoid supporting 5.12 LTS and 5.15 LTS for ever, 5.15 LTS will be the minimum required version 18 months after its release.<br />
<br />
== Frameworks compiler requirements and C++11 ==<br />
The following minimal compiler versions are supported by KDE Frameworks:<br />
* GCC 4.8<br />
* Clang 3.3<br />
* VS2013 (MSVC12)<br />
<br />
This means all of the C++11 standards can be used.</div>Dfaurehttps://community.kde.org/index.php?title=Policies/Binary_Compatibility_Issues_With_C%2B%2B&diff=87982Policies/Binary Compatibility Issues With C++2020-04-04T22:38:55Z<p>Dfaure: /* Using a d-Pointer */</p>
<hr />
<div><languages /><br />
<translate><br />
<br />
== Definition ==<br />
<br />
A library is '''binary compatible''', if a program linked dynamically to a former version of the library continues running with newer versions of the library without the need to recompile.<br />
<br />
If a program needs to be recompiled to run with a new version of library but doesn't require any further modifications, the library is '''source compatible'''.<br />
<br />
Binary compatibility saves a lot of trouble. It makes it much easier to distribute software for a certain platform. Without ensuring binary compatibility between releases, people will be forced to provide statically linked binaries. Static binaries are bad because they<br />
* waste resources (especially memory)<br />
* don't allow the program to benefit from bugfixes or extensions in the libraries<br />
<br />
In the KDE project, we will provide binary compatibility within the life-span of a major release for the core libraries (kdelibs, kdepimlibs).<br />
<br />
== Note about ABI ==<br />
<br />
This text applies to most C++ ABIs used by compilers which KDE can be built with. It is mostly based on the [https://itanium-cxx-abi.github.io/cxx-abi/abi.html Itanium C++ ABI Draft], which is used by the GCC C++ compiler since version 3.4 in all platforms it supports. Information about Microsoft Visual C++ mangling scheme mostly comes from [http://www.agner.org/optimize/calling_conventions.pdf this article on calling conventions] (it's the most complete information found so far on MSVC ABI and name mangling).<br />
<br />
Some of the constraints specified here may not apply to a given compiler. The goal here is to list the most restrictive set of conditions when writing cross-platform C++ code, meant to be compiled with several different compilers.<br />
<br />
This page is updated when new binary incompatibility issues are found.<br />
<br />
== The Do's and Don'ts ==<br />
<br />
You can...<br />
<br />
* add new non-virtual functions including signals and slots and constructors.<br />
* add a new enum to a class.<br />
* append new enumerators to an existing enum.<br />
** Exeption: if that leads to the compiler choosing a larger underlying type for the enum, that makes the change binary-incompatible. Unfortunately, compilers have some leeway to choose the underlying type, so from an API-design perspective it's recommended to add a '''Max....''' enumerator with an explicit large value ('''=255''', '''=1<<15''', etc) to create an interval of numeric enumerator values that is guaranteed to fit into the chosen underlying type, whatever that may be.<br />
* reimplement virtual functions defined in the primary base class hierarchy (that is, virtuals defined in the first non-virtual base class, or in that class's first non-virtual base class, and so forth) '''if''' it is safe that programs linked with the prior version of the library call the implementation in the base class rather than the derived one. ''This is tricky and might be dangerous. Think twice before doing it. Alternatively see below for a workaround.''<br />
** Exception: if the overriding function has a [http://en.wikipedia.org/wiki/Covariant_return_type covariant return type], it's only a binary-compatible change if the more-derived type has always the same pointer address as the less-derived one. ''If in doubt, do not override with a covariant return type.''<br />
* change an inline function or make an inline function non-inline '''if''' it is safe that programs linked with the prior version of the library call the old implementation. ''This is tricky and might be dangerous. Think twice before doing it.''<br />
* remove private non-virtual functions '''if''' they are not called by any inline functions (and have never been).<br />
* remove private static members '''if''' they are not called by any inline functions (and have never been).<br />
* add new '''static''' data members.<br />
* change the default arguments of a method. It requires recompilation to use the actual new default argument values, though.<br />
* add new classes.<br />
* export a class that was not previously exported.<br />
* add or remove friend declarations to classes.<br />
* rename reserved member types<br />
* extend reserved bit fields, provided this doesn't cause the bit field to cross the boundary of its underlying type (8 bits for char & bool, 16 bits for short, 32 bits for int, etc.)<br />
* add the Q_OBJECT macro to a class if the class already inherits from QObject<br />
* add a Q_PROPERTY, Q_ENUMS or Q_FLAGS macro as that only modifies the meta-object generated by moc and not the class itself<br />
<br />
You cannot...<br />
* For existing classes:<br />
** [[Policies/Binary_Compatibility_Examples#Unexport_or_remove_a_class|unexport or remove]] an exported class.<br />
** [[Policies/Binary_Compatibility_Examples#Change_the_class_hierarchy|change the class hierachy]] in any way (add, remove, or reorder base classes).<br />
** [[Policies/Binary_Compatibility_Examples#Remove_class_finality|Remove]] <code>final</code>ity<br />
* For template classes:<br />
** [[Policies/Binary_Compatibility_Examples#Change_the_template_arguments_of_a_template_class|change the template arguments]] in any way (add, remove or reorder).<br />
* For existing functions of any type:<br />
** [[Policies/Binary_Compatibility_Examples#Unexport_a_function|unexport]] it.<br />
** remove it.<br />
*** Remove the implementation of existing declared functions. The symbol comes from the implementation of the function, so this is effectively the function.<br />
** [[Policies/Binary_Compatibility_Examples#Inline_a_function|inline]] it (this includes moving a member function's body to the class definition, even without the inline keyword).<br />
** add an overload (BC, but not SC: makes <tt>&func</tt> ambiguous), adding overloads to already overloaded functions is ok (any use of <tt>&func</tt> already needed a cast).<br />
** change its signature. This includes:<br />
*** changing any of the types of the arguments in the [[Policies/Binary_Compatibility_Examples#Change_the_parameters_of_a_function|parameter list]], including changing the const/volatile qualifiers of the existing parameters (instead, add a new method)<br />
*** changing the const/volatile qualifiers of the function<br />
*** changing the [[Policies/Binary_Compatibility_Examples#Change_the_access_rights|access rights]] to some functions or data members, for example from <tt>private</tt> to <tt>public</tt>. With some compilers, this information may be part of the signature. If you need to make a private function protected or even public, you have to add a new function that calls the private one.<br />
*** changing the [[Policies/Binary_Compatibility_Examples#Change_the_CV-qualifiers_of_a_member_function|CV-qualifiers of a member function]]: the const and/or volatile that apply to the function itself.<br />
*** extending a function with another parameter, even if this parameter has a default argument. ''See below for a suggestion on how to avoid this issue''<br />
*** changing the [[Policies/Binary_Compatibility_Examples#Change_the_return_type|return type]] in any way<br />
*** Exception: non-member functions declared with extern "C" can change parameter types (be very careful).<br />
* For virtual member functions:<br />
** [[Policies/Binary_Compatibility_Examples#Add_a_virtual_member_function_to_a_class_without_any|add a virtual function]] to a class that doesn't have any virtual functions or virtual bases.<br />
** [[Policies/Binary_Compatibility_Examples#Add_new_virtuals_to_a_non-leaf_class|add new virtual functions]] to non-leaf classes as this will break subclasses. Note that a class designed to be subclassed by applications is '''always''' a non-leaf class. ''See below for some workarounds or ask on mailing lists.''<br />
** add new virtual functions for any reason, even to leaf classes, ''if the class is intended to remain binary compatible on Windows''. Doing so may [http://lists.kde.org/?l=kde-core-devel&m=139744177410091&w=2 reorder existing virtual functions] and break binary compatibility.<br />
** [[Policies/Binary_Compatibility_Examples#Change_the_order_of_the_declaration_of_virtual_functions|change the order]] of virtual functions in the class declaration.<br />
** [[Policies/Binary_Compatibility_Examples#Override_a_virtual_that_doesn.27t_come_from_a_primary_base|override an existing virtual function if that function is not in the primary base class]] (first non-virtual base class, or the primary base class's primary base class and upwards).<br />
** [[Policies/Binary_Compatibility_Examples#Override_a_virtual_with_a_covariant_return_with_different_top_address|override an existing virtual function]] if the overriding function has a [http://en.wikipedia.org/wiki/Covariant_return_type covariant return type] for which the more-derived type has a pointer address different from the less-derived one (usually happens when, between the less-derived and the more-derived ones, there's multiple inheritance or virtual inheritance).<br />
** Remove a virtual function, even if it is a reimplementation of a virtual function from the base class<br />
* For static non-private members or for non-static non-member public data:<br />
** Remove or unexport it<br />
** Change its [[Policies/Binary_Compatibility_Examples#Change_the_type_of_global_data|type]]<br />
** Change its [[Policies/Binary_Compatibility_Examples#Change_the_CV-qualifiers_of_global_data|CV-qualifiers]]<br />
* For non-static members:<br />
** add new, data members to an existing class.<br />
** change the order of non-static data members in a class.<br />
** change the type of the member, except for signedness<br />
** remove existing non-static data members from an existing class.<br />
<br />
If you need to add extend/modify the parameter list of an existing function, you need to add a new function instead with the new parameters. In that case, you may want to add a short note that the two functions shall be merged with a default argument in later versions of the library:<br />
<br />
<source lang="cpp-qt"><br />
void functionname( int a );<br />
void functionname( int a, int b ); //BCI: merge with int b = 0<br />
</source><br />
<br />
You should...<br />
<br />
In order to make a class to extend in the future you should follow these rules:<br />
* add d-pointer. ''See below''.<br />
* add non-inline virtual destructor even if the body is empty.<br />
* reimplement <tt>event</tt> in QObject-derived classes, even if the body for the function is just calling the base class' implementation. This is specifically to avoid problems caused by adding a reimplemented virtual function as discussed below.<br />
* make all constructors non-inline.<br />
* write non-inline implementations of the copy constructor and assignment operator unless the class cannot be copied by value (e.g. classes inherited from QObject can't be)<br />
<br />
== Techniques for Library Programmers ==<br />
<br />
The biggest problem when writing libraries is, that one cannot safely add data members since this would change the size and layout of every class, struct, or array containing objects of the type, including subclasses.<br />
<br />
=== Bitflags ===<br />
One exception are bitflags. If you use bitflags for enums or bools, you can safely round up to at least the next byte minus 1. A class with members<br />
<br />
<source lang="cpp-qt"><br />
uint m1 : 1;<br />
uint m2 : 3;<br />
uint m3 : 1;<br />
</source><br />
<source lang="cpp-qt"><br />
uint m1 : 1;<br />
uint m2 : 3;<br />
uint m3 : 1;<br />
uint m4 : 2; // new member<br />
</source><br />
without breaking binary compatibility. Please round up to a maxmimum of 7 bits (or 15 if the bitfield was already larger than 8). Using the very last bit may cause problems on some compilers.<br />
<br />
=== Using a d-Pointer===<br />
Bitflags and predefined reserved variables are nice, but far from being sufficient. This is where the d-pointer technique comes into play. The name "d-pointer" stems from Trolltech's Arnt Gulbrandsen, who first introduced the technique into Qt, making it one of the first C++ GUI libraries to maintain binary compatibility even between bigger release. The technique was quickly adapted as general programming pattern for the KDE libraries by everyone who saw it. It's a great trick to be able to add new private data members to a class without breaking binary compatibility.<br />
<br />
'''Remark:''' The d-pointer pattern has been described many<br />
times in computer science history under various names, e.g. as pimpl,<br />
as handle/body or as cheshire cat. Google helps finding online papers<br />
for any of these, just add C++ to the search terms.<br />
<br />
In your class definition for class Foo, define a forward declaration<br />
<source lang="cpp-qt"><br />
class FooPrivate;<br />
</source><br />
and the d-pointer in the private section:<br />
<source lang="cpp-qt"><br />
private:<br />
FooPrivate* d;<br />
</source><br />
The FooPrivate class itself is purely defined in the class implementation file (usually *.cpp ), for example:<br />
<source lang="cpp-qt"><br />
class FooPrivate {<br />
public:<br />
FooPrivate()<br />
: m1(0), m2(0)<br />
{}<br />
int m1;<br />
int m2;<br />
QString s;<br />
};<br />
</source><br />
<br />
All you have to do now is to create the private data in your constructors or your init function with<br />
<source lang="cpp-qt"><br />
d = new FooPrivate;<br />
</source><br />
and to delete it again in your destructor with<br />
<source lang="cpp-qt"><br />
delete d;<br />
</source><br />
<br />
In most circumstances you will want to make the dpointer constant to catch situations where it's accidentally getting modified or copied over so you'd lose ownership of the private object and create a memory leak:<br />
<source lang="cpp-qt"><br />
private:<br />
FooPrivate* const d;<br />
</source><br />
This allows you to modify the object pointed to by d but not the value of the pointer after it has been initialized.<br />
<br />
You may not want all member variables to live in the private data object, though. For very often used members, it's faster to put them directly in the class, since inline functions cannot access the d-pointer data. Also note that all data covered by the d-pointer is "private", despite being declared public in the d-pointer itself. For public or protected access, provide both a set and a get function. Example<br />
<source lang="cpp-qt"><br />
QString Foo::string() const<br />
{<br />
return d->s;<br />
}<br />
<br />
void Foo::setString( const QString& s )<br />
{<br />
d->s = s;<br />
}<br />
</source><br />
<br />
It is also possible (but not recommended) to declare the private class for the d-pointer as a nested private class (e.g. Foo::Private). If you use this technique, remember that the nested private class will inherit the public symbol visibility of the containing exported class. This will cause the functions of the private class to be named in the dynamic library's symbol table. You can use <code>Q_DECL_HIDDEN</code> in the implementation of the nested private class to manually re-hide the symbols. (For an existing class, this is technically an ABI change, but does not impact the public ABI supported by the KDE developers, so private symbols mistaken exposed may be re-hidden without further warning.). Other downsides of the nested private class include the lack of consistency with Qt and its Q_D/Q_Q macros, and the fact that it can't be forward-declared in unrelated headers anymore (which can be useful to declare it as a friend class). For all these reasons, prefer FooPrivate.<br />
<br />
<h2>Trouble shooting</h2><br />
<br />
=== Adding new data members to classes without d-pointer === <br />
<br />
If you don't have free bitflags, reserved variables and no d-pointer either, but you absolutely have to add a new private member variable, there are still some possibilities left. If your class inherits {{qt|QObject}}, you can for example place the additional data in a special child and find it by traversing over the list of children. You can access the list of children with QObject::children(). However, a fancier and usually faster approach is to use a hashtable to store a<br />
mapping between your object and the extra data. For this purpose, Qt provides a pointer-based dictionary called {{qt|QHash}} (or {{qt3|QPtrDict}} in Qt3).<br />
<br />
The basic trick in your class implementation of class Foo is:<br />
* Create a private data class FooPrivate.<br />
* Create a static QHash&lt;Foo *, FooPrivate *&gt;.<br />
*Note that some compilers/linkers (almost all, unfortunately) do not manage to create static objects in shared libraries. They simply forget to call the constructor. Therefore you should use the <tt>Q_GLOBAL_STATIC</tt> macro to create and access the object:<br />
<br />
<source lang="cpp-qt"><br />
// BCI: Add a real d-pointer<br />
typedef QHash<Foo *, FooPrivate *> FooPrivateHash;<br />
Q_GLOBAL_STATIC(FooPrivateHash, d_func)<br />
static FooPrivate *d(const Foo *foo)<br />
{<br />
FooPrivate *ret = d_func()->value(foo);<br />
if ( ! ret ) {<br />
ret = new FooPrivate;<br />
d_func()->insert(foo, ret);<br />
}<br />
return ret;<br />
}<br />
static void delete_d(const Foo *foo)<br />
{<br />
FooPrivate *ret = d_func()->value(foo);<br />
delete ret;<br />
d_func()->remove(foo);<br />
}<br />
</source><br />
<br />
* Now you can use the d-pointer in your class almost as simple as in the code before, just with a function call to d(this). For example:<br />
<br />
<source lang="cpp-qt"><br />
d(this)->m1 = 5;<br />
</source><br />
<br />
* Add a line to your destructor:<br />
<source lang="cpp-qt"><br />
delete_d(this);<br />
</source><br />
* Do not forget to add a BCI remark, so that the hack can be removed in the next version of the library.<br />
* Do not forget to add a d-pointer to your next class.<br />
<br />
=== Adding a reimplemented virtual function ===<br />
<br />
As already explained, you can safely reimplement a virtual function defined in one of the base classes only if it is safe that the programs linked with the prior version call the implementation in the base class rather than the derived one. This is because the compiler sometimes calls virtual functions directly if it can determine which one to call. For example, if you have <br />
<source lang="cpp-qt"><br />
void C::foo()<br />
{<br />
B::foo();<br />
}<br />
</source><br />
<br />
then B::foo() is called directly. If class B inherits from class A which implements foo() and B itself doesn't reimplement it, then C::foo() will in fact call A::foo(). If a newer version of the library adds B::foo(), C::foo() will call it only after a recompilation.<br />
<br />
Another more common example is:<br />
<source lang="cpp-qt"><br />
B b; // B derives from A<br />
b.foo();<br />
</source><br />
then the call to foo() will not use the virtual table. That means that<br />
if B::foo() didn't exist in the library but now does, code that was<br />
compiled with the earlier version will still call A::foo().<br />
<br />
If you can't guarantee things will continue to work without a recompilation, move functionality from A::foo() to a new protected function A::foo2() and use this code:<br />
<source lang="cpp-qt"><br />
void A::foo()<br />
{<br />
if( B* b = dynamic_cast< B* >( this ))<br />
b->B::foo(); // B:: is important<br />
else<br />
foo2();<br />
}<br />
void B::foo()<br />
{<br />
// added functionality<br />
A::foo2(); // call base function with real functionality<br />
}<br />
</source><br />
All calls to A::foo() for objects of type B (or inherited) will result in calling B::foo(). The only case that will not work as expected are calls to A::foo() that explicitly specify A::foo(), but B::foo() calls A::foo2() instead and there should not be other places doing so.<br />
<br />
=== Using a new class ===<br />
<br />
A relatively simple method of "extending" a class can be writing a replacement class that will include also the new functionality (and that may inherit from the old class to reuse the code). This of course requires adapting and recompiling applications using the library, so it is not possible this way to fix or extend functionality of classes that are used by applications compiled against an older version of the library. However, especially with small and/or performance-critical classes it may be simpler to write them without making sure they'll be simple to extend in the future and if the need arises later write a new replacement class that will provide new features or better performance.<br />
<br />
=== Adding new virtual functions to leaf classes ===<br />
This technique is one of cases of using a new class that can help if there's a need to add new virtual functions to a class that should stay binary compatible and there is no class inheriting from it that should also stay binary compatible (i.e. all classes inheriting from it are in applications). In such case it's possible to add a new class inheriting from the original one that will add them. Applications using the new functionality will of course have to be modified to use the new class.<br />
<source lang="cpp-qt"><br />
class A {<br />
public:<br />
virtual void foo();<br />
};<br />
class B : public A { // newly added class<br />
public:<br />
virtual void bar(); // newly added virtual function<br />
};<br />
void A::foo()<br />
{<br />
// here it's needed to call a new virtual function<br />
if( B* this2 = dynamic_cast< B* >( this ))<br />
this2->bar();<br />
}<br />
</source><br />
It is not possible to use this technique when there are other inherited classes that should also stay binary compatible because they'd have to inherit from the new class.<br />
<br />
=== Using signals instead of virtual functions ===<br />
Qt's signals and slots are invoked using a special virtual method created by the Q_OBJECT macro and it exists in every class inherited from {{qt|QObject}}. Therefore adding new signals and slots doesn't affect binary compatibility and the signals/slots mechanism can be used to emulate virtual functions.<br />
<br />
<source lang="cpp-qt"><br />
class A : public QObject {<br />
Q_OBJECT<br />
public:<br />
A();<br />
virtual void foo();<br />
signals:<br />
void bar( int* ); // added new "virtual" function<br />
protected slots:<br />
// implementation of the virtual function in A<br />
void barslot( int* );<br />
};<br />
<br />
A::A()<br />
{<br />
connect(this, SIGNAL( bar(int*)), this, SLOT( barslot(int*)));<br />
}<br />
<br />
void A::foo()<br />
{<br />
int ret;<br />
emit bar( &ret );<br />
}<br />
<br />
void A::barslot( int* ret )<br />
{<br />
*ret = 10;<br />
}<br />
</source><br />
<br />
Function bar() will act like a virtual function, barslot() implements the actual functionality of it. Since signals have void return value, data must be returned using arguments. As there will be only one slot connected to the signal returning data from the slot this way will work without problems. Note that with Qt4 for this to work the connection type will have to be Qt::DirectConnection.<br />
<br />
If an inherited class will want to re-implement the functionality of bar() it will have to provide its own slot:<br />
<source lang="cpp-qt"><br />
class B : public A {<br />
Q_OBJECT<br />
public:<br />
B();<br />
protected slots: // necessary to specify as a slot again<br />
void barslot( int* ); // reimplemented functionality of bar()<br />
};<br />
<br />
B::B()<br />
{<br />
disconnect(this, SIGNAL(bar(int*)), this, SLOT(barslot(int*)));<br />
connect(this, SIGNAL(bar(int*)), this, SLOT(barslot(int*)));<br />
}<br />
<br />
void B::barslot( int* ret )<br />
{<br />
*ret = 20;<br />
}<br />
</source><br />
<br />
Now B::barslot() will act like virtual reimplementation of A::bar(). Note that it is necessary to specify barslot() again as a slot in B and that in the constructor it is necessary to first disconnect and then connect again, that will disconnect A::barslot() and connect B::barslot() instead.<br />
<br />
Note: the same can be accomplished by implementing a virtual slot.<br />
<br />
[[Category:Policies]] [[Category:C++]]<br />
</translate></div>Dfaurehttps://community.kde.org/index.php?title=Sprints/PIM/2020&diff=87970Sprints/PIM/20202020-04-04T14:00:24Z<p>Dfaure: /* Specific bugs */</p>
<hr />
<div>In-person meeting cancelled due to global pandemic.<br />
<br />
=Sprint Schedule=<br />
<br />
April 4/5, 2019<br />
<br />
=Agenda=<br />
<br />
Proposed topics, roughly grouped by scope. Feel free to extend and regroup this.<br />
<br />
=== General project stuff ===<br />
* [DONE] How can we get all of kde/pim migrated to gitlab? (Allen)<br />
* [DONE] Did the bi-monthly summary blog approach we tried over the last year work out and should we continue with this? (Volker)<br />
* [DONE] Should we phase out the Kolab resource in favor of IMAP+DAV, and if so, how can we do that practically? (Volker)<br />
* [DONE] Progress of frameworkification, is KDAV ready to go, which framework is next after that? (Volker)<br />
<br />
=== KF6 ===<br />
* [DONE] The use of KParts in kdepim (with some KF6 changes in mind) (David)<br />
* [DONE] KF6/Qt6: anything problematic or anything larger to do in PIM or "our" frameworks? The Kross usage in accountwizard comes to mind. (Volker)<br />
<br />
=== Larger reviews ===<br />
* [DONE] Review and finalize the API of Nicolas' platform calendar access abstraction - https://phabricator.kde.org/D24443. (Volker)<br />
* Review the KUserFeedback usage for 20.04 (Volker)<br />
<br />
=== Specific bugs ===<br />
* Deleting multiple emails really fast leads to some of them being stuck in "about to be deleted" state (David)<br />
* Deleting emails while the inbox is sync'ed leads to emails reappearing before disappearing again (David)<br />
* Finding out why kmail often shows "This message is encrypted" erroneously (David)<br />
* Finding out why contact completion/search doesn't find some contacts (David)<br />
* KOrganizer: can't modify item immediately after creating it ([https://bugs.kde.org/show_bug.cgi?id=407965 bug 407965]), https://phabricator.kde.org/D16917 didn't fully fix it? => https://phabricator.kde.org/D28559 (David)<br />
<br />
=Notes=<br />
<br />
* KDAV: David and ervin agree with the move, ervin will do another API review<br />
* Frameworkification:<br />
** kgapi - this is used externally AFAIK, so it might be worth moving? Dan?<br />
*** dvratil: needs porting to KJob (from the custom KJob-like code) and API cleanup, otherwise good to go<br />
** the entire set of email libs - lots of work, does anyone externally need those right now?<br />
*** dvratil: KMime make a lot of sense, but probably needs a good API review<br />
* KParts usage:<br />
** dfaure: <tt>lxr reminded me that kdepim uses KParts for embedding into kontact. I just had a deeper look, and it actually makes sense (KParts is basically a plugin mechanism with a widget() method, a XMLGuiClient+actionCollection for actions, and a KAboutData, all of which make sense in kontact).</tt><br />
** The plan however is to port from KParts::ReadOnlyPart to KParts::Part and to move parts to kf5/parts/ subdir so that the new KParts::PartLoader can be used.<br />
* Bi-monthly summary blog:<br />
** works, let's keep doing this<br />
** let's not increase the frequency, lacking the bandwidth for this<br />
** do we have more volunteers to help with this? Sandro volunteered.<br />
* Kolab resource<br />
** we do have a similar problem with Google calendar/addressbook resources being merged into one, so a generic approach is needed anyway<br />
** migration approach: automatically migrate configuration and re-create the new resources, but do not migrate data and rely on resyncing instead.<br />
** akonadi_migration_agent exists for this, with UI, so we can probably integrate it there<br />
* Calendar plugins<br />
** Flat list, one-level grouped list or full tree?<br />
*** Flat list is not enough either way<br />
*** Only Kolab uses a full tree, so a one-level tree is enough from an Akonadi POV<br />
*** Go for the single level list by adding a CalendarGroup property to CalendarEntry.<br />
** Should CalendarEntry be folded into Calendar? -> yes<br />
** We do NOT need an enabled property per calendar, this is handled per application, not globally.<br />
** How do we do lazy population in calendar plugins?<br />
*** Add a (pseudo-)virtual open() method to Calendar, to trigger (async) population. This completes the existing lifecycle methods (close, reload, save, etc), and we consider API symmetry to outweigh the reasoning for moving sync() to CalendarPlugin.<br />
* Account Wizard:<br />
** Possible approaches<br />
*** port to QML and rewrite the JS scripted UI<br />
*** drop the account wizard in favor of KAccounts<br />
*** add a new widget-based plugin system to replace the scripted UI bits<br />
** KAccounts is where we want to get to ultimately, the other options might be needed as an intermediate step if we don'T get that done before the KF6 deadline though.<br />
** We need to find a solution for the D-Bus issue with Qt 5.14, that breaks the entire account wizard.<br />
* KF6/Qt6<br />
** We need to make sure Grantlee joins frameworks with KF6 for real this time.<br />
* Gitlab migration<br />
** We all want that, but it should happen all at once, once everything is ready and all repos transition.<br />
<br />
=Attendance=<br />
<br />
* Franck Arrecot<br />
* Laurent Montel<br />
* Kévin Ottens<br />
* David Faure<br />
* Dan Vratil<br />
* Andre Heinecke<br />
* Sandro Knauss<br />
* Volker Krause<br />
* Ingo Klöcker<br />
* Allen Winter<br />
<br />
=Report=<br />
<br />
TODO<br />
<br />
=Previous Meeting=<br />
<br />
[[Sprints/PIM/2019 | PIM Sprint 2019, 5-7 April, Toulouse, France]]</div>Dfaurehttps://community.kde.org/index.php?title=Sprints/PIM/2020&diff=87961Sprints/PIM/20202020-04-04T12:59:47Z<p>Dfaure: /* Specific bugs */</p>
<hr />
<div>In-person meeting cancelled due to global pandemic.<br />
<br />
=Sprint Schedule=<br />
<br />
April 4/5, 2019<br />
<br />
=Agenda=<br />
<br />
Proposed topics, roughly grouped by scope. Feel free to extend and regroup this.<br />
<br />
=== General project stuff ===<br />
* How can we get all of kde/pim migrated to gitlab? (Allen)<br />
* [DONE] Did the bi-monthly summary blog approach we tried over the last year work out and should we continue with this? (Volker)<br />
* [DONE] Should we phase out the Kolab resource in favor of IMAP+DAV, and if so, how can we do that practically? (Volker)<br />
* [DONE] Progress of frameworkification, is KDAV ready to go, which framework is next after that? (Volker)<br />
<br />
=== KF6 ===<br />
* [DONE] The use of KParts in kdepim (with some KF6 changes in mind) (David)<br />
* KF6/Qt6: anything problematic or anything larger to do in PIM or "our" frameworks? The Kross usage in accountwizard comes to mind. (Volker)<br />
<br />
=== Larger reviews ===<br />
* [DONE] Review and finalize the API of Nicolas' platform calendar access abstraction - https://phabricator.kde.org/D24443. (Volker)<br />
* Review the KUserFeedback usage for 20.04 (Volker)<br />
<br />
=== Specific bugs ===<br />
* Deleting multiple emails really fast leads to some of them being stuck in "about to be deleted" state (David)<br />
* Deleting emails while the inbox is sync'ed leads to emails reappearing before disappearing again (David)<br />
* Finding out why kmail often shows "This message is encrypted" erroneously (David)<br />
* Finding out why contact completion/search doesn't find some contacts (David)<br />
* KOrganizer: can't modify item immediately after creating it ([https://bugs.kde.org/show_bug.cgi?id=407965 bug 407965]), https://phabricator.kde.org/D16917 didn't fully fix it? Can anyone find a way to reproduce it? (David)<br />
<br />
=Notes=<br />
<br />
* KDAV: David and ervin agree with the move, ervin will do another API review<br />
* Frameworkification:<br />
** kgapi - this is used externally AFAIK, so it might be worth moving? Dan?<br />
** the entire set of email libs - lots of work, does anyone externally need those right now?<br />
* KParts usage:<br />
** dfaure: <tt>lxr reminded me that kdepim uses KParts for embedding into kontact. I just had a deeper look, and it actually makes sense (KParts is basically a plugin mechanism with a widget() method, a XMLGuiClient+actionCollection for actions, and a KAboutData, all of which make sense in kontact).</tt><br />
** The plan however is to port from KParts::ReadOnlyPart to KParts::Part and to move parts to kf5/parts/ subdir so that the new KParts::PartLoader can be used.<br />
* Bi-monthly summary blog:<br />
** works, let's keep doing this<br />
** let's not increase the frequency, lacking the bandwidth for this<br />
** do we have more volunteers to help with this? Sandro volunteered.<br />
* Kolab resource<br />
** we do have a similar problem with Google calendar/addressbook resources being merged into one, so a generic approach is needed anyway<br />
** migration approach: automatically migrate configuration and re-create the new resources, but do not migrate data and rely on resyncing instead.<br />
** akonadi_migration_agent exists for this, with UI, so we can probably integrate it there<br />
* Calendar plugins<br />
** Flat list, one-level grouped list or full tree?<br />
*** Flat list is not enough either way<br />
*** Only Kolab uses a full tree, so a one-level tree is enough from an Akonadi POV<br />
*** Go for the single level list by adding a CalendarGroup property to CalendarEntry.<br />
** Should CalendarEntry be folded into Calendar? -> yes<br />
** We do NOT need an enabled property per calendar, this is handled per application, not globally.<br />
** How do we do lazy population in calendar plugins?<br />
*** Add a (pseudo-)virtual open() method to Calendar, to trigger (async) population. This completes the existing lifecycle methods (close, reload, save, etc), and we consider API symmetry to outweigh the reasoning for moving sync() to CalendarPlugin.<br />
<br />
=Attendance=<br />
<br />
* Franck Arrecot<br />
* Laurent Montel<br />
* Kévin Ottens<br />
* David Faure<br />
* Dan Vratil<br />
* Andre Heinecke<br />
* Sandro Knauss<br />
* Volker Krause<br />
* Ingo Klöcker<br />
<br />
=Report=<br />
<br />
TODO<br />
<br />
=Previous Meeting=<br />
<br />
[[Sprints/PIM/2019 | PIM Sprint 2019, 5-7 April, Toulouse, France]]</div>Dfaurehttps://community.kde.org/index.php?title=Sprints/PIM/2020&diff=87949Sprints/PIM/20202020-04-04T11:36:50Z<p>Dfaure: /* Specific bugs */</p>
<hr />
<div>In-person meeting cancelled due to global pandemic.<br />
<br />
=Sprint Schedule=<br />
<br />
April 4/5, 2019<br />
<br />
=Agenda=<br />
<br />
Proposed topics, roughly grouped by scope. Feel free to extend and regroup this.<br />
<br />
=== General project stuff ===<br />
* How can we get all of kde/pim migrated to gitlab? (Allen)<br />
* [DONE] Did the bi-monthly summary blog approach we tried over the last year work out and should we continue with this? (Volker)<br />
* Should we phase out the Kolab resource in favor of IMAP+DAV, and if so, how can we do that practically? (Volker)<br />
* [DONE] Progress of frameworkification, is KDAV ready to go, which framework is next after that? (Volker)<br />
<br />
=== KF6 ===<br />
* [DONE] The use of KParts in kdepim (with some KF6 changes in mind) (David)<br />
* KF6/Qt6: anything problematic or anything larger to do in PIM or "our" frameworks? The Kross usage in accountwizard comes to mind. (Volker)<br />
<br />
=== Larger reviews ===<br />
* Review and finalize the API of Nicolas' platform calendar access abstraction. (Volker)<br />
* Review the KUserFeedback usage for 20.04 (Volker)<br />
<br />
=== Specific bugs ===<br />
* Deleting multiple emails really fast leads to some of them being stuck in "about to be deleted" state (David)<br />
* Deleting emails while the inbox is sync'ed leads to emails reappearing before disappearing again (David)<br />
* Finding out why kmail often shows "This message is encrypted" erroneously (David)<br />
* Finding out why contact completion/search doesn't find some contacts (David)<br />
* KOrganizer: can't modify item immediately after creating it ([https://bugs.kde.org/show_bug.cgi?id=407965 bug 407965]), seems fixed already (https://phabricator.kde.org/D16917) (David)<br />
<br />
=Notes=<br />
<br />
* KDAV: David and ervin agree with the move, ervin will do another API review<br />
* Frameworkification:<br />
** kgapi - this is used externally AFAIK, so it might be worth moving? Dan?<br />
** the entire set of email libs - lots of work, does anyone externally need those right now?<br />
* KParts usage:<br />
** dfaure: <tt>lxr reminded me that kdepim uses KParts for embedding into kontact. I just had a deeper look, and it actually makes sense (KParts is basically a plugin mechanism with a widget() method, a XMLGuiClient+actionCollection for actions, and a KAboutData, all of which make sense in kontact).</tt><br />
** The plan however is to port from KParts::ReadOnlyPart to KParts::Part and to move parts to kf5/parts/ subdir so that the new KParts::PartLoader can be used.<br />
* Bi-monthly summary blog:<br />
** works, let's keep doing this<br />
** let's not increase the frequency, lacking the bandwidth for this<br />
** do we have more volunteers to help with this? Sandro volunteered.<br />
<br />
=Attendance=<br />
<br />
* Franck Arrecot<br />
* Laurent Montel<br />
* Kévin Ottens<br />
* David Faure<br />
* Dan Vratil<br />
* Andre Heinecke<br />
* Sandro Knauss<br />
* Volker Krause<br />
* Ingo Klöcker<br />
<br />
=Report=<br />
<br />
TODO<br />
<br />
=Previous Meeting=<br />
<br />
[[Sprints/PIM/2019 | PIM Sprint 2019, 5-7 April, Toulouse, France]]</div>Dfaurehttps://community.kde.org/index.php?title=Sprints/PIM/2020&diff=87941Sprints/PIM/20202020-04-04T08:27:27Z<p>Dfaure: /* Notes */</p>
<hr />
<div>In-person meeting cancelled due to global pandemic.<br />
<br />
=Sprint Schedule=<br />
<br />
April 4/5, 2019<br />
<br />
=Agenda=<br />
<br />
Proposed topics, roughly grouped by scope. Feel free to extend and regroup this.<br />
<br />
=== General project stuff ===<br />
* How can we get all of kde/pim migrated to gitlab? (Allen)<br />
* Did the bi-monthly summary blog approach we tried over the last year work out and should we continue with this? (Volker)<br />
* Should we phase out the Kolab resource in favor of IMAP+DAV, and if so, how can we do that practically? (Volker)<br />
* [DONE] Progress of frameworkification, is KDAV ready to go, which framework is next after that? (Volker)<br />
<br />
=== KF6 ===<br />
* [DONE] The use of KParts in kdepim (with some KF6 changes in mind) (David)<br />
* KF6/Qt6: anything problematic or anything larger to do in PIM or "our" frameworks? The Kross usage in accountwizard comes to mind. (Volker)<br />
<br />
=== Larger reviews ===<br />
* Review and finalize the API of Nicolas' platform calendar access abstraction. (Volker)<br />
* Review the KUserFeedback usage for 20.04 (Volker)<br />
<br />
=== Specific bugs ===<br />
* KOrganizer: can't modify item immediately after creating it ([https://bugs.kde.org/show_bug.cgi?id=407965 bug 407965]) (David)<br />
* Deleting multiple emails really fast leads to some of them being stuck in "about to be deleted" state (David)<br />
* Deleting emails while the inbox is sync'ed leads to emails reappearing before disappearing again (David)<br />
* Finding out why kmail often shows "This message is encrypted" erroneously (David)<br />
* Finding out why contact completion/search doesn't find some contacts (David)<br />
<br />
=Notes=<br />
<br />
* KDAV: David and ervin agree with the move, ervin will do another API review<br />
* Frameworkification:<br />
** kgapi - this is used externally AFAIK, so it might be worth moving? Dan?<br />
** the entire set of email libs - lots of work, does anyone externally need those right now?<br />
* KParts usage:<br />
** dfaure: <tt>lxr reminded me that kdepim uses KParts for embedding into kontact. I just had a deeper look, and it actually makes sense (KParts is basically a plugin mechanism with a widget() method, a XMLGuiClient+actionCollection for actions, and a KAboutData, all of which make sense in kontact).</tt><br />
** The plan however is to port from KParts::ReadOnlyPart to KParts::Part and to move parts to kf5/parts/ subdir so that the new KParts::PartLoader can be used.<br />
<br />
=Attendance=<br />
<br />
* Franck Arrecot<br />
* Laurent Montel<br />
* Kévin Ottens<br />
* David Faure<br />
* Dan Vratil<br />
* Andre Heinecke<br />
* Sandro Knauss<br />
* Volker Krause<br />
* Ingo Klöcker<br />
<br />
=Report=<br />
<br />
TODO<br />
<br />
=Previous Meeting=<br />
<br />
[[Sprints/PIM/2019 | PIM Sprint 2019, 5-7 April, Toulouse, France]]</div>Dfaurehttps://community.kde.org/index.php?title=Sprints/PIM/2020&diff=87940Sprints/PIM/20202020-04-04T08:27:09Z<p>Dfaure: /* Notes */</p>
<hr />
<div>In-person meeting cancelled due to global pandemic.<br />
<br />
=Sprint Schedule=<br />
<br />
April 4/5, 2019<br />
<br />
=Agenda=<br />
<br />
Proposed topics, roughly grouped by scope. Feel free to extend and regroup this.<br />
<br />
=== General project stuff ===<br />
* How can we get all of kde/pim migrated to gitlab? (Allen)<br />
* Did the bi-monthly summary blog approach we tried over the last year work out and should we continue with this? (Volker)<br />
* Should we phase out the Kolab resource in favor of IMAP+DAV, and if so, how can we do that practically? (Volker)<br />
* [DONE] Progress of frameworkification, is KDAV ready to go, which framework is next after that? (Volker)<br />
<br />
=== KF6 ===<br />
* [DONE] The use of KParts in kdepim (with some KF6 changes in mind) (David)<br />
* KF6/Qt6: anything problematic or anything larger to do in PIM or "our" frameworks? The Kross usage in accountwizard comes to mind. (Volker)<br />
<br />
=== Larger reviews ===<br />
* Review and finalize the API of Nicolas' platform calendar access abstraction. (Volker)<br />
* Review the KUserFeedback usage for 20.04 (Volker)<br />
<br />
=== Specific bugs ===<br />
* KOrganizer: can't modify item immediately after creating it ([https://bugs.kde.org/show_bug.cgi?id=407965 bug 407965]) (David)<br />
* Deleting multiple emails really fast leads to some of them being stuck in "about to be deleted" state (David)<br />
* Deleting emails while the inbox is sync'ed leads to emails reappearing before disappearing again (David)<br />
* Finding out why kmail often shows "This message is encrypted" erroneously (David)<br />
* Finding out why contact completion/search doesn't find some contacts (David)<br />
<br />
=Notes=<br />
<br />
* KDAV: David and ervin agree with the move, ervin will do another API review<br />
* Frameworkification:<br />
** kgapi - this is used externally AFAIK, so it might be worth moving? Dan?<br />
** the entire set of email libs - lots of work, does anyone externally need those right now?<br />
* KParts usage:<br />
** dfaure: <tt>lxr reminded me that kdepim uses KParts for embedding into kontact. I just had a deeper look, and it actually makes sense (KParts is basically a plugin mechanism with a widget() method, a XMLGuiClient+actionCollection for actions, and a KAboutData, all of which make sense in kontact).</tt><br />
The plan however is to port from KParts::ReadOnlyPart to KParts::Part and to move parts to kf5/parts/ subdir so that the new KParts::PartLoader can be used.<br />
<br />
=Attendance=<br />
<br />
* Franck Arrecot<br />
* Laurent Montel<br />
* Kévin Ottens<br />
* David Faure<br />
* Dan Vratil<br />
* Andre Heinecke<br />
* Sandro Knauss<br />
* Volker Krause<br />
* Ingo Klöcker<br />
<br />
=Report=<br />
<br />
TODO<br />
<br />
=Previous Meeting=<br />
<br />
[[Sprints/PIM/2019 | PIM Sprint 2019, 5-7 April, Toulouse, France]]</div>Dfaurehttps://community.kde.org/index.php?title=Sprints/PIM/2020&diff=87939Sprints/PIM/20202020-04-04T08:26:02Z<p>Dfaure: /* Specific bugs */</p>
<hr />
<div>In-person meeting cancelled due to global pandemic.<br />
<br />
=Sprint Schedule=<br />
<br />
April 4/5, 2019<br />
<br />
=Agenda=<br />
<br />
Proposed topics, roughly grouped by scope. Feel free to extend and regroup this.<br />
<br />
=== General project stuff ===<br />
* How can we get all of kde/pim migrated to gitlab? (Allen)<br />
* Did the bi-monthly summary blog approach we tried over the last year work out and should we continue with this? (Volker)<br />
* Should we phase out the Kolab resource in favor of IMAP+DAV, and if so, how can we do that practically? (Volker)<br />
* [DONE] Progress of frameworkification, is KDAV ready to go, which framework is next after that? (Volker)<br />
<br />
=== KF6 ===<br />
* [DONE] The use of KParts in kdepim (with some KF6 changes in mind) (David)<br />
* KF6/Qt6: anything problematic or anything larger to do in PIM or "our" frameworks? The Kross usage in accountwizard comes to mind. (Volker)<br />
<br />
=== Larger reviews ===<br />
* Review and finalize the API of Nicolas' platform calendar access abstraction. (Volker)<br />
* Review the KUserFeedback usage for 20.04 (Volker)<br />
<br />
=== Specific bugs ===<br />
* KOrganizer: can't modify item immediately after creating it ([https://bugs.kde.org/show_bug.cgi?id=407965 bug 407965]) (David)<br />
* Deleting multiple emails really fast leads to some of them being stuck in "about to be deleted" state (David)<br />
* Deleting emails while the inbox is sync'ed leads to emails reappearing before disappearing again (David)<br />
* Finding out why kmail often shows "This message is encrypted" erroneously (David)<br />
* Finding out why contact completion/search doesn't find some contacts (David)<br />
<br />
=Notes=<br />
<br />
* KDAV: David and ervin agree with the move, ervin will do another API review<br />
* Frameworkification:<br />
** kgapi - this is used externally AFAIK, so it might be worth moving? Dan?<br />
** the entire set of email libs - lots of work, does anyone externally need those right now?<br />
* KParts usage:<br />
** dfaure: <tt>lxr reminded me that kdepim uses KParts for embedding into kontact. I just had a deeper look, and it actually makes sense (KParts is basically a plugin mechanism with a widget() method, a XMLGuiClient+actionCollection for actions, and a KAboutData, all of which make sense in kontact).</tt><br />
<br />
=Attendance=<br />
<br />
* Franck Arrecot<br />
* Laurent Montel<br />
* Kévin Ottens<br />
* David Faure<br />
* Dan Vratil<br />
* Andre Heinecke<br />
* Sandro Knauss<br />
* Volker Krause<br />
* Ingo Klöcker<br />
<br />
=Report=<br />
<br />
TODO<br />
<br />
=Previous Meeting=<br />
<br />
[[Sprints/PIM/2019 | PIM Sprint 2019, 5-7 April, Toulouse, France]]</div>Dfaurehttps://community.kde.org/index.php?title=Sprints/PIM/2020&diff=87922Sprints/PIM/20202020-04-03T08:49:37Z<p>Dfaure: /* Specific bugs */</p>
<hr />
<div>In-person meeting cancelled due to global pandemic.<br />
<br />
=Sprint Schedule=<br />
<br />
April 4/5, 2019<br />
<br />
=Agenda=<br />
<br />
Proposed topics, roughly grouped by scope. Feel free to extend and regroup this.<br />
<br />
=== General project stuff ===<br />
* How can we get all of kde/pim migrated to gitlab? (Allen)<br />
* Did the bi-monthly summary blog approach we tried over the last year work out and should we continue with this? (Volker)<br />
* Should we phase out the Kolab resource in favor of IMAP+DAV, and if so, how can we do that practically? (Volker)<br />
* Progress of frameworkification, is KDAV ready to go, which framework is next after that? (Volker)<br />
<br />
=== KF6 ===<br />
* The use of KParts in kdepim (with some KF6 changes in mind) (David)<br />
* KF6/Qt6: anything problematic or anything larger to do in PIM or "our" frameworks? The Kross usage in accountwizard comes to mind. (Volker)<br />
<br />
=== Larger reviews ===<br />
* Review and finalize the API of Nicolas' platform calendar access abstraction. (Volker)<br />
* Review the KUserFeedback usage for 20.04 (Volker)<br />
<br />
=== Specific bugs ===<br />
* KOrganizer: bug can't modify item immediately after creating it (David)<br />
* Deleting multiple emails really fast leads to some of them being stuck in "about to be deleted" state (David)<br />
* Deleting emails while the inbox is sync'ed leads to emails reappearing before disappearing again (David)<br />
* Finding out why kmail often shows "This message is encrypted" erroneously (David)<br />
* Finding out why contact completion/search doesn't find some contacts (David)<br />
<br />
=Attendance=<br />
<br />
* Franck Arrecot<br />
* Laurent Montel<br />
* Kévin Ottens<br />
* David Faure<br />
* Dan Vratil<br />
* Andre Heinecke<br />
* Sandro Knauss<br />
* Volker Krause<br />
* Ingo Klöcker<br />
<br />
=Report=<br />
<br />
TODO<br />
<br />
=Previous Meeting=<br />
<br />
[[Sprints/PIM/2019 | PIM Sprint 2019, 5-7 April, Toulouse, France]]</div>Dfaurehttps://community.kde.org/index.php?title=Guidelines_and_HOWTOs/Debugging/Debugging_IOSlaves&diff=87921Guidelines and HOWTOs/Debugging/Debugging IOSlaves2020-04-02T11:47:02Z<p>Dfaure: mention ~/.local/share/sddm/xorg-session.log (*3)</p>
<hr />
<div>This page describes how you can debug a KIO ioslave.<br />
<br />
==How to Get Debug Output==<br />
<br />
=== GUI (Qt5/KF5 instructions) ===<br />
<br />
# Launch the <code>kdebugsettings</code> tool, either from terminal or from KRunner (the latter can be invoked with Alt + F2)<br />
# Type the name of the KIO Slave (e.g. ftp, http, ...). (If it's not listed, it doesn't use categorized debug output, so either its output is always on, or commented out in the code, in which case it needs to be ported to qCDebug)<br />
# From the drop-down menu next to each KIO Slave you're interested in, select '''Full Debug'''<br />
# Press '''OK''' to close the dialog and the save your changes<br />
# You can either run <code>kdeinit5</code> in terminal, in which case the output from any IO slave that's started afterwards will show up in that terminal OR<br />
# Alternatively log out then log back in, and additional debug info will typically end up in ~/.X.err, ~/.xsession-errors or ~/.local/share/sddm/xorg-session.log<br />
<br />
Notes:<br />
* If you have rebuilt an IO Slave from source with some changes you'll need ensure that <code>kdeinit5</code> will pick it up; this works with KIO from the KDE repos:<br />
{{Input|1=<nowiki><br />
cd <path to build dir>/bin<br />
export LD_LIBRARY_PATH=$PWD<br />
export QT_PLUGIN_PATH=$PWD<br />
kdeinit5</nowiki>}}<br />
** in the first <code>cd</code> command you change to the directory containing the compiled binaries, in KIO case it's ''<build dir>/bin''.<br />
<br />
* Instead of using <code>kdebugsettings</code>, you can change the Qt logging categories rules temporarily, in terminal:<br />
{{Input|1=<nowiki><br />
export QT_LOGGING_RULES="*kio*=true"<br />
</nowiki>}} <br />
** for more information see [https://doc.qt.io/qt-5/qloggingcategory.html this]. <br />
=== GUI (Qt4/kdelibs4 instructions) ===<br />
<br />
# Press ALT+F2.<br />
# Enter 'kdebugdialog --fullmode' without the quotes and press enter.<br />
# Select the desired number in the "Debug area", e.g. 7103 for http.<br />
# In the [Information] box, select "File" as the output.<br />
# Enter the desired file name, e.g. /tmp/kio_http.log.<br />
# Press OK to close the dialog.<br />
# Press ALT+F2, type ''kdeinit4'' and press enter or alternatively log out of KDE and log back in.<br />
<br />
This will print additional debug info to the stderr of your kdeinit process, which typically ends up in ~/.X.err, ~/.xsession-errors or ~/.local/share/sddm/xorg-session.log<br />
<br />
===Manual (Qt4/kdelibs4 instructions)===<br />
It is useful to redirect the debug output of your particular slave to a file <br />
instead of stderr. E.g. I myself use the following lines in<br />
$KDEDIR/share/config/kdebugrc.<br />
<pre><br />
[7113]<br />
InfoOutput=0<br />
InfoFilename=/tmp/http<br />
[7103]<br />
InfoOutput=0<br />
InfoFilename=/tmp/http <br />
</pre><br />
This redirects all debug info for areas 7103 and 7113 (as used by kio_http) <br />
to the file /tmp/http.<br />
<br />
To get debug information from the SMB slave you can add the following to<br />
kioslaverc:<br />
<pre><br />
[SMB]<br />
DebugLevel=100<br />
</pre><br />
This will print additional debug info to the stderr of your kdeinit process,<br />
which typically ends up in ~/.X.err, ~/.xsession-errors or ~/.local/share/sddm/xorg-session.log<br />
<br />
==How does an io-slave get started?==<br />
<br />
Your application requests 'klauncher' via DBus for a slave. If 'klauncher' does not have an idle slave ready, it will ask kdeinit to start a new one. kdeinit forks and dlopens the library that contains the io-slave.<br />
Then it calls a function called kdemain() in the library.<br />
<br />
==Attaching gdb to an io-slave==<br />
Due to the above sequence it is rather hard to get an io-slave in your<br />
debugger. But wait there is hope. You can start <tt>klauncher</tt> in such a way<br />
that slaves for a certain protocol (the first parameter of KIO::SlaveBase() constructor of the slave class) are started in debug mode.<br />
<br />
E.g. to start all 'http' slaves in debug mode, you type:<br />
<pre><br />
KDE_SLAVE_DEBUG_WAIT=http kdeinit5<br />
</pre><br />
<br />
This will restart 'kdeinit' and 'klauncher'.<br />
<br />
Note:<br />
The string after the equal signal designates the name of a service, not the name of the slave! E.g. if you want to debug the kio_imap4, you must use:<br />
<pre><br />
KDE_SLAVE_DEBUG_WAIT=imap kdeinit5<br />
</pre><br />
<br />
For example, these commands don't work:<br />
<pre><br />
KDE_SLAVE_DEBUG_WAIT=imap4 kdeinit5<br />
KDE_SLAVE_DEBUG_WAIT=143 kdeinit5<br />
</pre><br />
<br />
When your application now requests a http slave, the slave will be started<br />
by kdeinit, but before it calls kdemain() (cq. main()) it will suspend the<br />
slave by sending it a SIGSTOP signal.<br />
<br />
In the terminal from which you started kdeinit you will get the following<br />
message:<br />
<pre><br />
kdeinit: Suspending process<br />
kdeinit: 'gdb kdeinit 16779' to debug<br />
kdeinit: 'kill -SIGCONT 16779' to continue<br />
</pre><br />
<br />
You can now debug your slave by typing (or pasting) 'gdb kdeinit 16779' in<br />
a terminal. <br />
<br />
Note that modern linux kernels disable ptrace. If gdb says "ptrace: Operation not permitted." then you need this:<br />
<br />
<pre>echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope</pre><br />
<br />
If you don't want to debug a slave you can let it continue by<br />
sending it a SIGCONT by typing 'kill -SIGCONT 16779'.<br />
Be aware that slaves will not be killed while they are suspended.<br />
<br />
Once you have started gdb, you can set e.g. breakpoints and then resume the <br />
slave by typing 'continue'. The debugger will return immediate with a message <br />
that a SIGSTOP has been received so you will have to type 'continue' a second <br />
time.<br />
<br />
See also [[Development/Tutorials/Debugging/Debugging_on_MS_Windows#Debugging_kioslaves|Windows-specific notes on debugging io-slaves]].<br />
<br />
==Debugging io-slaves with valgrind==<br />
KLauncher can be told to run certain io-slaves through valgrind. The following<br />
command can be used to let klauncher run all https io-slaves via valgrind:<br />
<pre><br />
KDE_SLAVE_VALGRIND=https kdeinit5<br />
</pre><br />
<br />
The valgrind output will appear as the stderr output of the kdeinit process.<br />
The $VALGRIND_OPTS environment variable can be used to pass options to valgrind.<br />
If you want to use a different skin:<br />
<pre><br />
KDE_SLAVE_VALGRIND_SKIN=callgrind ( for example )<br />
</pre><br />
<br />
== specific kioslaves ==<br />
* [[Guidelines_and_HOWTOs/Debugging/Debugging IOSlaves/Debugging kio_fish|kio_fish]]<br />
* [[Guidelines_and_HOWTOs/Debugging/Debugging IOSlaves/Debugging kio_sftp|kio_sftp]]</div>Dfaurehttps://community.kde.org/index.php?title=Frameworks/CreationGuidelines&diff=86845Frameworks/CreationGuidelines2019-12-02T22:14:47Z<p>Dfaure: fix CI URL</p>
<hr />
<div>= Guidelines for creating a new framework =<br />
<br />
If you are creating a new framework, this checklist can help you get it done correctly:<br />
* Make sure it follows all the [[Frameworks/Policies|active policies]]<br />
* The above includes many important things, make sure to read all of it. E.g. it includes the often forgotten [[Frameworks/Frameworks_Localization_Policy#KI18n_installation_code|rule for installing translations]]<br />
* If it is created by splitting code from an existing repository, the new repository should be created by using a script to create a graft point<br />
* Run astyle-kdelibs or uncrustify-kf5 (both are part of kde-dev-scripts)<br />
* Ensure the module doesn't depend on deprecated or "portingAid" frameworks like kdelibs4support<br />
* Ensure the module is in frameworks on projects.kde.org (the source information is in the repo kde:sysadmin/repo-metadata), otherwise ask for it to be moved there (https://go.kde.org/systickets)<br />
* Adjust kde:kde-build-metadata - in particular, add it to the deps for frameworks/kf5umbrella<br />
* Get the CI jobs set up<br />
** Get the job set up on build.kde.org by filing a task towards https://phabricator.kde.org/tag/build.kde.org/<br />
** Make sure to request it to be added to the relevant view: https://build.kde.org/job/Frameworks/ <br />
** Ensure it is green<br />
* Add a new product for it on bugs.kde.org, which must be called frameworks-<name><br />
* Create a README.md file<br />
* Finally when it's all ready, change the yaml file to say release: true. The release scripts will then pick it up automatically for the next KF release.<br />
<br />
== Template ==<br />
<br />
The [http://quickgit.kde.org/?p=kdeexamples.git&a=tree&f=framework-template framework-template] directory in the kdeexamples repository has a setup.sh script that generates a helpful skeleton framework that is a good starting point for creating a framework. For example, if you were creating the KConfig framework, you might run<syntaxhighlight lang="bash"><br />
./setup.sh KConfig ../../kconfig <br />
</syntaxhighlight><br />
then go to the newly created "kconfig" directory and start adding source files etc.</div>Dfaurehttps://community.kde.org/index.php?title=Frameworks/Porting_Notes&diff=86170Frameworks/Porting Notes2019-09-10T13:45:35Z<p>Dfaure: Update KDialog</p>
<hr />
<div>This document contains the changes you have to apply to programs written for KDE 4.x when you want to port them to KDE Frameworks&nbsp;5.<br />
<br />
The other part of the porting documentation is the notes in the documentation for deprecated methods (especially in kdelibs4support), make sure to check that out as well.<br />
<br />
= Build System =<br />
<br />
A lot of CMake code that used to be provided by kdelibs is now provided by the <tt>extra-cmake-modules</tt> package. This can be obtained by doing<br />
<syntaxhighlight lang="cmake"><br />
find_package(ECM REQUIRED NO_MODULE)<br />
set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH})<br />
</syntaxhighlight><br />
and something approximating the settings provided with kdelibs 4 can be achieved by<br />
<syntaxhighlight lang="cmake"><br />
include(KDEInstallDirs)<br />
include(KDECompilerSettings NO_POLICY_SCOPE)<br />
include(KDECMakeSettings)<br />
include(FeatureSummary)<br />
</syntaxhighlight><br />
TechBase has a list of [[techbase:Development/CMake/IncompatibleChangesKDELibs4ToECM|source incompatible changes in ECM]].<br />
<br />
Other changes of significance include:<br />
* Add a feature_summary line to the end of the top level CMakeLists.txt. <br />
<syntaxhighlight lang="cmake"><br />
feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES)<br />
</syntaxhighlight><br />
* If you previously built with <tt>-DCMAKE_BUILD_TYPE=DebugFull</tt>, you should now use <tt> -DCMAKE_BUILD_TYPE=debug</tt>. Note that the old DebugFull build type passed <tt>-g3</tt> to the compiler (causing it to include macro expansions in the debugging information), while CMake's built-in debug build type just passes <tt>-g</tt>. You can use the [[http://www.cmake.org/cmake/help/v2.8.12/cmake.html#variable:CMAKE_LANG_FLAGS_DEBUG|CMAKE_CXX_FLAGS_DEBUG]] variable to reintroduce this flag if necessary (ie: add <tt>-DCMAKE_CXX_FLAGS_DEBUG:STRING=-g3</tt> and possibly <tt>-DCMAKE_C_FLAGS_DEBUG:STRING=-g3</tt> to your CMake command line).<br />
* The <tt>kde4_add_executable</tt> macro uses, should be changed into CMake's <tt>add_executable</tt> command.<br />
** The <tt>NOGUI</tt> tag in <tt>kde4_add_executable</tt> should be replaced by the <tt>ecm_mark_nongui_executable()</tt> macro in ECM<br />
** The TEST tag in kde4_add_executable should be replaced by the ecm_mark_as_test() macro in ECM<br />
*** To access the ecm_mark_as_test() macro, you must add:<br />
<syntaxhighlight lang="cmake"><br />
include(ECMAddTests)<br />
</syntaxhighlight><br />
* The kde4_add_plugin uses, should be changed for add_library(... MODULE ...). If WITH_PREFIX was being used, you'll have to tell CMake what prefix you want: set_target_properties(<targetname> PROPERTIES PREFIX "${CMAKE_SHARED_LIBRARY_PREFIX}")<br />
* KDE4_ADD_KDEINIT_EXECUTABLE should be turned into KF5_ADD_KDEINIT_EXECUTABLE, provided by KF5InitMacros.cmake.<br />
* include directories are automatically generated from specified target_link_library parameters, e.g., to include KTextEditor headers, add "KF5::TextEditor" to the target_link_libraries call.<br />
* kde4_add_unit_test(name sources) should be changed to add_executable(name sources) and add_test(lib-name name) and ecm_mark_as_test(name)<br />
<br />
<br />
== Installing Icons ==<br />
<br />
The command to install icons has seen major changes which are described in the [[techbase:Development/ECM_SourceIncompatChanges|source-incompatible changes]] page.<br />
<br />
= KDECore Changes =<br />
<br />
kdecore has been split up into a number of independent libraries: libkarchive, libkauth, libkdbus, etc.<br />
<br />
== General ==<br />
<br />
* KSaveFile has been deprecated in favour of the new QSaveFile:<br />
** <tt>backupFile ➙ KBackup::backupFile</tt><br />
** <tt>open() ➙ open(QIODevice::WriteOnly)</tt><br />
** <tt>finalize() ➙ commit()</tt><br />
** <tt>abort() ➙ cancelWriting()</tt><br />
** <tt>close()</tt> ➙ do not call close, call commit or cancelWriting directly<br />
** the return value from write() calls does not need to be checked anymore, commit will cancel in case of a write error<br />
** Use kde-dev-scripts/kf5/convert-ksavefile.pl to automate most of the conversion. <br />
* K_GLOBAL_STATIC: replace by adding #include <QGlobalStatic>, replace K_GLOBAL_STATIC with Q_GLOBAL_STATIC and move the declaration out of the instace() method. The constructor of a class used with [http://doc.qt.io/qt-5/qglobalstatic.html QGlobalStatic] must be public. This was not the case with K_GLOBAL_STATIC.<br />
* KStandardDirs: see these [[Frameworks/Porting Notes/KStandardDirs|specific]] porting notes.<br />
* KArchive::writeFile takes arguments in a different order from before, so that "user" and "group" are now optional, and so that const char* data, qint64 size could be replaced with a QByteArray.<br />
* KTemporaryFile is deprecated, port to QTemporaryFile instead, see KTemporaryFile API documentation for details. (Use kde-dev-scripts/kf5/convert-ktemporaryfile.pl to automate most of the conversion. )<br />
* KTempDir is deprecated, port to QTemporaryDir instead, see KTempDir API documentation for details. (Use kde-dev-scripts/kf5/convert-ktempdir.pl to automate most of the conversion. )<br />
* KToolInvocation::invokeHelp is now KHelpClient::invokeHelp, in the KConfigWidgets framework.<br />
* KToolInvocation::klauncher() has been removed. Use startKdeinit if you just want kdeinit/klauncher to be running. For setLaunchEnv(), generate klauncher_iface.h from the installed org.kde.KLauncher.xml.<br />
* KMD5 is deprecated, port to QCryptographicHash instead. (Use kde-dev-scripts/kf5/convert-kmd5.pl to automate most of the conversion.)<br />
* qtest_kde.h is deprecated. Port to &lt;QtTest&gt;, for core tests, or to &lt;QtTestWidgets&gt; for tests that use widgets, otherwise they'll crash in code that requires QApplication internally.<br />
* K_EXPORT_PLUGIN is deprecated. Either use Qt's [http://qt-project.org/doc/qt-5/plugins-howto.html native plugin system] for simple plugins, or the K_PLUGIN_FACTORY or the K_PLUGIN_FACTORY_WITH_JSON macro, defined in kpluginfactory.h. In both cases, remove the K_EXPORT_PLUGIN macro from your code. This case is indicated by the K_EXPORT_PLUGIN_is_deprecated_see_KDE5PORTING warning. More details about the plugin factory changes are explained in [http://vizzzion.org/blog/2013/08/kde-frameworks-5-plugin-factory-guts/ this blog post].<br />
* KAuthorized::authorizeUrlAction and KAuthorized::allowUrlAction have been moved to a new KUrlAuthorized namespace.<br />
* kde_file.h: KDE_struct_stat is now QT_STATBUF, KDE::lstat is now QT_LSTAT, include qplatformdefs.h instead of kde_file.h<br />
* KDebug is deprecated, use QDebug or QLogginCategory instead.<br />
** For non-categorized logging:<br />
*** <tt>kDebug() ➙ qDebug()</tt><br />
*** <tt>kError() ➙ qCritical()</tt><br />
*** <tt>kFatal() ➙ qFatal()</tt><br />
*** <tt>kWarning() ➙ qWarning()</tt><br />
*** Use kde-dev-scripts/kf5/convert-kdebug.pl to automate most of the conversion. <br />
** For categorized logging like kDebug(1221), see the [[Frameworks/Porting_To_qCDebug|kDebug -> qCDebug porting guide]]. (Use kde-dev-scripts/kf5/convert-kdebug-with-argument.sh to automate most of the conversion. )<br />
* *ui.rc files should now be installed in the ${KXMLGUI_INSTALL_DIR} directory<br />
<br />
== KComponentData ==<br />
* The class is in kde4support now. Port away from it. In your main(), just remove the instantiation, and instead use QCoreApplication::setApplicationName, QGuiApplication::setApplicationDisplayName, QGuiApplication::setWindowIcon. In plugins, see KPluginFactory/KPluginLoader.<br />
* dirs() has been removed. You can use kde4support's KGlobal::dirs, but better port to QStandardPaths. The only difference (for other KComponentData instances than the main one), is the "appdata" resource, which would now point to the application name rather than the component name. It's cleaner to use "data" anyway (or QStandardPaths::GenericDataLocation), and prepend the component name to the searched file.<br />
* The main componentData now needs to be created only once a QCoreApplication instance exists, otherwise the call to KAboutData::setApplicationData() during registration as MainComponent will not have any effect and leave application name unset, resulting e.g. in no display name and resources not found<br />
<br />
== KCmdLineArgs ==<br />
* Port to [http://doc.qt.io/qt-5/qcommandlineparser.html QCommandLineParser] instead.<br />
* A major difference is that KCmdLineArgs was set up before KApplication, while QCommandLineParser should be set up after creating the Q[Core]Application. This allows to use i18n() or tr() in the option definitions.<br />
* Use kde-dev-scripts/kf5/convert-kcmdlineargs.pl to automate most of the conversion.<br />
* KCmdLineArgs::addTempFileOption() becomes<br />
parser.addOption(QCommandLineOption(QStringList{"tempfile"}, i18n("The files/URLs opened by the application will be deleted after use")));<br />
* args.url(i) becomes QUrl::fromUserInput(args.at(i), QDir::currentPath()) (possibly with QUrl::AssumeLocalFile as 3rd argument if the application supports creating files, see documentation)<br />
<br />
== KAboutData ==<br />
* Make sure to call KAboutData::setApplicationData() from the main() of the application.<br />
* Make sure to create KAboutData instance only once the Q*Application instance has been created, if you are using KI18n's i18n() calls for translated strings. Only after the instance creation all locale settings are done as needed.<br />
* Make sure to call KAboutData::setApplicationData() only once the Q*Application instance has been created, otherwise the respective Q*Application metadata will not be set (e.g. QGuiApplication::applicationDisplayName), which other KF5 code now relies on.<br />
* KAboutData::setApplicationData() no longer sets the app window icon. For shells which do not fetch the icon name via the desktop file, make sure to call QApplication::setWindowIcon(QIcon::fromTheme(QStringLiteral("foo"))); (in GUI apps).<br />
* KAboutData::LicenseKey enums (e.g. KAboutData::License_LGPL) have all been moved to KAboutLicense in the KCoreAddons framework (KAboutLicense::LGPL, in this example).<br />
* KAboutData::catalogName and setCatalogName are gone, as is the constructor taking a catalogName. For KF5 software you want to use [http://api.kde.org/frameworks-api/frameworks5-apidocs/ki18n/html/classKLocalizedString.html#ad866b11bf396b9d93b7dc313a1930b7b KLocalizedString::setApplicationDomain] to set your translation catalog before constructing KAboutData. Alternately, there is still K4AboutData for temporary compatibility help while porting.<br />
* KCmdLineArgs uses K4AboutData rather than KAboutData: K4AboutData keeps the old mechanism for delayed translations (I18N_NOOP), while KAboutData is the one used by plugins, which can use an immediate translation (i18n).<br />
<br />
== URL ==<br />
<br />
KUrl has been deprecated in favour of QUrl. '''Warning:''' look at the KUrl documentation for proper porting. Do ''not'' just do a global search-and-replace. In particular:<br />
* KUrl(QString) means "absolute local file or absolute url" while QUrl(QString) means "relative url or absolute url", so for local files you have to use QUrl::fromLocalFile(QString), or if it could be local-or-remote, use QUrl::fromUserInput(QString). Note that the one-argument form of QUrl::fromUserInput assumes a web browser context. Qt 5.4 introduces [http://doc.qt.io/qt-5/qurl.html#fromUserInput-2 a 2- or 3-argument] form that is more appropriate for contexts such as command-line arguments. The closest equivalent to KUrl(QString) in Qt 5.4 is QUrl::fromUserInput(QString, QString(), QUrl::AssumeLocalFile). A version that always returns an absolute URL (as, e.g., KCmdLineArgs::url did) is QUrl::fromUserInput(QString, QDir::currentPath(), QUrl::AssumeLocalFile). (QUrl::AssumeLocalFile means that nonexistent files should not be assumed to be http:// URLs. This is required for output file names, and recommended for input file names in most contexts, because otherwise mistyped file names can result in DNS lookups, leaking user information.) If you don't want to depend on Qt 5.4 yet, use [http://lists.kde.org/?l=kde-core-devel&m=141359279227385&w=2 this code].<br />
* KUrl u; u.setPath("/tmp"); would make it file:///tmp, while QUrl u; u.setPath("/tmp"); is an incomplete URL, without a scheme. The correct way with QUrl is QUrl::fromLocalFile("/tmp").<br />
* KUrl::isParentOf means "parent or equal" while QUrl::isParentOf is strictly "parent" (see porting instructions in KUrl::isParentOf)<br />
* KUrl::upUrl is now the static method KIO::upUrl<br />
<br />
It is <b>very strongly</b> recommended to set -DQT_NO_URL_CAST_FROM_STRING so that the calls to QUrl(QString) are explicit.<br />
<br />
Many signals with a KUrl have been replaced with a QUrl (remember to update your connect statements and your slots!):<br />
* <tt>KUrlRequester: urlSelected(const KUrl&amp;) ➙ urlSelected(const QUrl&amp;)</tt><br />
* <tt>KRecentFilesAction: urlSelected(const KUrl&amp;) ➙ urlSelected(const QUrl&amp;)</tt><br />
* <tt>KUrlComboBox: urlActivated(const KUrl&amp;) ➙ urlActivated(const QUrl&amp;)</tt><br />
* <tt>KPropertiesDialog: saveAs(KUrl,KUrl) ➙ saveAs(QUrl,QUrl)</tt><br />
<br />
KUrl also provided the [http://api.kde.org/4.x-api/kdelibs-apidocs/kdecore/html/classKUrl_1_1List.html KUrl::List] class that was mainly a QList of KUrl objects with some static helper methods to deal with MIME data. It should now be a QList<QUrl>, and the following changes should be made<br />
* <tt>[http://api.kde.org/4.x-api/kdelibs-apidocs/kdecore/html/classKUrl_1_1List.html#a531573492dded54b74222d72af65f071 KUrl::List::canDecode]</tt> ➙ <tt>[http://qt-project.org/doc/qt-5/qmimedata.html#hasUrls QMimeData::hasUrls()]</tt><br />
* <tt>[http://api.kde.org/4.x-api/kdelibs-apidocs/kdecore/html/classKUrl_1_1List.html#a1f5ff2e67eace354f731f3f00aae3422 KUrl::List::fromMimeData]</tt> ➙ <tt>[http://qt-project.org/doc/qt-5/qmimedata.html#urls QMimeData::urls()]</tt><br />
<br />
Some commonly-used methods:<br />
* KUrl::prettyUrl ➙ QUrl::toDisplayString ('''warning:''' do '''not''' use plain toString(), because it includes the password by default, see also [http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-2074 CVE-2013-2074])<br />
* KUrl::pathOrUrl ➙ QUrl::url(QUrl::PreferLocalFile)<br />
* Porting hints for many other KUrl methods can be found in the API documentation for [http://api.kde.org/frameworks-api/frameworks5-apidocs/kdelibs4support/html/classKUrl.html KUrl in KDELibs4Support].<br />
<br />
== Mime Types ==<br />
<br />
KMimeType is deprecated, port to [http://doc.qt.io/qt-5/qmimetype.html QMimeType] instead. <tt>kde-dev-scripts/kf5/convert-kmimetype.pl</tt> implements most of the following porting guide:<br />
<br />
* <tt>[http://doc.qt.io/qt-5/qmimedatabase.html QMimeDatabase] db;</tt>, all the methods need a db instance, but it's very cheap to create, on stack is fine.<br />
* <tt>KMimeType::Ptr mime</tt> ➙ <tt>QMimeType mime</tt><br />
* <tt>if (mime)</tt> ➙ <tt>if (mime.isValid())</tt><br />
* <tt>KMimeType::mimeType(name)</tt> ➙ <tt>db.mimeTypeForName(name)</tt><br />
* <tt>KMimeType::mimeType(name, DontResolveAlias)</tt> ➙ <tt>db.mimeTypeForName(name)</tt>, there is no separate mime object for the alias<br />
* <tt>KMimeType::findByUrl(url)</tt> ➙ <tt>db.mimeTypeForUrl(url)</tt><br />
* <tt>KMimeType::findByUrl(url, 0, is_local, true)</tt> ➙ <tt>db.mimeTypeForFile(url.path(), QMimeDatabase::MatchExtension)</tt><br />
* <tt>KMimeType::findByPath(path)</tt> ➙ <tt>db.mimeTypeForFile(path)</tt><br />
* <tt>KMimeType::findByPath(path, 0, true)</tt> ➙ <tt>db.mimeTypeForFile(path, QMimeDatabase::MatchExtension)</tt> (this is slightly different in case of conflicting globs though, <tt>findByPath</tt> used to return empty, so that delayed mimetype determination could then refine this; <tt>mimeTypesForFileName</tt> can be useful to detect this case. But for most applications this detail doesn't matter).<br />
* <tt>KMimeType::findByContent(data)</tt> ➙ <tt>db.mimeTypeForData(data)</tt><br />
* <tt>KMimeType::findByNameAndContent(fileName, data_or_device)</tt> ➙ <tt>db.mimeTypeForFileNameAndData(fileName, data_or_device)</tt><br />
* <tt>KMimeType::findByFileContent(path)</tt> ➙ <tt>db.mimeTypeForFile(path, QMimeDatabase::MatchContent)</tt><br />
* <tt>mime-&gt;name() == KMimeType::defaultMimeType()</tt> ➙ <tt>mime.isDefault()</tt><br />
* <tt>mime.allParentMimeTypes()</tt> ➙ <tt>mime.allAncestors()</tt><br />
* <tt>KMimeType::extractKnownExtension(fileName)</tt> ➙ <tt>db.suffixForFileName(fileName)</tt><br />
* <tt>KMimeType::iconNameForUrl(url)</tt> has additional logic on top of <tt>db.mimeTypeForUrl(url).iconName()</tt>, to fallback to the protocol-specific icon (e.g. trash icon for trash:/, etc.). This logic has now moved to <tt>KIO::iconNameForUrl</tt>(from kio/global.h).<br />
* <tt>KMimeType::patterns()</tt> ➙ <tt>QMimeType::globPatterns()</tt><br />
* <tt>KMimeType::allMimeTypes()</tt> ➙ <tt>db.allMimeTypes()</tt><br />
* <tt>KMimeType::comment</tt> and <tt>KMimeType::iconName</tt> no longer take a <tt>KUrl</tt> argument. If you were passing such an argument (to support <tt>.directory</tt> files in directories), port the code to <tt>KFileItem::mimeComment</tt> and <tt>KFileItem::iconName</tt>.<br />
<br />
The following fake MIME types have been removed and should be replaced as follows:<br />
* all/allfiles ➙ application/octet-stream<br />
* all/all ➙ application/octet-stream+inode/directory<br />
* uri/{mms,mmst,mmsu,pnm,rtspt,rtsptu} ➙ x-scheme-handler/...<br />
<br />
== Config ==<br />
<br />
* KConfig and KDesktopFile have been ported to QStandardPaths. This changes the "const char* resourceType" in the API into QStandardPaths::StandardLocation, and means that modifying the "config" resource before using KConfig has no effect on KConfig anymore.<br />
* KConfigBase::sync now returns a bool<br />
* KCoreConfigSkeleton::writeConfig now returns a bool<br />
* KCoreConfigSkeleton::usrWriteConfig now returns a bool<br />
* <tt>kde4_add_kcfg_files</tt>, used in the build system to generate code from KConfigXT files, should be changed to <tt>kconfig_add_kcfg_files</tt>.<br />
* If you want the config files placed in the correct location instead of being mixed up with other stuff, make sure you have QCoreApplication::setOrganizationDomainName() call that sets the correct name for your application.<br />
<br />
== Encoding ==<br />
<br />
KEncodingDetector is removed, port to KEncodingProber. <br />
<br />
Porting guide:<br />
<pre><br />
KEncodingDetector detector -&gt; KEncodingProber prober<br />
enum KEncodingDetector::AutoDetectScript -&gt; enum KEncodingProber::ProberType<br />
detector.encoding() -&gt; prober.encoding()<br />
detector.visuallyOrdered() -&gt; check prober.encoding() hebrew<br />
detector.autoDetectLanguage() -&gt; prober.proberType()<br />
detector.setAutoDetectLanguage(script) -&gt; prober.setProberType(proberType)<br />
detector.decode(data) -&gt; prober.feed(data) + QTextCodec::codecForName(prober.encoding())-&gt;toUnicode(data)<br />
detector.decodeWithBuffering(data, len) -&gt; prober.feed(data1), feed(data2), feed(data3) + check prober.state() + QTextCodec::codecForName(prober.encoding())-&gt;makeDecoder()<br />
detector.decodedInvalidCharacters() -&gt; QTextCodec::codecForName(prober.encoding())-&gt;makeDecoder() + hasFailure()<br />
detector.resetDecoder() -&gt; prober.reset()<br />
detector.flush() -&gt; prober.feed(data1), feed(data2), feed(data3) + QTextCodec::codecForName(prober.encoding())-&gt;toUnicode<br />
KEncodingDetector::scriptForName(lang) -&gt; KEncodingProber::proberTypeForName(lang)<br />
KEncodingDetector::nameForScript(script) -&gt; KEncodingProber::nameForProberType(proberType)<br />
KEncodingDetector::hasAutoDetectionForScript(script) -&gt; if (proberType == KEncodingProber::None) ... else ... KEncodingProber::encodingName() is removed, use KEncodingProber::encoding() instead.<br />
</pre><br />
<br />
The following functions have been moved into khtml with the original KEncodingDetector class. khtml is the only user of them.<br />
<pre><br />
enum KEncodingDetector::EncodingChoiceSource -&gt; removed<br />
KEncodingDetector::setEncoding(encoding, choice) -&gt; removed, implement it in khtml code<br />
KEncodingDetector::encodingChoiceSource() -&gt; removed<br />
</pre><br />
<br />
== Localization ==<br />
<br />
KLocale has been deprecated and moved to kde4support, with its features split between QLocale and KLocalizedString:<br />
<br />
* For translation support, use KLocalizedString (ki18n framework). <br />
* For string formatting, use [http://qt-project.org/doc/qt-5/qlocale.html QLocale], or KFormat from the KCoreAddons framework when QLocale does not provide the formatting you need.<br />
* For localized string comparison, KStringHandler::naturalCompare() is deprecated in kdelibs4support, use QCollator instead.<br />
<br />
The formating/parsing functions of KLocale have been replaced by QLocale:<br />
<br />
* Replace all uses of "KGlobal::locale()" with "QLocale()", e.g.:<br />
<syntaxhighlight lang="cpp-qt"><br />
// KDE4<br />
QString string = KGlobal::locale().formatDate(myDate);<br />
// KF5<br />
QString string = QLocale().toString(myDate);<br />
</syntaxhighlight><br />
* Replace all uses of KGlobal::setLocale() with QLocale::setDefault(myLocale)<br />
* QLocale does not allow changing of default formats, i.e. with KLocale you could call "KGlobal::locale()->setDateFormat("%y-%M-%d")" to change the applications default date format, you cannot do this with QLocale. You must use the standard QLocale custom formatters each time, e.g. "QLocale().toString("yyyy-MM-dd)", or set a new application default QLocale using "QLocale::setDefault()".<br />
* QLocale formatter/parser methods are named as toString()/toDate() pairs rather than formatDate()/readDate() pairs as in KLocale, and take different enum or format strings. See the [http://qt-project.org/doc/qt-5/qlocale.html QLocale docs] for full details.<br />
* QLocale date and time formatting does not use the POSIX format codes like "%y-%M-%d", you need to use the Qt format codes like "yyyy-MM-dd" instead.<br />
* QLocale does not have an option for formatByteSize(), FancyDate, formatDuration(), or prettyFormatDuration(), use [http://api.kde.org/frameworks-api/frameworks5-apidocs/kcoreaddons/html/classKFormat.html KCoreAddons::KFormat] instead.<br />
* <tt>int KLocale::pageSize()</tt> ➙ <tt>QPageSize QPrinterInfo::defaultPageSize()</tt> (since Qt 5.3) - Note this gives you the default paper size for any installed printer, but may not work if there is no printer installed. It is preferable to check the QLocale().measurementSystem(), if it is QLocale::ImperialUSSystem then use QPageSize::Letter, otherwise use QPage::SizeA4.<br />
<br />
== Translations ==<br />
<br />
Translations are now entirely handled in the Ki18n library, primarily the [http://api.kde.org/frameworks-api/frameworks5-apidocs/ki18n/html/classKLocalizedString.html KLocalizedString] class. <br />
<br />
* Translation catalogs are no longer dynamically inserted, so the idiom <tt>KGlobal::locale()-&gt;insertCatalog("somecatalog")</tt> is no longer available. To simply make the code build, for the sake of porting other things first, just remove or comment out these calls. This will stop translations from working, and to fully port them eventually, follow the section [http://api.kde.org/frameworks-api/frameworks5-apidocs/ki18n/html/prg_guide.html#link_cat "Connecting Calls to Catalogs"] in ki18n programmer's guide.<br />
* i18n*() functions no longer handle KUIT markup. If you use KUIT markup, use the new xi18n*() functions.<br />
<br />
== Date / Time ==<br />
<br />
KDateTime, KCalendarSystem, KLocalizedDate, KTimeZone and other related classes have been deprecated and moved to kde4support. Use [http://doc.qt.io/qt-5/qdatetime.html QDateTime] and [http://doc.qt.io/qt-5/qtimezone.html QTimeZone] instead. KCalendarSystem has yet to be replaced by QCalendarSystem (planned for Qt 5.7?), the few places that require this must use kde4support or wait for QCalendarSystem.<br />
<br />
Replace all instances of KDateTime with QDateTime. The KDateTime api was deliberately very similar to QDateTime, so most method names will be unchanged, but the enums they take, and the constructors, are different:<br />
* The KDateTime::Spec class should be removed and the KDateTime::SpecType replaced with Qt::TimeSpec. This may need some careful investigation, but most users of KDateTime do not use this feature.<br />
** KDateTime::ClockTime has no direct Qt::TimeSpec equivalent, but Qt:LocalTime is effectively the same<br />
** KDateTime::LocalZone has no direct Qt::TimeSpec equivalent, instead just use Qt::TimeZone with the QTimeZone::systemTimeZone().<br />
** KDateTime::Invalid has no Qt::TimeSpec equivalent.<br />
* The KDateTime::TimeFormat enum is replaced with Qt::DateFormat<br />
** KDateTime::RFCDate and KDateTime::RFCDateDay are replaced by Qt::RFC2822Date, fromString() will accept with or without the day name, toString() does not write the day name so will need to be manually added.<br />
** KDateTime::ISODate supported "simplified" and other variant ISO dates like YYYYMMDD, that Qt does not.<br />
** KDateTime::RFC3339Date is replaced by Qt:ISODate.<br />
** KDateTime::QtTextDate is replaced by Qt::TextDate, but should never be used.<br />
** KDateTime::LocalDate is replaced by Qt::LocalDate, but is deprecated and should never be used. Use QLocale methods instead.<br />
* The date/time string formats are changed from the POSIX standard (such as "%y %M %d") to the Qt standard which is a hybrid of CLDR and Windows (e.g. "yyyy MM dd").<br />
* Replace all calls to the KDateTime or QDateTime toString()/fromString() using the format strings to use the QLocale equivalents instead to ensure that the local calendar system is used.<br />
<br />
<br />
Method changes:<br />
* utcOffset() => offsetFromUtc()<br />
* isClockTime() => (qdt.timeSpec() == Qt::LocalTime)<br />
* isLocalZone() => (qdt.timeSpec() == Qt::LocalTime) or (qdt.timeZone() == QTimeZone::systemTimeZone())<br />
* isOffsetFromUtc() => (qdt.timeSpec() == Qt::OffsetFromUTC)<br />
* isUtc() => (qdt.timeSpec() == Qt::UTC)<br />
* int secsTo(KDateTime) => QDateTime returns qint64 instead of int<br />
* qint64 secsTo_long(KDateTime) => Use secsTo() instead<br />
* setTime_t(qint64) => QDateTime version takes a uint, perhaps use setMSecsSinceEpoch() if it matters<br />
* toClockTime() => toLocalTime()<br />
* toLocalZone() => toLocalTime() or toTimeZone(QTimeZone::systemTimeZone())<br />
* toOffsetFromUtc() => qdt.toOffsetFromUtc(qdt.offsetFromUtc())<br />
* toUtc() => toUTC()<br />
* toZone() => toTimeZone()<br />
* KDateTime::currentLocalDateTime() => QDateTime::currentDateTime()<br />
* KDateTime::currentUtcDateTime() => QDateTime::currentDateTimeUtc()<br />
<br />
<br />
Unsupported methods / features<br />
* KDateTime::dateTime() and KDateTime::setDateTime() - No longer required, use the QDateTime instance directly.<br />
* KDateTime::Comparison and KDateTime::compare() - QDateTime does not have an equivalent.<br />
* KDateTime::isDateOnly() and KDateTime::setDateOnly() - QDateTime does not have a "Date Only" mode, use QDate instead, or a QDateTime with a time of 00:00:00 instead.<br />
* KDateTime::isSecondOccurrence() and KDateTime::setSecondOccurrence() - QDateTIme does not as yet have proper second occurrence support.<br />
* KDateTime::detach() is no longer required, QDateTime manages this itself.<br />
* KDateTime::setSimulatedSystemTime and KDateTime::setFromStringDefault() - QDateTime does not a time simulation testing facility.<br />
<br />
= KDEUI Changes =<br />
<br />
== Application ==<br />
<br />
KApplication and KUniqueApplication are replaced with QApplication<br />
<br />
Make sure to:<br />
* Call void KAboutData::setApplicationData(const KAboutData &aboutData)<br />
<br />
or separately:<br />
* Call QCoreApplication::setApplicationName("...")<br />
* Call QCoreApplication::setApplicationVersion("...") (from the old KAboutData object)<br />
* Call QCoreApplication::setOrganizationDomain("kde.org")<br />
* Call QGuiApplication::setApplicationDisplayName(i18n("...")) for GUI programs<br />
* Call QGuiApplication::setDesktopFileName("...") for GUI programs<br />
<br />
Make sure that the desktop file name set directly or via KAboutData matches the desktop file name (without file extension) installed for the program. This property is used by shells like Plasma to access more metadata about a running program which is stored in its desktop file.<br />
<br />
* Call QGuiApplication::setWindowIcon(QIcon::fromTheme("...")) for GUI programs (needed by shells not using desktop file to retrieve app metadata)<br />
* Use KDBusService for DBus registration, and optional "unique" behavior. Use also the "NoExitOnFailure" flag, unless unsuited.<br />
* Important: if you create a QApplication (instead of KApplication) after using KCmdLineArgs, do not pass argc and argv to it, but KCmdLineArgs::qtArgc() and KCmdLineArgs::qtArgv(). This can go away when porting away from KCmdLineArgs.<br />
<br />
Also adapt in the .desktop file of the program the "Exec=" entry:<br />
* replace "-caption" with "-qwindowtitle" (supported by QGuiApplication)<br />
* remove "%i" (not supported by any Q*Application)<br />
<br />
If your program should work as a D-Bus activatable service, the base name of the D-Bus service description file or of the desktop file you install must match the D-Bus "well-known name" for which the program will register. For example, KDBusService will use a name created from the reversed organization domain with the component name attached, so for an organization domain "bar.org" and a component name "foo" the name of an installed D-Bus service file needs to be "org.bar.foo.service" or the name of the installed desktop file "org.bar.foo.desktop".<br />
<br />
For still supporting the deprecated start of services via KToolInvocation, the desktop file needs to have an entry with the key "X-DBUS-ServiceName" and a value which matches the used D-Bus "well-known name" as just described, so with the above used values it needs a line "X-DBUS-ServiceName=org.bar.foo"<br />
<br />
If you adopt the desktop file name for being D-Bus activatable, make sure to also update the value set for the desktopFileName application data property (see above). With the given example, it would accordingly be set to "org.bar.foo".<br />
<br />
For standard purposes, it is recommended to use a desktop file name which uses an organization domain. So if without one yet and unless the desktop file name is bound to its current name (e.g. by respective D-Bus well-known name being in use), consider renaming it (and then adapting all related data). The appdata file should have the same name for consistency.<br />
<br />
== General ==<br />
<br />
* KColorDialog: Use QColorDialog instead.<br />
* KLineEdit: Two choices:<br />
** Use QLineEdit instead, setClickMessage(...) becomes setPlaceholderText(...), setClearButtonShown(...) becomes setClearButtonEnabled(...). showClearButton property becomes clearButtonEnabled. clearButtonClicked() signal isn't available, connect to textChanged(const QString & text) and check if text.isEmpty(). (Use kde-dev-scripts/kf5/convert-klineedit.pl to automate most of the conversion. )<br />
** Use KLineEdit from the [http://api.kde.org/frameworks-api/frameworks5-apidocs/kcompletion/html/index.html kcompletion framework].<br />
* KIntValidator: Use QIntValidator instead, the only difference was that KIntValidator attempted to support non-decimal bases (but it was broken with prefix and suffix texts, and therefore unused in KDE SC)<br />
* KIntSpinBox: Use QSpinBox instead (Make sure to set minimum/maximum as needed! The defaults are 0-99). If using KIntSpinBox::setSuffix() with ki18n use KPluralHandlingSpinBox.<br />
* KDoubleValidator: Use QDoubleValidator instead (as part of KLocale -&gt; QLocale)<br />
* KFloatValidator: Use QDoubleValidator instead (drop-in replacement)<br />
* KSvgRenderer: Use QSvgRenderer instead (drop-in replacement)<br />
* KCursor: Use QCursor instead<br />
* KToolBar::applySettings and KMainWindow::applyMainWindowSettings don't take a "bool force" as second argument anymore (it was unused since KDE3 anyway)<br />
* the virtual method KMainWindow::queryExit doesn't exist anymore. Either use queryClose/closeEvent for things that should be done for every window (or simply if there's only ever one window), or connect to QCoreApplication::aboutToQuit for things that should only be done once on shutdown.<br />
* KIdentityProxyModel: Removed, used QIdentityProxyModel instead (trivial search/replace)<br />
* Other proxy models: Moved to the KItemModels framework<br />
* KPassivePopup: standardView() now returns a QWidget* instead of a KVBox*. The QWidget has a QVBoxLayout, i.e., additional widgets can be appended by calling widget-&gt;layout()-&gt;addWidget().<br />
* KCodecAction: use enum KEncodingProber::ProberType instead of enum KEncodingDetector::AutoDetectScript<br />
* KXMessages: the "obsolete = false" argument has been removed from all methods, and int screen has a default value of -1 now. Remove the "-1, false" in all calls. The sendMessage and sendMessageX methods were apparently unused, and have been commented out. Email kde-frameworks-devel at kde.org if you need them back.<br />
* KNotification: setComponentData(KComponentData) is now setComponentName(QString), only the component name was used.<br />
* KUndoStack: Use QUndoStack with KUndoActions::createUndoAction() and KUndoActions::createRedoAction() instead<br />
* KRichTextWidget: createActions() does not take any KActionCollection and returns a list of QAction instead. You could use KActionCollection.addActions(KRichTextWidget.createActions()) instead.<br />
* KTextBrowser: Use QTextBrowser instead. The only difference is QTextBrowser does not support "whatsthis:" urls. (Use kde-dev-scripts/kf5/convert-ktextbrowser.pl to automate most of the conversion. )<br />
* KTextEditInterface: This was a hack to preserve the ABI. Please use the methods in KTextEdit instead.<br />
* KTimeZoneWidget: Was copied as K4TimeZoneWidget in KDE4Support framework. A new KTimeZoneWidget replacement might appear so we freed the name.<br />
* KIcon: has been deprecated and moved to kde4support, prefer [http://doc.qt.io/qt-5/qicon.html QIcon]. Port KIcon("foo") to [http://doc.qt.io/qt-5/qicon.html#fromTheme QIcon::fromTheme("foo")] and KIcon("foo", iconLoaderPtr) to QIcon(new KIconEngine("foo", iconLoaderPtr)) using [http://api.kde.org/frameworks-api/frameworks5-apidocs/kiconthemes/html/index.html KIconEngine from the KIconThemes framework]. '''Note:''' XDG_DATA_DIRS has to be set to allow icons to be found. (Use kde-dev-scripts/kf5/convert-kicon.pl to automate most of the conversion. )<br />
* KPixmapSequence now can only be instanced with a fullPath, to use XDG icons use KIconLoader::loadPixmapSequence.<br />
* KLed: Several protected virtual methods to override painting got removed. If you need custom painting, override paintEvent() instead.<br />
* Use [http://qt-project.org/doc/qt-5/qkeysequence.html QKeySequence] instead of KShortcut to set shortcuts in actions.<br />
* KInputDialog: use QInputDialog instead, with a relevant difference the returned value: QInputDialog allows empty input and it is not possible to define a validator. Ensure that the returned value is checked if an empty value is not acceptable.<br />
<br />
== Global Settings ==<br />
<br />
* KGlobalSettings::contextMenuKey is gone, reimplement QWidget::contextMenuEvent() instead.<br />
* KGlobalSettings::*Font methods are deprecated. Use [http://doc.qt.io/qt-5/qfontdatabase.html QFontDatabase:]:systemFont(...). ::menuFont, ::taskBarFont and ::toolBarFont are not available now (they are provided by the QPA but not public API). If cases needing those arise we'll have to find an alternative<br />
* KGlobalSettings::naturalCompare is deprecated, you'll have to specifically read the settings:<br />
<pre><br />
KConfigGroup g( KSharedConfig::openConfig(), "KDE" );<br />
m_naturalSorting = g.readEntry("NaturalSorting", true);<br />
</pre><br />
<br />
== Message Box ==<br />
<br />
[http://api.kde.org/frameworks-api/frameworks5-apidocs/kwidgetsaddons/html/namespaceKMessageBox.html KMessageBox] is no longer a class, but a namespace, as it only had static methods. The KMessageBox namespace spans now in two frameworks:<br />
* Queued methods are deprecated and moved to kdelibs4support as kmessagebox_queued.h<br />
* All other methods are in kwidgetsaddons as kmessagebox.h<br />
<br />
Other changes:<br />
* setDontShowAskAgainConfig was renamed to setDontShowAgainConfig<br />
* KMessageBox methods now return enums instead of ints. While code using int will continue to build, you are encouraged to switch to enums for better type safety.<br />
* KMessageBoxMessageHandler is deprecated and moved to kdelibs4support<br />
<br />
== Action ==<br />
* KActionCollection and KXMLGUIClient: replace setComponentData with setComponentName and setComponentDisplayName<br />
* KAction is deprecated now, use QAction or QWidgetAction. (Use kde-dev-scripts/kf5/convert-kaction.pl to automate most of the conversion. )<br />
** Shape and rocker gestures are now handled by KGestureMap. The existing KAction methods related to gesture handling delegate to KGestureMap.<br />
* KAction global shortcut handling logic moved to KGlobalAccel. So the KAction::globalShortcutChanged signal was removed and a new corresponding KGlobalAccel::globalShortcutChanged has been added. The signal semantics have not changed.<br />
<br />
== Gesture ==<br />
<br />
* KGestureMap changes:<br />
** '''addGesture''' renamed to '''setShapeGesture''' and '''setRockerGesture''' and now allow replacing existing gestures. When this occurs, a warning is traced with qDebug.<br />
** new '''setDefault[Shape|Rocker]Gesture''' methods allow defining default gestures for an action, providing the functionality removed from KAction.<br />
** new '''shapeGesture''' and '''defaultShapeGesture''' methods retrieves already defined shape gestures for a given action<br />
** new '''rockerGesture''' and '''defaultRockerGesture''' methods retrieves already defined rocker gestures for a given action<br />
<br />
== Event Filter ==<br />
<br />
* KSystemEventFilter was removed as Qt 5 uses XCB instead of XLib. To get the same functionality derive from QAbstractNativeEventFilter, filter XCB events and register the filter in the QCoreApplication: <br />
<syntaxhighlight lang="cpp-qt"><br />
class MyXcbEventFilter : public QAbstractNativeEventFilter<br />
{<br />
public:<br />
MyXcbEventFilter()<br />
{<br />
QCoreApplication::instance()->installNativeEventFilter(this);<br />
}<br />
virtual bool nativeEventFilter(const QByteArray &eventType, void *message, long int*) Q_DECL_OVERRIDE<br />
{<br />
if (eventType != "xcb_generic_event_t") {<br />
// only interested in XCB events<br />
return false;<br />
}<br />
auto *event = static_cast<xcb_generic_event_t*>(message);<br />
switch (event->response_type & 0x80) {<br />
case XCB_KEY_PRESS:<br />
auto *keyEvent = reinterpret_cast<xcb_key_press_event_t*>(event);<br />
// handle key press event...<br />
return true;<br />
case XCB_KEY_RELEASE:<br />
// ...<br />
}<br />
return false;<br />
}<br />
};<br />
</syntaxhighlight><br />
<br />
== Dialog ==<br />
<br />
* KDialog: It has been deprecated and moved to kde4support. Port to QDialog + QDialogButtonBox. The script in kde-dev-scripts/kf5/convert-kdialog.pl can help.<br />
<br />
== KCharSelect ==<br />
<br />
* KCharSelect: To allow the user to select characters outside the Unicode BMP, you must <tt>setAllPlanesEnabled(true)</tt> and port to the uint-based methods and signals (available since version 5.25):<br />
** <tt>QChar currentChar()</tt> ➙ <tt>uint currentCodePoint()</tt><br />
** <tt>setCurrentChar(QChar)</tt> ➙ <tt>setCurrentCodePoint(uint)</tt><br />
** <tt>charSelected(QChar)</tt> ➙ <tt>codePointSelected(uint)</tt><br />
** <tt>currentCharChanged(QChar)</tt> ➙ <tt>currentCodePointChanged(uint)</tt><br />
To convert between uint code points and QString, use <tt>QString::fromUcs4()</tt> and <tt>QString::toUcs4()</tt>:<br />
<syntaxhighlight lang="cpp-qt"><br />
...<br />
Q_SLOTS:<br />
void codePointSelected(uint code) {<br />
QString selected = QString::fromUcs4(&code, 1);<br />
...<br />
}<br />
...<br />
</syntaxhighlight><br />
You can also manually do the surrogate pair handling.<br />
<br />
== Style ==<br />
In styles based on KStyle, this will work out of the box.<br />
* KStyle: Was copied as K4Style in KDE4Support framework. New KStyle class has been trimmed down and reimplements only necessary methods to enforce some of the user settings (for example icons). K4Style users should use K_EXPORT_K4STYLE instead of K_EXPORT_STYLE<br />
<br />
== Toolbar ==<br />
* ToolBar has moved to XMLGUI. If you don't want to depend on XMLGUI, use QToolBar instead, with the following setup:<br />
** Set ToolButtonStyle to Qt::ToolButtonFollowStyle, this will make QToolBar use the settings for "Main Toolbar"<br />
** Additionally set QToolBar::setProperty("otherToolbar", true) to use settings for "Other toolbars"<br />
** Settings from "Other toolbars" will only work on a widget style that derives from KStyle<br />
<syntaxhighlight lang="cpp-qt">QToolBar *toolbar = new QToolBar();<br />
toolbar->setToolButtonStyle(Qt::ToolButtonFollowStyle);<br />
toolbar->setProperty("otherToolbar", true);<br />
</syntaxhighlight><br />
<br />
== Font Dialog ==<br />
<br />
* Use QFontDialog instead of KFontDialog. Notice that, in the case of KFontDialog::getFont vs QFontDialog::getFont, QFontDialog::getFont returns the selected font instead of the dialog code, and the Accept/Cancel value is returned through a pointer to a boolean value that is passed as the first argument. Also, notice that the flags for KFontDialog::getFont (defined at [http://api.kde.org/4.x-api/kdelibs-apidocs/kdeui/html/classKFontChooser.html#a5f8cecef70d1a0b820592c17db7dafb7 KFontChooser::DisplayFlag]) do not map to those of QFontDialog::getFont (defined at [http://qt-project.org/doc/qt-5/qfontdialog.html#FontDialogOption-enum QFontDialog:: FontDialogOptions]) and serve a different purpose.<br />
<br />
* It should be noted that QFontDialog does not support the deactivation of the style list. If necessary, KFontChooser is a better alternative.<br />
<br />
== Window Systems ==<br />
<br />
KWindowSystem changes:<br />
* NETWinInfo2 class got removed. All methods are merged into NETWinInfo. Use NETWinInfo instead of NETWinInfo2.<br />
* NETRootInfo and NETWinInfo use xcb datatypes instead of XLib datatypes. Inheriting classes need to adjust the method arguments.<br />
* Constructor of NETRootInfo and NETWinInfo expect an xcb_connection_t* instead of Display*.<br />
* Constructor of NETRootInfo and NETWinInfo no longer take an array for properties, but dedicated flag types.<br />
* Method NETRootInfo::screenNumber has been removed.<br />
* NETRootInfo, NETWinInfo, KWindoInfo and KWindowSystem adjusted to use flag types instead of unsigned long int for the flags. This includes virtual method NETWinInfo::changeState.<br />
* NETWinInfo::event(xcb_generic_event_t*) returns NET::Properties<br />
* NETWinInfo::passedProperties returns NET::Properties and a new NETWinInfo::passedProperties2 is added which returns the NET::Properties2<br />
* NETRootInfo::event(xcb_generic_event_t*) returns NET::Properties<br />
* NETRootInfo::passedProperties returns NET::Properties and new methods for Properties2, WindowTypes, States and Actions are added<br />
* NETRootInfo::supportedProperties returns NET::Properties and new methods for Properties2, WindowTypes, States and Actions are added.<br />
* Desktop argument in NETRootInfo::desktopGeometry() and NETRootInfo::setDesktopGeometry() has been removed.<br />
<br />
== Printing ==<br />
<br />
KDE's print support which added extra features to the Qt print dialog has been deprecated and moved to kdelibs4support. All the extra features have been added to Qt.<br />
<br />
* For Qt printing support you will need to link to Qt5::PrintSupport.<br />
* KPrintPreview is replaced by QPrintPreview<br />
* KdePrint::createPrintDialog() is replaced by QPrintDialog<br />
<br />
Examples:<br />
<syntaxhighlight lang="cpp-qt"><br />
// KDE4 style<br />
QPrintDialog *printDialog = KdePrint::createPrintDialog(&printer, parent);<br />
// KF5 style<br />
QPrintDialog *printDialog = new QPrintDialog(&printer, 0);<br />
<br />
// KDE4 style, adding custom widgets<br />
QPrintDialog *printDialog = KdePrint::createPrintDialog(&printer, customWidgetList, parent);<br />
// KF5 style, adding custom widgets<br />
QPrintDialog *printDialog = new QPrintDialog(&printer, 0);<br />
printDialog->setOptionTabs(customWidgetList);<br />
<br />
// KDE4 style, setting server-side page selection<br />
QPrintDialog *printDialog = KdePrint::createPrintDialog(&printer, KdePrint::SystemSelectsPages, parent);<br />
// KF5 style, tell Qt you don't do client-side page selection, it will do server-side if supported<br />
QPrintDialog *printDialog = new QPrintDialog(&printer, 0);<br />
printDialog->setOption(QPrintDialog::PrintPageRange, false);<br />
</syntaxhighlight><br />
<br />
= KIO Changes =<br />
<br />
* The very common job-&gt;ui()-&gt;setWindow(widget) has to be ported to KJobWidgets::setWindow(job, widget), because job-&gt;ui() is now only a KJobUiDelegate.<br />
* The deprecated KIO::Job::showErrorDialog() has been removed, use KJobWidgets::setWindow(job, parent) and job-&gt;ui()-&gt;showErrorMessage()<br />
* The KFileItem API has been ported to QMimeType. As a consequence, mimeTypePtr() is now currentMimeType().<br />
* KFileItem::run(QWidget*) has disappeared, due to core/gui separation. Use new KRun(item.targetUrl(), widget) instead.<br />
* KFileItem::pixmap(size, state=0) has disappeared, due to core/gui separation. If you can, use KDE::icon(item.iconName(), item.overlays(), 0) instead. If you really need a QPixmap, e.g. for showing in a QLabel, use this instead: <pre> KIconLoader::global()-&gt;loadMimeTypeIcon(item.iconName(), KIconLoader::Desktop, size, state);</pre><br />
* KIO::pixmapForUrl has moved from kio/global.h to kio/pixmaploader.h (so that global.h is core only)<br />
* KProtocolInfo::isHelperProtocol() and exec() no longer detect apps associated with x-scheme-handler/*. This has moved up to KRun. Therefore KProtocolInfo is again about .protocol files only.<br />
* KIO::RenameDialogPlugin was removed, it was unused for a long time anyway. The rename dialog uses KFileMetaDataWidget and PreviewJob instead.<br />
* When Job::setUiDelegate(0) is used on a CopyJob (KIO::copy or KIO::move), an extra call to setUiDelegateExtension(0) is probably necessary, to disable skip and rename dialogs.<br />
* KIO::Job::isInteractive() has been removed, use uiDelegate() or uiDelegateExtension() depending on what is meant (error messages, or rename/skip dialog).<br />
* KIO::http_update_cache() now takes a QDateTime instead of a time_t, you can use QDateTime::fromTime_t if you need to<br />
* The "resume" and "resume_until" metadata keys have been renamed to "range-start" and "range-end".<br />
* KBookmark and assorted classes are now in a separate framework, kbookmarks. One API change is that KBookmarkDialog::addBookmark now takes a QString icon (to remove a dependency on KIO::iconNameForUrl). Instead, the caller is recommended to call KIO::iconNameForUrl himself (from the header kio/global.h).<br />
* KIO::NetAccess is deprecated, use KIO::get or similar functions and -&gt;exec() the returned job object.<br />
<br />
= KFile Changes =<br />
<br />
* libkfile is now called KIOFileWidgets, part of the KIO framework.<br />
* KFileWidget no longer inherits KAbstractFileWidget (which no longer exists). KAbstractFileWidget::{OperationMode, Other, Opening, Saving} is now KFileWidget::{...}<br />
<br />
= KParts Changes =<br />
<br />
* With the port from KUrl to QUrl in APIs, the signature of the virtual method openUrl has changed, make sure to port your reimplemented methods to QUrl!<br />
* TerminalInterfaceV2 has been merged into TerminalInterface, you can remove the "V2" everywhere (classname, interface name).<br />
* The installed normal lowercase headers no longer define multiple classes. Now it is only one class per header, with the filename matching the classname (e.g. KParts::ReadOnlyPart is no longer defined in <kparts/part.h> but <kparts/readonlypart.h>). So make sure you now include the matching headers.<br />
<br />
= ItemViews Changes =<br />
<br />
* KCategoryDrawer margins should be set by overriding the leftMargin/rightMargin methods as appropriate.<br />
* KWidgetItemDelegate::createItemWidgets now has an QModelIndex with the index to create widgets for. It does not need to be used<br />
<br />
= KArchive Changes =<br />
<br />
* KFilterBase::findFilterByFileName and KFilterBase::findFilterByMimeType are gone, now you should use KCompressionDevice::filterForCompressionType<br />
* To get the CompressionType you can call KFilterDev::compressionTypeForMimeType<br />
* KFilterDev::device is deprecated, instead you should use: <br />
<syntaxhighlight lang="cpp-qt"><br />
KCompressionDevice::CompressionType type = KFilterDev::compressionTypeForMimeType(mimeType);<br />
KCompressionDevice flt(&amp;file, false, type);<br />
</syntaxhighlight><br />
* KFilterDev::deviceForFile is deprecated, instead you should use: <syntaxhighlight lang="cpp-qt">KFilterDev dev(fileName)</syntaxhighlight><br />
<br />
= KEmoticons Changes =<br />
<br />
* KEmoticonsProvider::save is deprecated, instead you should use KEmoticonsProvider::saveTheme<br />
* KEmoticonsTheme::save is deprecated, instead you should subclass KEmoticonsProvider and implement the pure virtual method KEmoticonsProvider::saveTheme<br />
* KEmoticonsProvider::createNew is deprecated, instead you should use KEmoticonsProvider::newTheme<br />
* KEmoticonsTheme::createNew is deprecated, instead you should subclass KEmoticonsProvider and implement the pure virtual method KEmoticonsProvider::newTheme<br />
* KEmoticonsProvider::addEmoticonsMap is deprecated, instead you should use KEmoticonsProvider::addMapItem<br />
* KEmoticonsProvider::removeEmoticonsMap is deprecated, instead you should use KEmoticonsProvider::removeMapItem<br />
* KEmoticonsProvider::addEmoticonIndex is deprecated, instead you should use KEmoticonsProvider::addIndexItem<br />
* KEmoticonsProvider::removeEmoticonIndex is deprecated, instead you should use KEmoticonsProvider::removeIndexItem<br />
* KEmoticonsTheme::loadTheme is deprecated, instead you should subclass KEmoticonsProvider and implement the pure virtual method KEmoticonsProvider::loadTheme<br />
* KEmoticonsTheme::addEmoticon is deprecated, instead you should subclass KEmoticonsProvider and implement the pure virtual method KEmoticonsProvider::addEmoticon<br />
* KEmoticonsTheme::removeEmoticon is deprecated, instead you should subclass KEmoticonsProvider and implement the pure virtual method KEmoticonsProvider::removeEmoticon<br />
<br />
= KDNSSD Changes =<br />
* The include paths have changed from dnssd to kdnssd<br />
* The namespace has changed from DNSSD to KDNSSD<br />
<br />
= KNewStuff3 Changes =<br />
* The include paths has changed from knewstuff3 to kns3 (Use kde-dev-scripts/kf5/adapt_knewstuff3_includes.pl to automate most of the conversion. )<br />
<br />
= KUnitConversion Changes =<br />
<br />
* KUnitConversion is now a separate Tier 2 Framework, you need to link to KF5::UnitConversion<br />
* The Convertor, CategoryUnit, Unit and Value classes are all now standard Qt shared data containers, i.e. like QString. Each class is either implicitly or explicitly shared as appropriate, and should be passed by const references. The main impact of this is that existing code will need to change from calling of methods from -> to . notation.<br />
* The api now uses the enums instead of int<br />
* The api now uses qreal instead of double<br />
* The custom constructors and protected setters have been removed. If you require adding custom units, please contact the maintainer to discuss.<br />
<br />
= Plasma Changes =<br />
<br />
libplasma has been replaced with libplasma2. See the [[Plasma/PortingTolibplasma2|libplasma2 porting notes]].<br />
Plasma themes specifications has seen small changes as well (intended and unintended) . See the [https://techbase.kde.org/Development/Tutorials/Plasma5/ThemePortingToPlasma5 Theme porting notes].<br />
<br />
= Docbook Documentation Changes =<br />
<br />
* The DocBookXML schema used by the documentation has changed; the custom KDE DTD is now based on version 4.5 (previously was 4.2).<br />
* The change is almost painless (and should be completely painless for applications using KDE4Support).<br />
* You need to change the DOCTYPE declaration as follows:<br />
<syntaxhighlight lang="diff"><br />
--- <!DOCTYPE book PUBLIC "-//KDE//DTD DocBook XML V4.2-Based Variant V1.1//EN" "dtd/kdex.dtd" [<br />
+++ <!DOCTYPE book PUBLIC "-//KDE//DTD DocBook XML V4.5-Based Variant V1.1//EN" "dtd/kdedbx45.dtd" [</syntaxhighlight><br />
<br />
(The changes are "V4.2" to "V4.5" and "dtd/kdex.dtd" to "dtd/kdedbx45.dtd").<br />
<br />
= KAuth Changes =<br />
* KDE4_AUTH_HELPER_MAIN should be replaced by KAUTH_HELPER_MAIN<br />
<br />
= KTextEditor Changes =<br />
Changes to the KTextEditor Interfaces are documented in the API documentation: http://api.kde.org/frameworks-api/frameworks5-apidocs/ktexteditor/html/kte_port_to_5.html<br />
<br />
= KNotifications Changes =<br />
* KNotifications lets you set a default sound for notifications. Typically for KDE applications these were sounds shipped by kde-runtime. These should be changed to files shipped by Plasma 5. This is the same as the kde-runtime sound theme but with files renamed to start with Oxygen- instead of KDE-. You will need to update your .notifyrc file for this, e.g. Sound=KDE-Sys-Log-Out.ogg is now Sound=Oxygen-Sys-Log-Out.ogg<br />
<br />
= Solid Changes =<br />
== Interfaces ==<br />
* DvbInterface: We only supported linux plus usually this is used together with a multimedia framework. Users of this interface will be better suited using that multimedia framework to get a list of devices.<br />
* Video: We only supported linux plus usually this is used together with a multimedia framework. Users of this interface will be better suited using that multimedia framework to get a list of devices.<br />
*Button: New Async api will be added to announce button availability and state.<br />
*NetworkInterface: Use QNetworkConfigurationManager.<br />
*InternetGateway: This class mattered only for UPnP, we never had proper UPnP support so if you were using this just remove any usage.<br />
*SerialInterface: You can use UdevQt (you can find that inside Solid) for the time being. New api will be added to QtSerialport.<br />
*AudioInterface: We were only supporting Alsa here, if you were using this either use Alsa directly or UdevQt.<br />
*SmartCardReader: This was not even working since we moved from HAL (4 years ago). If you are using this please remove any usage of it.<br />
<br />
== Solid Networking ==<br />
QNetworkConfigurationManager does most of the things Solid/Networking did.<br />
<br />
== Solid Powermanagement ==<br />
New async api will be added, W.I.P<br />
<br />
= Sonnet Changes =<br />
<br />
The only big change from an API consumer standpoint is that it was ported away from KConfig, and also lost the ability to set per-application settings, for now. It's on my todolist to bring it back, but if someone else wants to implement it feel free (one semi-big gotcha will be to avoid exposing QSettings directly, as the QSettings codebase is a mess and we might want to port away from it in the future, without impacting applications that use Sonnet).<br />
<br />
= libkonq =<br />
<ul><br />
<li><br />
KonqMimeData::populateMimeData(mimeData, kdeUrls, mostLocalUrls, cut) is now<br />
<syntaxhighlight lang="cpp-qt"><br />
KIO::setClipboardDataCut(mimeData, cut);<br />
KUrlMimeData::setUrls(kdeUrls, mostLocalUrls, mimeData);<br />
</syntaxhighlight><br />
or if one of the two URL lists was always empty, just mimeData->setUrls(urls);<br />
</li><br />
<li>KonqMimeData::addIsCutSelection(mimeData, cut) is now KIO::setClipboardDataCut(mimeData, cut);</li><br />
<li>KonqMimeData::decodeIsCutSelection is now KIO::isClipboardDataCut.</li><br />
<li>KonqStatusbarMessageLabel has moved back to konqueror, its only user.</li><br />
<li>KonqFileItemCapabilities and KonqPopupMenuInformation were removed, use KFileItemListProperties from KIO.</li><br />
<li>KonqMenuActions was removed, use KFileItemActions from KIO.</li><br />
<li>KNewMenu was removed, use KNewFileMenu from KIO.</li><br />
<li><br />
KonqOperations::restoreTrashedItems should be replaced with<br />
<syntaxhighlight lang="cpp-qt"><br />
KIO::RestoreJob *job = KIO::restoreFromTrash(urls);<br />
KJobWidgets::setWindow(job, m_mainWindow);<br />
job->uiDelegate()->setAutoErrorHandlingEnabled(true); // or connect to the result signal<br />
</syntaxhighlight><br />
</li><br />
<li>KonqOperations::emptyTrash should be replaced with<br />
<syntaxhighlight lang="cpp-qt"><br />
KIO::JobUiDelegate uiDelegate;<br />
uiDelegate.setWindow(m_mainWindow);<br />
if (uiDelegate.askDeleteConfirmation(QList<QUrl>(), KIO::JobUiDelegate::EmptyTrash, KIO::JobUiDelegate::DefaultConfirmation)) {<br />
KIO::Job* job = KIO::emptyTrash();<br />
KJobWidgets::setWindow(job, m_mainWindow);<br />
job->ui()->setAutoErrorHandlingEnabled(true); // or connect to the result signal<br />
}<br />
</syntaxhighlight><br />
It's a bit more verbose, but you can choose how you want to ask confirmation and how you want to handle errors.<br />
</li><br />
<li>KonqOperations::askDeleteConfirmation should be replaced with uiDelegate.askDeleteConfirmation as in the example above.</li><br />
<li>KonqOperations::del should be replaced with<br />
<syntaxhighlight lang="cpp-qt"><br />
KIO::JobUiDelegate uiDelegate;<br />
uiDelegate.setWindow(m_mainWindow);<br />
if (uiDelegate.askDeleteConfirmation(urls, KIO::JobUiDelegate::Trash or Delete, KIO::JobUiDelegate::DefaultConfirmation)) {<br />
KIO::Job* job = KIO::del(urls); // or KIO::trash(urls)<br />
// after KIO::trash, add this for undo/redo support:<br />
// KIO::FileUndoManager::self()->recordJob( KIO::FileUndoManager::Trash, urls, KUrl("trash:/"), job );<br />
KJobWidgets::setWindow(job, m_mainWindow);<br />
job->ui()->setAutoErrorHandlingEnabled(true); // or connect to the result signal<br />
}<br />
</syntaxhighlight><br />
</li><br />
<li>KonqOperations::copy should be replaced with<br />
<syntaxhighlight lang="cpp-qt"><br />
KIO::CopyJob* job = KIO::copy(selectedUrls, destUrl); // or KIO::move, or KIO::link<br />
KIO::FileUndoManager::self()->recordCopyJob(job);<br />
KJobWidgets::setWindow(job, m_mainWindow);<br />
job->ui()->setAutoErrorHandlingEnabled(true); // or connect to the result signal<br />
</syntaxhighlight><br />
</li><br />
<li>KonqOperations::mkdir should be replaced with<br />
<syntaxhighlight lang="cpp-qt"><br />
KIO::SimpleJob* job = KIO::mkdir(url);<br />
KIO::FileUndoManager::self()->recordJob(KIO::FileUndoManager::Mkdir, QList<QUrl>(), url, job);<br />
KJobWidgets::setWindow(job, m_mainWindow);<br />
job->ui()->setAutoErrorHandlingEnabled(true); // or connect to the result signal<br />
</syntaxhighlight><br />
</li><br />
<li>KonqOperations::newDir should be replaced with KNewFileMenu::createDirectory, which requires having a long-living instance, calling setParentWidget, and setPopupFiles first. See this [http://commits.kde.org/gwenview/814d1bbfbee68065b6808ed76ae6ecd241c3c87b gwenview commit] for an example.</li><br />
<li><br />
KonqOperations::pasteInfo(destUrl) should be replaced with KIO::pasteActionText(QApplication::clipboard()->mimeData(), &enable, destItem)<br />
</li><br />
<br />
= Migrating configuration =<br />
<br />
Since KDE Frameworks 5.2, there is a convenience class in KCoreAddons (Kdelibs4ConfigMigrator) that can be used to migrate configuration files from 4.x applications (stored in KDEHOME/share/config) to the XDG_*_HOME used by KF5-based applications. As it will ensure that user-facing applications will not lose their settings once ported to KF5, hence usage is highly recommended (with some caveats: see below).<br />
<br />
If you use it, you will have to link to KCoreAddons.<br />
<br />
Running the migration is an one-time step, and you should put it directly in the main() function of your application, before instantiating QApplication:<br />
<br />
<syntaxhighlight lang="cpp-qt"><br />
#include <Kdelibs4ConfigMigrator><br />
// ... other code here<br />
<br />
Kdelibs4ConfigMigrator migrator(QStringLiteral("myappname")); // the same name defined in the aboutData<br />
// all the config files of your application<br />
migrator.setConfigFiles(QStringList() << QStringLiteral("myapprc") << QStringLiteral("myotherconfigrc"));<br />
// list of KXMLGUI files used by your application<br />
migrator.setUiFiles(QStringList() << QStringLiteral("myappui.rc")); <br />
migrator.migrate();<br />
</syntaxhighlight><br />
<br />
There is a caveat you should keep in mind: this code copies the files '''verbatim'''. In case you have adjusted your configuration files, don't forget to use a kconf_update script to ensure they are adjusted properly. <br />
<br />
There is no need to check for the existence of the migrated files: if they are already present, the migration is skipped.</div>Dfaurehttps://community.kde.org/index.php?title=Frameworks/Porting_Notes/KStandardDirs&diff=86159Frameworks/Porting Notes/KStandardDirs2019-09-10T09:25:01Z<p>Dfaure: </p>
<hr />
<div>'''A script is available in kdesdk/kde-dev-scripts/kf5/convert-kstandarddirs.pl to port some of this.'''<br />
<br />
KStandardDirs is now in kdelibs4support. Apps can keep using it, but it is recommended to use QStandardPaths instead. Note that KStandardDirs makes some assumptions about all the frameworks being installed in the same location that the frameworks themselves do not.<br />
<br />
Also note that $KDEDIRS and $KDEHOME do not exist anymore (no matter which class you use).<br />
<br />
The porting depends on the resource type:<br />
<pre><br />
KStandardDirs "data" -&gt; QStandardPaths::GenericDataLocation<br />
KStandardDirs "appdata" -&gt; QStandardPaths::AppDataLocation // or AppLocalDataLocation<br />
KStandardDirs "config" -&gt; QStandardPaths::GenericConfigLocation<br />
KStandardDirs "xdgdata-apps" -&gt; QStandardPaths::ApplicationsLocation<br />
KStandardDirs "cache" -&gt; QStandardPaths::GenericCacheLocation<br />
KStandardDirs "socket" -&gt; QStandardPaths::RuntimeLocation<br />
</pre><br />
If the resource is available in QStandardPaths (i.e. for all of the above), then the porting is simple:<br />
<pre><br />
KStandardDirs::locate("data", "kmyapp/my-data") -&gt; QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kmyapp/my-data")<br />
KStandardDirs::locate("services", "foo.desktop") -&gt; QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kde5/services/foo.desktop")<br />
dirs.findResource("data", relPath) -&gt; QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kmyapp/my-data")<br />
dirs.findDirs("data", "kconf_update") -&gt; QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, "kconf_update", QStandardPaths::LocateDirectory)<br />
saveLocation -&gt; writableLocation (note that you might have to mkpath it if it doesn't exist)<br />
locateLocal(type, file) -&gt; writableLocation(type) + '/' + file (you might have to mkpath the directory)<br />
locateLocal(tmp, file) -&gt; QDir::tempPath() + '/' + file<br />
resourceDirs("xdgdata-apps") -&gt; QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation) (no trailing slashes anymore though)<br />
</pre><br />
Otherwise, you need to use GenericDataLocation and add the subdirectory name manually.<br />
<pre><br />
dirs()-&gt;resourceDirs("xdgdata-icon") -&gt; QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, "icons", QStandardPaths::LocateDirectory) // xdgata-icon is the "icons" subdir under the xdg data locations<br />
dirs()-&gt;findAllResources("xdgdata-mime", file) -&gt; QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, "mime/" + file)<br />
Similarly, xdgconf-menu is QStandardPaths::GenericConfigLocation + "menus", and xdgconf-autostart is QStandardPaths::GenericConfigLocation + "autostart";<br />
"xdgdata-dirs" is QStandardPaths::GenericDataLocation + "desktop-directories"<br />
"templates" is QStandardPaths::GenericDataLocation + "templates"<br />
"emoticons" is QStandardPaths::GenericDataLocation + "emoticons<br />
"html" is QStandardPaths::GenericDataLocation + "doc/HTML"<br />
"sound" is QStandardPaths::GenericDataLocation + "sounds" (note the additional 's')<br />
"wallpaper" is QStandardPaths::GenericDataLocation + "wallpapers" (note the additional 's')<br />
"apps" was the kde3 "applnk" directory. Remove this compatibility code altogether, or port it to xdgdata-apps, i.e. QStandardPaths::ApplicationsLocation.<br />
(see kstandarddirs.cpp line 119 ff for resources that are missing here)<br />
</pre><br />
When the code uses wildcard filters or the Recursive flag in findAllResources, you cannot port it to one line of QStandardPaths. Either keep using KStandardDirs, or write your own filtering (QDir::entryList) or recursive listing (use QDirIterator with the Subdirectories flag). Also, check for absolute paths first, findAllResources(res, "/absolute/path") returned the path, QStandardPaths doesn't.<br />
<br/><br />
If NoDuplicates was used, make a unique list of relative paths first, then use locate on each one (see autostart.cpp for an example).<br />
<br/><br />
Example using entryList:<br />
<syntaxhighlight lang="cpp-qt"><br />
QStringList files = dirs()->findAllResources("data", "foo/bar/*.desktop")<br />
</syntaxhighlight><br />
becomes:<br />
<syntaxhighlight lang="cpp-qt"><br />
QStringList files;<br />
const QStringList dirs = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, "foo/bar", QStandardPaths::LocateDirectory);<br />
Q_FOREACH (const QString& dir, dirs) {<br />
const QStringList fileNames = QDir(dir).entryList(QStringList() << QStringLiteral("*.desktop"));<br />
Q_FOREACH (const QString& file, fileNames) {<br />
files.append(dir + '/' + file);<br />
}<br />
}<br />
</syntaxhighlight><br />
Example using QDirIterator:<br />
<syntaxhighlight lang="cpp-qt"><br />
QStringList files;<br />
const QStringList dirs = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, "foo/bar", QStandardPaths::LocateDirectory);<br />
Q_FOREACH (const QString& dir, dirs) {<br />
QDirIterator it(dir, QStringList() << QStringLiteral("*.desktop"));<br />
while (it.hasNext()) {<br />
files.append(it.next());<br />
}<br />
}<br />
</syntaxhighlight><br />
On the other hand, findAllResources("locale", "*/entry.desktop") requires<br />
<syntaxhighlight lang="cpp-qt"><br />
const QStringList localeDirs = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("locale"), QStandardPaths::LocateDirectory);<br />
Q_FOREACH (const QString &localeDir, localeDirs) {<br />
const QStringList entries = QDir(localeDir).entryList(QDir::Dirs);<br />
Q_FOREACH (const QString &d, entries) {<br />
if (QFile::exists(localeDir + '/' + d + "/entry.desktop")) {<br />
// ...<br />
}<br />
}<br />
}<br />
</syntaxhighlight><br />
KStandardDirs::findExe (and the use of the "exe" resource) can be ported to QStandardPaths::findExecutable, except when the executable comes from libexec, in which case the path should just be hardcoded using CMAKE_INSTALL_PREFIX "/" LIBEXEC_INSTALL_DIR.<br />
<br />
The "lib" resource was not used directly in code (the linker finds shared libs, not the code).<br />
<br />
The "module" resource, on the other hand, was used to locate plugins. KPluginLoader now uses QT_PLUGIN_PATH instead, and looks in the kf5 subdirectory.<br />
Please email kde-frameworks-devel@kde.org if you would need public API for this.<br />
<br />
With KStandardDirs, applications could even define their own resource types with addResourceType() or addResourceDir(). This was like creating an alias for a directory (relative or absolute) and using that later. With QStandardPaths there is no such mechanism, just use the subdir directly in your calls to QStandardPaths::locate/locateAll.<br />
For instance, this code:<br />
<syntaxhighlight lang="cpp-qt"><br />
KGlobal::dirs()->addResourceType("dtd", "data", "ksgmltools2/");<br />
KStandardDirs::locate("dtd", fileName);<br />
</syntaxhighlight><br />
becomes<br />
<syntaxhighlight lang="cpp-qt"><br />
QStandardPaths::locate(QStandardPaths::GenericDataLocation, "ksgmltools2/" + fileName);<br />
</syntaxhighlight><br />
<br />
For relativeLocation, see the helper method in the documentation for the method in kstandarddirs.h.</div>Dfaurehttps://community.kde.org/index.php?title=Guidelines_and_HOWTOs/Flatpak&diff=85335Guidelines and HOWTOs/Flatpak2019-07-23T09:28:10Z<p>Dfaure: Upgrade to 5.12</p>
<hr />
<div>Flatpak is a solution for creating sandboxed software builds for GNU/Linux systems. You can find more information [http://flatpak.org/ here].<br />
<br />
= Applications =<br />
We are building release versions of most KDE applications and distributing them on flathub, https://flathub.org.<br />
We are also building nightlies of most KDE applications and distributing them at https://distribute.kde.org. This has the master version of the applications, so expect some unstable development quirks; on the bright side, if you find one, you get to tell the developers so they can fix it!<br />
<br />
The "app store" or software center in many distributions is able to install Flatpaks.<br />
You can simply open the flatpakrepo files with Discover or your otherwise favorite software center:<br />
* https://flathub.org/repo/flathub.flatpakrepo<br />
* https://distribute.kde.org/kdeapps.flatpakrepo<br />
and then when you search for a KDE application it should offer to install the flatpak version.<br />
<br />
Here's how to install a Flatpak application from the terminal:<br />
<syntaxhighlight lang="bash"><br />
flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo<br />
flatpak remote-add --if-not-exists kdeapps --from https://distribute.kde.org/kdeapps.flatpakrepo<br />
flatpak install kdeapps org.kde.okular<br />
</syntaxhighlight><br />
<br />
If you added both the Flathub and kdeapps repos, the `flatpak` command-line tool will prompt you which one you want, something like:<br />
<syntaxhighlight><br />
flatpak install skrooge<br />
Looking for matches…<br />
Remotes found with refs similar to ‘skrooge’:<br />
<br />
1) ‘flathub’ (system)<br />
2) ‘kdeapps’ (system)<br />
<br />
Which do you want to use (0 to abort)? [0-2]: 2<br />
Found ref ‘app/org.kde.skrooge/x86_64/master’ in remote ‘kdeapps’ (system).<br />
Use this ref? [Y/n]: y<br />
</syntaxhighlight><br />
<br />
== Build status ==<br />
The Continuous Integration that triggers many of the nightly flatpak builds is at https://binary-factory.kde.org.. If a flatpak is not updated or has a problem, you may be able to look at build logs here and puzzle out why.<br />
<br />
= Qt and KF5 Runtime =<br />
We provide a runtime with Qt and all KDE Frameworks 5 (except for the 4th tier) to make sure it's easily adaptable for any KDE Application and possibly most Qt-based applications as well.<br />
<br />
This runtime can be added by following these instructions:<br />
<syntaxhighlight lang="bash"><br />
flatpak install flathub org.kde.Platform//5.12<br />
flatpak install flathub org.kde.Sdk//5.12<br />
</syntaxhighlight><br />
<br />
{{ Note | All flatpak commands (such as <code>remote-add</code> and <code>install</code>) accept a <code>--user</code> option to install things at the user level, without being prompted for the sudo password every time. }}<br />
<br />
= Compile your application =<br />
<br />
Now you get to compile your favorite application. If you want to see how it's done, you can see some of the ones that have already been built. You can find it [https://cgit.kde.org/flatpak-kde-applications.git/tree/ here].<br />
<br />
To compile applications, you should create a json file similar to the ones in the previous link. Then you'd just need to trigger the build and get it into a repository. For testing, I recommend just creating a local one (to publish an rsync will be required).<br />
<br />
<syntaxhighlight lang="bash"><br />
mkdir app repo<br />
flatpak-builder --ccache --repo=repo --subject="Build of AWESOMEAPP `date`" app org.kde.AWESOMEAPP.json<br />
</syntaxhighlight><br />
<br />
This will do everything required and create a repository in ./repo. To test the application we add the repository (called remotes), we install the application and then we run it:<br />
<syntaxhighlight lang="bash"><br />
flatpak remote-add awesomeapp repo --no-gpg-verify<br />
flatpak install awesomeapp org.kde.AWESOMEAPP<br />
flatpak run org.kde.AWESOMEAPP<br />
</syntaxhighlight><br />
<br />
Now you will see that some things don't work and you'll have the privilege to start fixing things!<br />
<br />
= Contribute! =<br />
In the following repositories you'll find the code in charge of packaging the runtime (Qt 5 and KF5) and then several (but not all, yet) KDE Applications.<br />
* Runtime: https://phabricator.kde.org/source/flatpak-kde-runtime/<br />
* Applications: https://phabricator.kde.org/source/flatpak-kde-applications/<br />
* Our XDG portals: https://phabricator.kde.org/source/xdg-desktop-portal-kde/<br />
<br />
= Flatpak portals =<br />
Portals are high-level session bus APIs that provide selective access to resources to sandboxed applications. The implicit expectation of portals is that the user will always be involved in granting or rejecting a portal request, thus most portal APIs will lead to user interaction in the form of dialogs.<br />
<br />
Since such dialogs must fit into the user experience of the desktop shell, the portal APIs are implemented by a generic frontend called [https://github.com/flatpak/xdg-desktop-portal xdg-desktop-portal] which calls out to desktop-specific implementations that provide the actual UI. The bus name through which the portal APIs are available is org.freedesktop.portal.Desktop, with the object path /org/freedesktop/portal/desktop implementing the various portal interfaces.<br />
{{ Note | You can find more information about flatpak portals [https://github.com/flatpak/flatpak/wiki/Portals here]. }}<br />
<br />
== KDE implementation of portals ==<br />
KDE backend for flatpak portals is called [https://cgit.kde.org/xdg-desktop-portal-kde.git/ xdg-desktop-portal-kde] and is now part of Plasma releases (starting with Plasma 5.10). Currently it supports most of the portals. If you want to test KDE flatpak portals, you can use this [https://cgit.kde.org/xdg-portal-test-kde.git/ simple test app].<br />
<br />
====Debugging portals====<br />
To get some debug information, you first kill the running '''xdg-desktop-portal-kde''' instance. Then first start xdg-desktop-portal-kde with:<br />
<syntaxhighlight lang="bash"><br />
QT_LOGGING_RULES='xdg-desktop*.debug=true' /usr/lib/$(uname -m)-linux-gnu/libexec/xdg-desktop-portal-kde<br />
</syntaxhighlight><br />
then in another terminal session restart '''xdg-desktop-portal''' with:<br />
<syntaxhighlight lang="bash"><br />
G_MESSAGES_DEBUG=all /usr/libexec/xdg-desktop-portal --verbose --replace<br />
</syntaxhighlight><br />
You can use above mentioned testing application to test various portals. You should then see debug output from xdp-kde similar to:<br />
<syntaxhighlight lang="bash"><br />
xdg-desktop-portal-kde: Desktop portal registered successfuly<br />
xdg-desktop-portal-kde-file-chooser: OpenFile called with parameters:<br />
xdg-desktop-portal-kde-file-chooser: handle: "/org/freedesktop/portal/desktop/request/1_255/t"<br />
xdg-desktop-portal-kde-file-chooser: parent_window: "x11:1"<br />
xdg-desktop-portal-kde-file-chooser: title: "Flatpak test - open dialog"<br />
xdg-desktop-portal-kde-file-chooser: options: QMap(("accept_label", QVariant(QString, "Open (portal)"))("filters", QVariant(QDBusArgument, ))("modal", QVariant(bool, true))("multiple", QVariant(bool, true)))<br />
</syntaxhighlight><br />
You can see which portal has been called, whether it has been called or when you check output from '''xdg-desktop-portal''' then you should see message in case of portal error (usually related to DBus). You can also monitor dbus messages using '''dbus-monitor''', which indicates whether portals get involved at all as everything goes through DBus.<br />
<br />
= Styles and integration with other desktops =<br />
We are aware that not everyone is using KDE/Qt applications in Plasma desktop. For this flatpak comes with extensions, where you specify a directory (with themes, icons) where third-party is allowed to install additional stuff as an addition to what we have in our runtimes. At this moment we have added support for Gnome in form of adwaita icons and adwaita-qt style. All you need to is install following extensions using commands below:<br />
<syntaxhighlight lang="bash"><br />
flatpak install kdeapps org.freedesktop.Platform.Icontheme.Adwaita<br />
flatpak install kdeapps org.kde.KStyle.Adwaita<br />
flatpak install kdeapps org.kde.PlatformTheme.QGnomePlatform<br />
</syntaxhighlight></div>Dfaurehttps://community.kde.org/index.php?title=Frameworks/Policies&diff=85276Frameworks/Policies2019-07-21T09:48:13Z<p>Dfaure: /* Frameworks Qt requirements */</p>
<hr />
<div><br />
== Frameworks have a Tier and a Type ==<br />
Each framework has a clear position in the Tier/Type matrix, its position forces a set of rules on its possible dependencies. This matrix and its rules are summarized in the [http://files.kde.org/frameworks/kde-frameworks-matrix.pdf Frameworks matrix document].<br />
<br />
<br />
The constraints from Tiers are the following:<br />
* Tier 1 Frameworks can depend only on Qt official frameworks or other system libraries;<br />
* Tier 2 Frameworks can depend only on Tier 1 Frameworks, Qt official frameworks, or other system libraries;<br />
* Tier 3 Frameworks can depend only on other Tier 3 Frameworks, Tier 2 Frameworks, Tier 1 Frameworks, Qt official frameworks, or other system libraries.<br />
<br />
<br />
The constraints from Types are the following:<br />
* Functional Qt Addons cannot have runtime dependencies;<br />
* Integration Qt Addons can have an optional runtime dependencies and aim at integrating with the underlying OS/Platform;<br />
* Solutions have mandatory runtime dependencies, it is part of their design and where their added value comes from (think scalability, resource sharing, resilience, etc.).<br />
<br />
== Framework directory structure ==<br />
All the frameworks will have the same directory structure which will follow some rules:<br />
* The containing directory has the name of the technology (plasma, kio, itemmodels, etc.);<br />
* At the top level we find the common files like README.md, COPYING.LIB, metainfo.yaml...<br />
* More comprehensive documentation go into a '''docs''' subdirectory<br />
* The source code for the targets go into '''src''' subdirectory, if several payloads are built (like a core lib and a gui layer on top) then src will contain one subdirectory per library: core, gui, widgets, etc.<br />
* Code examples go into an '''examples''' subdirectory<br />
* Automatic tests go into an '''autotests''' subdirectory<br />
* Test applications go into a '''tests''' subdirectory<br />
* CMake modules (FindFoo.cmake etc.) or CMake macro files go into '''cmake''' subdirectory<br />
<br />
== Frameworks have automatic unit tests ==<br />
Enough said really... They must be unit tested with automatic unit tests.<br />
<br />
Corollary: When fixing a bug in a framework, the auto-test proving the bug and the fix should come in the same commit.<br />
<br />
== Frameworks maintain binary compatibility ==<br />
Just like we did in kdelibs, KDE Frameworks maintain the binary compatibility through their lifetime, for more details see the [[Policies/Binary_Compatibility_Issues_With_C++| binary compatibility policy]].<br />
<br />
Note however that this policy is lifted during major version transition, corresponding epics of milestones will be marked as such.<br />
<br />
== Frameworks are documented ==<br />
<br />
The API exposed by frameworks are documented using Doxygen. Documentation follows the [[Frameworks/Frameworks_Documentation_Policy|Frameworks Documentation Policy]].<br />
<br />
== Frameworks are localized ==<br />
<br />
Frameworks adapt to the user language and locale settings. This is described in the [[Frameworks/Frameworks_Localization_Policy|Frameworks Localization Policy]].<br />
<br />
== Frameworks buildsystem is consistent ==<br />
<br />
* each framework should install a CMake configuration file for itself. This includes:<br />
** a FooConfig.cmake file<br />
** a FooConfigVersion.cmake file<br />
** usually a FooTargets.cmake file<br />
** optionally a file containing macros/functions for using the package<br />
* no framework should install any other CMake files than mentioned above. Find-modules useful for multiple packages should be upstreamed into extra-cmake-modules if they are generally useful. <br />
* For especially exotic packages which are not suitable for extra-cmake-modules, it is ok for a framework to have extra find modules, but they should not be installed.<br />
* Library names are in CamelCase<br />
* All dependencies between frameworks are documented in the CMakeLists.txt (see for instance kio/src/core/CMakeLists.txt)<br />
<br />
For an example, see the [http://quickgit.kde.org/?p=kdeexamples.git&a=tree&f=framework-template framework-template] directory in the kdeexamples repository (you can use setup.sh to create a template that matches the name of your framework).<br />
<br />
== Frameworks commits are reviewed ==<br />
Make sure all commits in the master branch of a repository part of the KDE Frameworks got a proper review. As such commits must contain either a "Reviewed by:" (for quick pastebin reviews) or a "REVIEW:" (for more formal reviewboard reviews).<br />
<br />
== Frameworks CI failures are treated as stop the line events ==<br />
When a commit causes a regression in the CI for one of the frameworks, then all work on the corresponding framework should stop. The only commits allowed in are those working toward a resolution of the problem. Only once the framework is green again that regular work can be resumed.<br />
<br />
== Frameworks Qt requirements ==<br />
KDE Frameworks are tested and working with the last 3 minor Qt releases. For instance, once Qt 5.11 was released, the minimum required Qt version changed from Qt 5.8 to Qt 5.9, i.e. the three supported Qt versions became 5.9, 5.10 and 5.11.<br />
<br />
In addition, a Qt LTS release remains supported until the next Qt release after the next Qt LTS release.<br />
For instance, when Qt 5.15 is released, Qt 5.12 remains supported until Qt 5.16, to give time for people to migrate from Qt 5.12 LTS to Qt 5.15 LTS. When Qt 5.16 is released, both Qt 5.12 LTS and Qt 5.13 are dropped, to go back to "last 3 minor Qt releases".<br />
<br />
== Frameworks compiler requirements and C++11 ==<br />
The following minimal compiler versions are supported by KDE Frameworks:<br />
* GCC 4.8<br />
* Clang 3.3<br />
* VS2013 (MSVC12)<br />
<br />
This means all of the C++11 standards can be used.</div>Dfaurehttps://community.kde.org/index.php?title=Sprints/Onboarding/2019&diff=84586Sprints/Onboarding/20192019-05-24T10:48:08Z<p>Dfaure: /* Attendance */</p>
<hr />
<div>===Streamlined Onboarding Sprint 2019===<br />
This is the planning page for the [https://phabricator.kde.org/T7116 Streamlined Onboarding] goal 2019 development sprint. Note that we plan to hold it directly after the [https://community.kde.org/Sprints/KDE_Connect/2019 KDE Connect 2019 sprint], at the same place.<br />
<br />
Dates: Monday 2019-07-22 - Tuesday 2019-07-23<br />
<br />
Location: Suse offices, Nuremberg, Germany<br />
https://www.openstreetmap.org/#map=19/49.45960/11.08203&layers=N <br />
<br />
== Topics ==<br />
Making it easier to setup a development environment and start working on KDE software: https://phabricator.kde.org/T8484<br />
<br />
==Where to stay==<br />
A nearby hotel will be provided free of charge (currently in the planning stages).<br />
<br />
==Attendance==<br />
Please add your name to the table below if you're coming, along with arrival and departure dates.<br />
<br />
{| class="wikitable"<br />
|-<br />
! Name<br />
! Arrival<br />
! Leaving<br />
! Accomodation<br />
|-<br />
|Neofytos Kolokotronis<br />
| 20th<br />
| 24th<br />
| <br />
|-<br />
|-<br />
| Aleix Pol<br />
| 19th<br />
| 24th<br />
| <br />
|-<br />
| Filip Fila<br />
| 21st (20:40)<br />
| 23rd (23:05)<br />
| <br />
|-<br />
|Boudewijn Rempt<br />
| 19th<br />
| 24th<br />
|<br />
|-<br />
|Dmitry Kazakov<br />
| 19th<br />
| 24th<br />
|<br />
|-<br />
|David Faure<br />
|19th (22:45)<br />
|23nd (14:50)<br />
|<br />
|-<br />
|Harald Sitter<br />
|21th<br />
|24th<br />
|<br />
|-<br />
|Piyush Aggarwal<br />
|19th<br />
|23rd<br />
|<br />
|-<br />
|Simon Redman<br />
| (KDE Connect)<br />
| 23 July @ 09:40<br />
| Hotel (Already paid)<br />
|-<br />
|Weixuan Xiao<br />
|19th<br />
|23rd<br />
|<br />
|-<br />
|Albert Astals Cid (potentially)<br />
|21st<br />
|24th<br />
|???<br />
|-<br />
|David Redondo<br />
|22nd<br />
|23rd<br />
|<br />
|-<br />
<br />
|}<br />
<br />
== Travel reimbursement ==<br />
https://reimbursements.kde.org/events/98<br />
<br />
==Communication==<br />
Matrix channel: #kde-onboarding-sprint:kde.org</div>Dfaurehttps://community.kde.org/index.php?title=Sprints/KDE_Connect/2019&diff=84585Sprints/KDE Connect/20192019-05-24T10:47:22Z<p>Dfaure: /* Attendance */</p>
<hr />
<div>===KDE Connect sprint 2019===<br />
<br />
Friday 2019-07-19 - Sunday 2019-07-21<br />
<br />
Location: Suse offices, Nuremberg<br />
<br />
https://www.openstreetmap.org/#map=19/49.45960/11.08203&layers=N<br />
<br />
== Topics ==<br />
https://notes.kde.org/p/kdeconnect-sprint-2019<br />
<br />
==Where to stay==<br />
tbd.<br />
<br />
==Attendance==<br />
<br />
Please put your name below if you're coming along with arrival and leave dates<br />
<br />
Keep list alphabetically sorted.<br />
<br />
{| class="wikitable"<br />
|-<br />
! Name<br />
! Arrival<br />
! Leaving<br />
! Accommodation<br />
|-<br />
| Albert Vaca<br />
| 19th<br />
| 21st<br />
| <br />
|-<br />
| Aleix Pol<br />
| 19th<br />
| 24th<br />
| <br />
|-<br />
| Erik Duisters<br />
| 19th<br />
| 21st<br />
| <br />
|-<br />
| Kai Uwe Broulik<br />
| 19th<br />
| 21st<br />
|<br />
|-<br />
| David Edmundson<br />
| 19th<br />
| 21st<br />
| <br />
|-<br />
| David Faure<br />
| 19th (22:45)<br />
| 23th (14:50)<br />
| <br />
|-<br />
| Nicolas Fella<br />
| 19th-ish<br />
| 21st-ish<br />
| <br />
|-<br />
| Simon Redman<br />
| 18th<br />
| 23st<br />
| Hotel (Booked with brother for simultaneous vacation)<br />
|-<br />
| Matthijs Tijink<br />
| 19th<br />
| 21st-ish<br />
|<br />
|-<br />
| Piyush Aggarwal<br />
| 18th<br />
| 23rd<br />
|<br />
|-<br />
| Richard Liebscher (R1tschY)<br />
| 19th<br />
| 21rd<br />
| <br />
|-<br />
| Weixuan Xiao<br />
| 19th<br />
| 23rd<br />
| <br />
|-<br />
|}<br />
<br />
== Travel reimbursement ==<br />
https://reimbursements.kde.org/events/97</div>Dfaurehttps://community.kde.org/index.php?title=Sprints/Onboarding/2019&diff=84584Sprints/Onboarding/20192019-05-24T10:23:42Z<p>Dfaure: /* Attendance */</p>
<hr />
<div>===Streamlined Onboarding Sprint 2019===<br />
This is the planning page for the [https://phabricator.kde.org/T7116 Streamlined Onboarding] goal 2019 development sprint. Note that we plan to hold it directly after the [https://community.kde.org/Sprints/KDE_Connect/2019 KDE Connect 2019 sprint], at the same place.<br />
<br />
Dates: Monday 2019-07-22 - Tuesday 2019-07-23<br />
<br />
Location: Suse offices, Nuremberg, Germany<br />
https://www.openstreetmap.org/#map=19/49.45960/11.08203&layers=N <br />
<br />
== Topics ==<br />
Making it easier to setup a development environment and start working on KDE software: https://phabricator.kde.org/T8484<br />
<br />
==Where to stay==<br />
A nearby hotel will be provided free of charge (currently in the planning stages).<br />
<br />
==Attendance==<br />
Please add your name to the table below if you're coming, along with arrival and departure dates.<br />
<br />
{| class="wikitable"<br />
|-<br />
! Name<br />
! Arrival<br />
! Leaving<br />
! Accomodation<br />
|-<br />
|Neofytos Kolokotronis<br />
| 20th<br />
| 24th<br />
| <br />
|-<br />
|-<br />
| Aleix Pol<br />
| 19th<br />
| 24th<br />
| <br />
|-<br />
| Filip Fila<br />
| 21st (20:40)<br />
| 23rd (23:05)<br />
| <br />
|-<br />
|Boudewijn Rempt<br />
| 19th<br />
| 24th<br />
|<br />
|-<br />
|Dmitry Kazakov<br />
| 19th<br />
| 24th<br />
|<br />
|-<br />
|David Faure<br />
|19th<br />
|23nd (14:50)<br />
|<br />
|-<br />
|Harald Sitter<br />
|21th<br />
|24th<br />
|<br />
|-<br />
|Piyush Aggarwal<br />
|19th<br />
|23rd<br />
|<br />
|-<br />
|Simon Redman<br />
| (KDE Connect)<br />
| 23 July @ 09:40<br />
| Hotel (Already paid)<br />
|-<br />
|Weixuan Xiao<br />
|19th<br />
|23rd<br />
|<br />
|-<br />
|Albert Astals Cid (potentially)<br />
|21st<br />
|24th<br />
|???<br />
|-<br />
|David Redondo<br />
|22nd<br />
|23rd<br />
|<br />
|-<br />
<br />
|}<br />
<br />
== Travel reimbursement ==<br />
https://reimbursements.kde.org/events/98<br />
<br />
==Communication==<br />
Matrix channel: #kde-onboarding-sprint:kde.org</div>Dfaurehttps://community.kde.org/index.php?title=Sprints/Onboarding/2019&diff=84539Sprints/Onboarding/20192019-05-20T07:21:18Z<p>Dfaure: </p>
<hr />
<div>===Streamlined Onboarding Sprint 2019===<br />
This is the planning page for the [https://phabricator.kde.org/T7116 Streamlined Onboarding] goal 2019 development sprint. Note that we plan to hold it directly after the [https://community.kde.org/Sprints/KDE_Connect/2019 KDE Connect 2019 sprint], at the same place.<br />
<br />
Dates: Monday 2019-07-22 - Tuesday 2019-07-23<br />
<br />
Location: Suse offices, Nuremberg, Germany<br />
https://www.openstreetmap.org/#map=19/49.45960/11.08203&layers=N <br />
<br />
== Topics ==<br />
Making it easier to setup a development environment and start working on KDE software: https://phabricator.kde.org/T8484<br />
<br />
==Where to stay==<br />
A nearby hotel will be provided free of charge (currently in the planning stages).<br />
<br />
==Attendance==<br />
Please add your name to the table below if you're coming, along with arrival and departure dates.<br />
<br />
{| class="wikitable"<br />
|-<br />
! Name<br />
! Arrival<br />
! Leaving<br />
! Accomodation<br />
|-<br />
|Neofytos Kolokotronis<br />
| 20th<br />
| 24th<br />
| <br />
|-<br />
|-<br />
| Aleix Pol<br />
| 19th<br />
| 24th<br />
| <br />
|-<br />
| Filip Fila<br />
| <br />
| <br />
| <br />
|-<br />
|Boudewijn Rempt<br />
| 19th<br />
| 24th<br />
|<br />
|-<br />
|Dmitry Kazakov<br />
| <br />
| <br />
|<br />
|-<br />
|David Faure<br />
|21th afternoon (to be confirmed)<br />
|23nd end-of-afternoon (to be confirmed)<br />
|<br />
|-<br />
|Harald Sitter<br />
|21th<br />
|24th<br />
|<br />
|-<br />
|Piyush Aggarwal<br />
|19th<br />
|23rd<br />
|<br />
|-<br />
|Simon Redman<br />
| (KDE Connect)<br />
| 23 July @ 09:40<br />
| Hotel (Already paid)<br />
|-<br />
|Weixuan Xiao<br />
|19th<br />
|23rd<br />
|<br />
|-<br />
|Albert Astals Cid (potentially)<br />
|21st<br />
|24th<br />
|???<br />
|-<br />
<br />
|}<br />
<br />
== Travel reimbursement ==<br />
https://reimbursements.kde.org/events/98<br />
<br />
==Communication==<br />
Matrix channel: #kde-onboarding-sprint:kde.org</div>Dfaurehttps://community.kde.org/index.php?title=Sprints/Onboarding/2019&diff=84041Sprints/Onboarding/20192019-05-15T13:26:27Z<p>Dfaure: /* Attendance */</p>
<hr />
<div>===Streamlined Onboarding Sprint 2019===<br />
This is the planning page for the [https://phabricator.kde.org/T7116 Streamlined Onboarding] goal 2019 development sprint. Note that we plan to hold it directly after the [https://community.kde.org/Sprints/KDE_Connect/2019 KDE Connect 2019 sprint], at the same place.<br />
<br />
Dates: Monday 2019-07-22 - Tuesday 2019-07-23<br />
<br />
Location: Suse offices, Nuremberg, Germany<br />
https://www.openstreetmap.org/#map=19/49.45960/11.08203&layers=N <br />
<br />
== Topics ==<br />
Making it easier to setup a development environment and start working on KDE software: https://phabricator.kde.org/T8484<br />
<br />
==Where to stay==<br />
A nearby hotel will be provided free of charge (currently in the planning stages).<br />
<br />
==Attendance==<br />
Please add your name to the table below if you're coming, along with arrival and departure dates.<br />
<br />
{| class="wikitable"<br />
|-<br />
! Name<br />
! Arrival<br />
! Leaving<br />
! Accomodation<br />
|-<br />
|Neofytos Kolokotronis<br />
| <br />
| <br />
| <br />
|-<br />
|-<br />
| Aleix Pol<br />
| 19th<br />
| 24th<br />
| <br />
|-<br />
| Filip Fila<br />
| <br />
| <br />
| <br />
|-<br />
|Bhavisha Dhruve<br />
|<br />
|<br />
|<br />
|-<br />
|Boudewijn Rempt<br />
|<br />
|<br />
|<br />
|-<br />
|David Faure<br />
|20th afternoon (to be confirmed)<br />
|22nd end-of-afternoon (to be confirmed)<br />
|<br />
|-<br />
|Harald Sitter (maybe)<br />
|<br />
|<br />
|<br />
|-<br />
|Piyush Aggarwal<br />
|<br />
|<br />
|<br />
|-<br />
|Simon Redman<br />
| (KDE Connect)<br />
| 23 July @ 09:40<br />
| Hotel (Already paid)<br />
|-<br />
|Weixuan Xiao<br />
|<br />
|<br />
|<br />
|-<br />
|Albert Astals Cid (potentially)<br />
|21st<br />
|24th<br />
|???<br />
|-<br />
<br />
|}<br />
<br />
== Travel reimbursement ==<br />
To become available once this event is finalized.<br />
<br />
==Communication==<br />
Matrix channel: #kde-onboarding-sprint:kde.org</div>Dfaurehttps://community.kde.org/index.php?title=Sprints/Onboarding/2019&diff=84039Sprints/Onboarding/20192019-05-15T11:19:47Z<p>Dfaure: /* Attendance */</p>
<hr />
<div>===Streamlined Onboarding Sprint 2019===<br />
This is the planning page for the [https://phabricator.kde.org/T7116 Streamlined Onboarding] goal 2019 development sprint. Note that we plan to hold it directly after the [https://community.kde.org/Sprints/KDE_Connect/2019 KDE Connect 2019 sprint], at the same place.<br />
<br />
Dates: Monday 2019-07-22 - Tuesday 2019-07-23<br />
<br />
Location: Suse offices, Nuremberg, Germany<br />
https://www.openstreetmap.org/#map=19/49.45960/11.08203&layers=N <br />
<br />
== Topics ==<br />
Making it easier to setup a development environment and start working on KDE software: https://phabricator.kde.org/T8484<br />
<br />
==Where to stay==<br />
A nearby hotel will be provided free of charge (currently in the planning stages).<br />
<br />
==Attendance==<br />
Please add your name to the table below if you're coming, along with arrival and departure dates.<br />
<br />
{| class="wikitable"<br />
|-<br />
! Name<br />
! Arrival<br />
! Leaving<br />
! Accomodation<br />
|-<br />
|Neofytos Kolokotronis<br />
| <br />
| <br />
| <br />
|-<br />
|-<br />
| Aleix Pol<br />
| 19th<br />
| 24th<br />
| <br />
|-<br />
| Filip Fila<br />
| <br />
| <br />
| <br />
|-<br />
|Bhavisha Dhruve<br />
|<br />
|<br />
|<br />
|-<br />
|Boudewijn Rempt<br />
|<br />
|<br />
|<br />
|-<br />
|David Faure<br />
|<br />
|<br />
|<br />
|-<br />
|Harald Sitter (maybe)<br />
|<br />
|<br />
|<br />
|-<br />
|Piyush Aggarwal<br />
|<br />
|<br />
|<br />
|-<br />
|Simon Redman<br />
| (KDE Connect)<br />
| 23 July @ 09:40<br />
| Hotel (Already paid)<br />
|-<br />
|Weixuan Xiao<br />
|<br />
|<br />
|<br />
|-<br />
|Albert Astals Cid (potentially)<br />
|<br />
|<br />
|<br />
|-<br />
<br />
|}<br />
<br />
== Travel reimbursement ==<br />
To become available once this event is finalized.<br />
<br />
==Communication==<br />
Matrix channel: #kde-onboarding-sprint:kde.org</div>Dfaurehttps://community.kde.org/index.php?title=KDEConnect&diff=83787KDEConnect2019-04-22T15:41:09Z<p>Dfaure: Use -I to prepend, in case there's a DROP rule. Fix syntax error "iptables v1.6.2: Can't use -i with OUTPUT"</p>
<hr />
<div><languages /><br />
<translate><br />
This is the community page for KDE Connect. Feel free to edit it! It should contain useful and up to date resources for both users and developers.<br />
<br />
== What is KDE Connect? ==<br />
<br />
KDE Connect is a project that enables all your devices to communicate with each other. Here's a few things KDE Connect can do:<br />
* Receive your phone notifications on your desktop computer and reply to messages<br />
* Control music playing on your desktop from your phone<br />
* Use your phone as a remote control for your desktop<br />
* Run predefined commands on your PC from connected devices. See the list of [https://userbase.kde.org/KDE_Connect/Tutorials/Useful_commands example commands] for more details.<br />
* Check your phones battery level from the desktop<br />
* Ring your phone to help finding it<br />
* Share files and links between devices<br />
* Browse your phone from the desktop<br />
* Control the desktop's volume from the phone<br />
<br />
<br />
To achieve this, KDE Connect:<br />
* implements a secure communication protocol over the network, and allows any developer to create plugins on top of it.<br />
* Has a component that you install on your desktop.<br />
* Has a KDE Connect client app you run on your phone.<br />
<br />
<br />
This video from 2013 demonstrates some other cool features: https://www.youtube.com/watch?v=KkCFngNmsh0<br />
<br />
More info at [http://albertvaka.wordpress.com Albert Vaka's] or [http://nicolasfella.wordpress.com Nico's] blog.<br />
<br />
== Installation ==<br />
<br />
You will most likely find the KDE Connect desktop component as a package in your distribution's repos. If not you can ask them to package it.<br />
<br />
Despite a common misconception you can use KDE Connect on all desktop environments. Since most of the developers are using Plasma it may occur that a feature is broken or inaccessible on other desktop environments. In this case, please report it as a [https://bugs.kde.org/enter_bug.cgi?product=kdeconnect bug]. There are multiple ways to enhance the KDE Connect experience on non-Plasma desktops. If you are a GNOME user you might prefer [https://extensions.gnome.org/extension/1319/gsconnect/ GSConnect], a GNOME shell extension. For desktops with AppIndicator support (Budgie, Cinnamon, LXDE, Pantheon, Unity) [https://github.com/Bajoja/indicator-kdeconnect indicator-kdeconnect] is available.<br />
<br />
The app for Android can be found in both the [https://play.google.com/store/apps/details?id=org.kde.kdeconnect_tp Google Play Store] and the free and open store [https://f-droid.org/repository/browse/?fdid=org.kde.kdeconnect_tp F-Droid].<br />
<br />
There was some development of a KDE Connect client app for iOS in 2014 (see [https://cgit.kde.org/scratch/yangqiao/kdeconnect-ios.git/ source code]) but due to our experience and various technical and organizational factors it's unlikely that we will have official iOS support anytime soon.<br />
<br />
KDE Connect is also available on [https://openrepos.net/content/piggz/kde-connect SailfishOS] and we are working on bringing it to other Linux-based phones (Plasma Mobile, PostmarketOS etc.)<br />
<br />
== Browser Integration ==<br />
<br />
[https://community.kde.org/Plasma/Browser_Integration Plasma Browser Integration] makes KDE Connect even more powerful. It allows you to control content from e.g. Youtube or Netflix from your phone and send browser tabs to your phone. Despite the name it can also be used on non-Plasma desktops.<br />
<br />
== Running KDE Connect over OpenVPN ==<br />
There may be a variety of reasons for using KDE Connect with a VPN. Maybe you have left home and want to run a command or maybe you’re on a public wifi network where your devices aren’t allowed to communicate and you want to use remote control to give a presentation.<br />
<br />
=== Set up Open VPN ===<br />
If you have your own server with a public-facing IP address, you can set up OpenVPN yourself. OpenVPN is not the easiest piece of software to set up, but by following a setup tutorial such as this one, you should be able to manage: https://openvpn.net/howto.html<br />
<br />
In order to allow UDP broadcast packets, which are what KDE Connect uses to automatically discover two devices, OpenVPN needs to be set up for bridging (TAP device). If you use a tun device, you can still manually connect by IP address.<br />
<br />
If you want to rent a pre-configured OpenVPN service rather than set up your own it should work, but the same considerations about the server settings need to be taken into account.<br />
<br />
Once the server is running, you can use the official OpenVPN client to connect the desktop to the server. There is no official OpenVPN client for Android, but I find that the OpenVPN for Android client works well: https://play.google.com/store/apps/details?id=de.blinkt.openvpn<br />
<br />
Once both devices are connected, test that they are able to communicate over the VPN by trying to do a network ping between them.<br />
<br />
=== Configure KDE Connect ===<br />
If your OpenVPN instance is set up for bridging, KDE Connect should work just like on a local network<br />
<br />
If you are using OpenVPN with a tun device, you will have to manually add your devices by IP. Then, once you connect to the VPN, KDE Connect should automatically detect your device and either connect or be ready for pairing!<br />
<br />
== Building KDE Connect ==<br />
=== Linux Desktop ===<br />
If you want to build KDE Connect yourself, you'll first need to grab the code from git. <br />
<syntaxhighlight lang="bash"><br />
git clone https://invent.kde.org/kde/kdeconnect-kde.git<br />
</syntaxhighlight><br />
KDE Connect uses cmake as a build system, which will tell you if you are missing any dependencies. On some distros you will need to install some development packages. On Ubuntu you can use <code>sudo apt-get build-dep kdeconnect</code> to install all build dependencies. On openSUSE you can use <code>sudo zypper si -d kdeconnect-kde</code>.<br />
<br />
To configure use<br />
<syntaxhighlight lang="bash"><br />
cd kdeconnect-kde<br />
mkdir build<br />
cd build<br />
cmake -DCMAKE_INSTALL_PREFIX=/usr ..<br />
</syntaxhighlight><br />
To build use<br />
<syntaxhighlight lang="bash"><br />
make<br />
sudo make install<br />
</syntaxhighlight><br />
Note that this will override the KDE Connect provided by your distro<br />
<br />
If you are intending to develop KDE Connect or experience a crash and are asked to give a backtrace, build KDE Connect with debugging symbols:<br />
<syntaxhighlight lang="bash"><br />
cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Debug ..<br />
</syntaxhighlight><br />
If you don't want to override your distros KDE Connect choose another prefix than /usr. To temporarily run the newly installed KDE Connect run <code>source prefix.sh</code> from the build directory. <br />
If you install KDE Connect in a custom location you'll need to run <code>kdeconnectd</code> manually, since DBus doesn't know about it.<br />
<br />
For instruction on how to integrate the build with KDevelop check out this [https://nicolasfella.wordpress.com/2018/03/30/building-kde-connect/ blog post]<br />
<br />
=== Android ===<br />
You can find the code at git://anongit.kde.org/kdeconnect-android.git. It's easiest to use Android Studio to build the app and install it to your phone, although it can be done on the command line using gradle.<br />
<br />
Running KDE Connect in the emulator is possible, but needs an advanced networking setup. See the guide posted for the [[/Android_Emulator/]]<br />
<br />
=== Windows ===<br />
KDE Connect works quite well on Windows, with many features ported.<br />
See [https://community.kde.org/KDEConnect/Build_Windows here] for build instructions<br />
<br />
=== MacOS ===<br />
KDE Connect works basically on macOS. But it is an experimental build. There is not an official release for it. You can try KDE Connect with this build guide.<br />
See [https://community.kde.org/KDEConnect/Build_MacOS here] for build instructions.<br />
<br />
=== Mobile-Friendly QML App ===<br />
KDE Connect provides on alternative mobile-friendly interface, targeted at mobile Linux platforms such as Plasma Mobile. The app is usable on the desktop as well. It is built from the same sources as the desktop component. The build steps are mostly the same, just one additional step is needed to enable building the app.<br />
<br />
<syntaxhighlight lang="bash"><br />
cd build<br />
cmake -DEXPERIMENTALAPP_ENABLED=True .<br />
</syntaxhighlight><br />
<br />
This will result in an additional 'kcapp' executable being built<br />
<br />
=== Desktop SMS Messaging App (Pre-beta) ===<br />
KDE Connect is working on releasing an SMS Messaging app which will let you type and view SMS messages from your computer. It is not ready for release and doesn't work correctly all the time, but it is also good enough to be useful. If you are interested in trying it or developing it, you can build it from source.<br />
<br />
A CMake flag is required to build the Messenger:<br />
<syntaxhighlight lang="bash"><br />
cd build<br />
cmake -DSMSAPP_ENABLED=True .<br />
</syntaxhighlight><br />
<br />
This will result in an additional 'kdeconnect-sms' executable being built<br />
<br />
== Troubleshooting ==<br />
<br />
=== I have two devices running KDE Connect on the same network, but they can't see each other === <br />
KDE Connect uses dynamic ports in the range 1714-1764 for UDP and TCP. So if you are behind a firewall, make sure to open this port range for both TCP and UDP. Otherwise, make sure your network is not blocking UDP broadcast packets.<br />
<br />
==== ufw ====<br />
<br />
If your firewall is '''ufw''', you can open the necessary ports with:<br />
<br />
<syntaxhighlight lang="bash"><br />
sudo ufw allow 1714:1764/udp<br />
sudo ufw allow 1714:1764/tcp<br />
sudo ufw reload<br />
</syntaxhighlight><br />
<br />
==== firewalld ====<br />
<br />
If your firewall is '''firewalld''', you can open the necessary ports with:<br />
<br />
<syntaxhighlight lang="bash"><br />
sudo firewall-cmd --zone=public --permanent --add-port=1714-1764/tcp<br />
sudo firewall-cmd --zone=public --permanent --add-port=1714-1764/udp<br />
sudo systemctl restart firewalld.service<br />
</syntaxhighlight><br />
<br />
==== Fedora firewall ====<br />
In Fedora there is a program to configure the firewall. Open Firewall Configuration (the program's filename is <code>firewall-config</code>), and in '''Zones''' ➔ '''Services''' check the kde-connect service.<br />
<br />
Make sure you have chosen the '''Permanent''' Configuration in the drop-down at the top, otherwise these settings will be reset upon reboot.<br />
<br />
==== iptables ====<br />
<br />
<br />
If your firewall is '''iptables''', you can open the necessary ports with:<br />
<br />
<syntaxhighlight lang="bash"><br />
sudo iptables -I INPUT -i <yourinterface> -p udp --dport 1714:1764 -m state --state NEW,ESTABLISHED -j ACCEPT<br />
sudo iptables -I INPUT -i <yourinterface> -p tcp --dport 1714:1764 -m state --state NEW,ESTABLISHED -j ACCEPT<br />
<br />
sudo iptables -A OUTPUT -o <yourinterface> -p udp --sport 1714:1764 -m state --state NEW,ESTABLISHED -j ACCEPT<br />
sudo iptables -A OUTPUT -o <yourinterface> -p tcp --sport 1714:1764 -m state --state NEW,ESTABLISHED -j ACCEPT<br />
</syntaxhighlight><br />
<br />
=== My KDE Connect crashes or restarts when trying to pair with another device ===<br />
Sometimes, a corrupt config file may cause KDE Connect to crash when trying to pair with a device. In that case, deleting the config ~/.config/kdeconnect might help.<br />
<br />
=== Can I run KDE Connect without a display server? === <br />
Yes, you can pass the command line argument `-platform offscreen` to the daemon (eg: `killall -9 kdeconnectd; /usr/lib/libexec/kdeconnectd -platform offscreen`)<br />
<br />
=== Running kdeconnect on an emulator ===<br />
How to setup running kdeconnect on an emulator is described here [[/Android_Emulator/]]<br />
<br />
=== GSConnect ===<br />
GSConnect is an independent project which implements the KDE Connect protocol and uses the same Android app. If you are running GSConnect, please visit that project's [https://github.com/andyholmes/gnome-shell-extension-gsconnect/wiki GitHub page] first for support. If you and the GSConnect team determine the issue is the Android app or protocol, feel free to report those in the KDE Connect bug tracker.<br />
<br />
=== My problem is not in this list :( === <br />
In case you find a bug and want to report it, you can do so in the [https://bugs.kde.org/enter_bug.cgi?product=kdeconnect KDE bug tracker].<br />
<br />
== Development ==<br />
NOTE: KDE Connect is in process of moving from Phabricator to GitLab. Focus any new contributions on GitLab. This wiki will be updated as we figure out the GitLab workflow.<br />
<br />
KDE Connect is a perfect project to start contributing to KDE. You'll need a basic understanding of programming concepts, the rest can be learned by doing. Experience with Android or Qt is beneficial, but not needed.<br />
<br />
We have a group to discuss development. You can access it from [https://t.me/joinchat/BRUUN0bwMhNfn8FIejA-nw Telegram], IRC (#kdeconnect) or matrix.org (#freenode_#kdeconnect:matrix.org). Feel free to ask any development related questions there. We also have a [https://mail.kde.org/mailman/listinfo/kdeconnect mailing list].<br />
<br />
You can submit patches on our [https://phabricator.kde.org/project/view/159/ Phabricator]. [https://community.kde.org/Infrastructure/Phabricator This wiki page] has more details on how this process works. For the reviewer, put in #kde_connect. Should this be your first patch, it's good to know that it might take some time before your patch is reviewed (we all work on KDE Connect in our free time), and you'll probably have to make some changes a couple of times. That's not because you're new, that's what happens for all reviews (even for long-time contributors).<br />
<br />
There are a couple of tasks marked as Junior Jobs on our [https://phabricator.kde.org/project/board/159/ workboard]. Those have some extra information on how to approach them that help you get started.<br />
<br />
=== Setting up KDE Connect Repository for Development ===<br />
<br />
KDE Connect is actually composed of two repositories; one for the Android implementation and one for the C++ (Desktop) implementation. You can have a local clone of both on your computer and the steps to set them up are the same. For these directions, I will use the C++ repository, but if you want the Android repository, just replace every instance of 'kdeconnect-kde' with 'kdeconnect-android'<br />
<br />
# Fork the repository<br />
#* With your web browser, open the Web GUI to KDE Connect's GitLab: https://invent.kde.org/kde/kdeconnect-kde<br />
#* If you are not already, sign in with your KDE identity by clicking the "Sign In" button in the top left<br />
#* Click the "Fork" Button, near the top right<br />
#* Wait for the forking to complete<br />
# Clone your fork<br />
#* Open your new fork in the GitLab web GUI<br />
#* Click the "Clone" button in the top right<br />
#* Select the method of cloning<br />
#** I recommend SSH. This will require you add an SSH public key to you KDE GitLab account.<br />
#** An HTTPS clone will require you to log in with your KDE Identity credentials to push changes.<br />
#* In the folder you want to clone, do 'git clone <cloning path from above>'<br />
<br />
You are all set up! See the optional steps for ways to make life easier.<br />
<br />
==== Set up second remote (Optional) ====<br />
Having a second remote allows you to have your local 'master' branch track the upstream kdeconnect-kde master branch, so you can easily get all the latest changes.<br />
<br />
These steps assume you are using command-line git. If you are using a GUI tool, the steps will be different, but the ideas will be the same.<br />
<br />
# On the command line, change to your local repository clone<br />
# Execute:<br />
<syntaxhighlight lang="bash"><br />
# Note that we use HTTPS cloning here so that you don't need a verified account to pull changes!<br />
git remote add upstream https://invent.kde.org/kde/kdeconnect-kde.git<br />
git fetch upstream<br />
git checkout -b upstream-master --track upstream/master<br />
</syntaxhighlight><br />
# Now whenever there are new changes upstream, simply pull the upstream-master branch, then merge or rebase your local branches onto those changes!<br />
<br />
===Development tips===<br />
<br />
====Restarting the daemon====<br />
Whenever you do a change to KDE Connect you need to restart the daemon for the change to take effect. <br />
<syntaxhighlight lang="bash"><br />
killall kdeconnectd<br />
build/bin/kdeconnectd<br />
</syntaxhighlight><br />
<br />
====DBus inspection====<br />
The daemon communicates with various UI components (Plasmoid, CLI, Indicator etc.) over DBus. QDbusViewer allows inspecting the DBus interface provided by the daemon which can be incredibly useful for debugging.<br />
<br />
</translate></div>Dfaurehttps://community.kde.org/index.php?title=Frameworks/CreationGuidelines&diff=83734Frameworks/CreationGuidelines2019-04-15T21:18:57Z<p>Dfaure: </p>
<hr />
<div>= Guidelines for creating a new framework =<br />
<br />
If you are creating a new framework, this checklist can help you get it done correctly:<br />
* Make sure it follows all the [[Frameworks/Policies|active policies]]<br />
* The above includes many important things, make sure to read all of it. E.g. it includes the often forgotten [[Frameworks/Frameworks_Localization_Policy#KI18n_installation_code|rule for installing translations]]<br />
* If it is created by splitting code from an existing repository, the new repository should be created by using a script to create a graft point<br />
* Run astyle-kdelibs or uncrustify-kf5 (both are part of kde-dev-scripts)<br />
* Ensure the module doesn't depend on deprecated or "portingAid" frameworks like kdelibs4support<br />
* Ensure the module is in frameworks on projects.kde.org (the source information is in the repo kde:sysadmin/repo-metadata), otherwise ask for it to be moved there (https://go.kde.org/systickets)<br />
* Adjust kde:kde-build-metadata - in particular, add it to the deps for frameworks/kf5umbrella<br />
* Get the CI jobs set up<br />
** Get the job set up on build.kde.org by filing a task towards https://phabricator.kde.org/tag/build.kde.org/<br />
** Make sure to request it to be added to the relevant view: http://build.kde.org/view/Frameworks%20kf5-qt5/ view <br />
** Ensure it is green<br />
* Add a new product for it on bugs.kde.org, which must be called frameworks-<name><br />
* Create a README.md file<br />
* Finally when it's all ready, change the yaml file to say release: true. The release scripts will then pick it up automatically for the next KF release.<br />
<br />
== Template ==<br />
<br />
The [http://quickgit.kde.org/?p=kdeexamples.git&a=tree&f=framework-template framework-template] directory in the kdeexamples repository has a setup.sh script that generates a helpful skeleton framework that is a good starting point for creating a framework. For example, if you were creating the KConfig framework, you might run<syntaxhighlight lang="bash"><br />
./setup.sh KConfig ../../kconfig <br />
</syntaxhighlight><br />
then go to the newly created "kconfig" directory and start adding source files etc.</div>Dfaurehttps://community.kde.org/index.php?title=Sprints/PIM/2019&diff=83631Sprints/PIM/20192019-04-07T13:14:16Z<p>Dfaure: /* Restaurants */</p>
<hr />
<div>=Venue=<br />
<br />
Etincelle Coworking<br />
<br />
Friday location : 2 Rue d'Austerlitz, 31000 Toulouse<br />
As a good marker point you have the Wilson Parc or the Jean Jaures metro station super close.<br />
<br />
For importing into KDE Itinerary:<br />
{<br />
"@context": "http://schema.org",<br />
"@type": "EventReservation",<br />
"reservationFor": {<br />
"@type": "Event",<br />
"name": "KDE PIM Sprint 2019",<br />
"startDate": "2019-04-05T14:00:00+02:00",<br />
"endDate": "2019-04-07T18:00:00+02:00",<br />
"location": {<br />
"@type": "Place",<br />
"name": "Etincelle Coworking",<br />
"address": {<br />
"@type": "PostalAddress",<br />
"addressCountry": "FR",<br />
"addressLocality": "Toulouse",<br />
"postalCode": "31000",<br />
"streetAddress": "2 Rue d'Austerlitz"<br />
}<br />
}<br />
}<br />
}<br />
<br />
Saturday location: 36 rue Alsace Lorraine.<br />
<br />
=Sprint Schedule=<br />
April 5/6/7, 2019<br />
<br />
=Travel Reimbursement=<br />
File a request on https://reimbursements.kde.org/events/89<br />
The hotel is € 113.30 for two nights.<br />
<br />
=Attendance=<br />
<br />
* David Faure<br />
* Volker Krause<br />
* Kevin Ottens<br />
* Franck Arrecot<br />
* Dan Vratil<br />
<br />
=Hotel=<br />
<br />
[http://www.occitania-toulouse-matabiau.com/en/ Hôtel Occitania Centre Toulouse Matabiau]<br />
<br />
For importing into KDE Itinerary:<br />
{<br />
"@context": "http://schema.org",<br />
"@type": "LodgingReservation",<br />
"checkinDate": "2019-04-05T15:00:00+02:00",<br />
"checkoutDate": "2019-04-07T10:00:00+02:00",<br />
"reservationFor": {<br />
"@type": "LodgingBusiness",<br />
"address": {<br />
"@type": "PostalAddress",<br />
"addressCountry": "FR",<br />
"addressLocality": "Toulouse",<br />
"postalCode": "31000",<br />
"streetAddress": "7 Boulevard Bonrepos"<br />
},<br />
"geo": {<br />
"@type": "GeoCoordinates",<br />
"latitude": 43.6101706,<br />
"longitude": 1.4526995<br />
},<br />
"name": "Hôtel Occitania Toulouse Matabiau"<br />
}<br />
}<br />
<br />
=Arrival and departure times=<br />
<br />
* David: arriving 20:14 on 5 April (by train), departing 14:48 on 7 April (by train).<br />
* Volker: arriving ~noon on 5 April, departing ~18:00 on 7 April<br />
* Dan: arriving with Volker, departing probably with Volker as well (18:20 on Sunday)<br />
<br />
=Restaurants=<br />
* Friday dinner: https://www.restoyeti.com/<br />
* Saturday lunch: https://www.latelierduburger.com/carte<br />
* Saturday dinner: http://www.katana-toulouse.fr/<br />
* Sunday lunch: bagels<br />
<br />
=Report=<br />
<br />
Draft of report : https://notes.kde.org/p/KDE-PIM-Sprint-2019</div>Dfaurehttps://community.kde.org/index.php?title=Sprints/PIM/2019&diff=83630Sprints/PIM/20192019-04-07T13:13:36Z<p>Dfaure: /* Restaurants */</p>
<hr />
<div>=Venue=<br />
<br />
Etincelle Coworking<br />
<br />
Friday location : 2 Rue d'Austerlitz, 31000 Toulouse<br />
As a good marker point you have the Wilson Parc or the Jean Jaures metro station super close.<br />
<br />
For importing into KDE Itinerary:<br />
{<br />
"@context": "http://schema.org",<br />
"@type": "EventReservation",<br />
"reservationFor": {<br />
"@type": "Event",<br />
"name": "KDE PIM Sprint 2019",<br />
"startDate": "2019-04-05T14:00:00+02:00",<br />
"endDate": "2019-04-07T18:00:00+02:00",<br />
"location": {<br />
"@type": "Place",<br />
"name": "Etincelle Coworking",<br />
"address": {<br />
"@type": "PostalAddress",<br />
"addressCountry": "FR",<br />
"addressLocality": "Toulouse",<br />
"postalCode": "31000",<br />
"streetAddress": "2 Rue d'Austerlitz"<br />
}<br />
}<br />
}<br />
}<br />
<br />
Saturday location: 36 rue Alsace Lorraine.<br />
<br />
=Sprint Schedule=<br />
April 5/6/7, 2019<br />
<br />
=Travel Reimbursement=<br />
File a request on https://reimbursements.kde.org/events/89<br />
The hotel is € 113.30 for two nights.<br />
<br />
=Attendance=<br />
<br />
* David Faure<br />
* Volker Krause<br />
* Kevin Ottens<br />
* Franck Arrecot<br />
* Dan Vratil<br />
<br />
=Hotel=<br />
<br />
[http://www.occitania-toulouse-matabiau.com/en/ Hôtel Occitania Centre Toulouse Matabiau]<br />
<br />
For importing into KDE Itinerary:<br />
{<br />
"@context": "http://schema.org",<br />
"@type": "LodgingReservation",<br />
"checkinDate": "2019-04-05T15:00:00+02:00",<br />
"checkoutDate": "2019-04-07T10:00:00+02:00",<br />
"reservationFor": {<br />
"@type": "LodgingBusiness",<br />
"address": {<br />
"@type": "PostalAddress",<br />
"addressCountry": "FR",<br />
"addressLocality": "Toulouse",<br />
"postalCode": "31000",<br />
"streetAddress": "7 Boulevard Bonrepos"<br />
},<br />
"geo": {<br />
"@type": "GeoCoordinates",<br />
"latitude": 43.6101706,<br />
"longitude": 1.4526995<br />
},<br />
"name": "Hôtel Occitania Toulouse Matabiau"<br />
}<br />
}<br />
<br />
=Arrival and departure times=<br />
<br />
* David: arriving 20:14 on 5 April (by train), departing 14:48 on 7 April (by train).<br />
* Volker: arriving ~noon on 5 April, departing ~18:00 on 7 April<br />
* Dan: arriving with Volker, departing probably with Volker as well (18:20 on Sunday)<br />
<br />
=Restaurants=<br />
Friday dinner: https://www.restoyeti.com/<br />
Saturday lunch: https://www.latelierduburger.com/carte<br />
Saturday dinner: http://www.katana-toulouse.fr/<br />
Sunday lunch: bagels<br />
<br />
=Report=<br />
<br />
Draft of report : https://notes.kde.org/p/KDE-PIM-Sprint-2019</div>Dfaurehttps://community.kde.org/index.php?title=Sprints/PIM/2019&diff=83629Sprints/PIM/20192019-04-07T08:38:56Z<p>Dfaure: </p>
<hr />
<div>=Venue=<br />
<br />
Etincelle Coworking<br />
<br />
Friday location : 2 Rue d'Austerlitz, 31000 Toulouse<br />
As a good marker point you have the Wilson Parc or the Jean Jaures metro station super close.<br />
<br />
For importing into KDE Itinerary:<br />
{<br />
"@context": "http://schema.org",<br />
"@type": "EventReservation",<br />
"reservationFor": {<br />
"@type": "Event",<br />
"name": "KDE PIM Sprint 2019",<br />
"startDate": "2019-04-05T14:00:00+02:00",<br />
"endDate": "2019-04-07T18:00:00+02:00",<br />
"location": {<br />
"@type": "Place",<br />
"name": "Etincelle Coworking",<br />
"address": {<br />
"@type": "PostalAddress",<br />
"addressCountry": "FR",<br />
"addressLocality": "Toulouse",<br />
"postalCode": "31000",<br />
"streetAddress": "2 Rue d'Austerlitz"<br />
}<br />
}<br />
}<br />
}<br />
<br />
Saturday location: 36 rue Alsace Lorraine.<br />
<br />
=Sprint Schedule=<br />
April 5/6/7, 2019<br />
<br />
=Travel Reimbursement=<br />
File a request on https://reimbursements.kde.org/events/89<br />
The hotel is € 113.30 for two nights.<br />
<br />
=Attendance=<br />
<br />
* David Faure<br />
* Volker Krause<br />
* Kevin Ottens<br />
* Franck Arrecot<br />
* Dan Vratil<br />
<br />
=Hotel=<br />
<br />
[http://www.occitania-toulouse-matabiau.com/en/ Hôtel Occitania Centre Toulouse Matabiau]<br />
<br />
For importing into KDE Itinerary:<br />
{<br />
"@context": "http://schema.org",<br />
"@type": "LodgingReservation",<br />
"checkinDate": "2019-04-05T15:00:00+02:00",<br />
"checkoutDate": "2019-04-07T10:00:00+02:00",<br />
"reservationFor": {<br />
"@type": "LodgingBusiness",<br />
"address": {<br />
"@type": "PostalAddress",<br />
"addressCountry": "FR",<br />
"addressLocality": "Toulouse",<br />
"postalCode": "31000",<br />
"streetAddress": "7 Boulevard Bonrepos"<br />
},<br />
"geo": {<br />
"@type": "GeoCoordinates",<br />
"latitude": 43.6101706,<br />
"longitude": 1.4526995<br />
},<br />
"name": "Hôtel Occitania Toulouse Matabiau"<br />
}<br />
}<br />
<br />
=Arrival and departure times=<br />
<br />
* David: arriving 20:14 on 5 April (by train), departing 14:48 on 7 April (by train).<br />
* Volker: arriving ~noon on 5 April, departing ~18:00 on 7 April<br />
* Dan: arriving with Volker, departing probably with Volker as well (18:20 on Sunday)<br />
<br />
=Restaurants=<br />
<br />
Saturday lunch: https://www.latelierduburger.com/carte<br />
<br />
=Report=<br />
<br />
Draft of report : https://notes.kde.org/p/KDE-PIM-Sprint-2019</div>Dfaure