These changes are necessary because of changing the compilation
process for the gui from a single executable to static lib +
executable in commit 0521dce174.
Otherwise the version and icon information will be lost.
Signed-off-by: Felix Weilbach <felix.weilbach@nextcloud.com>
on windos absolute path does not have to start with / . Remove failing assert
when editing ignored files list.
Signed-off-by: Matthieu Gallien <matthieu_gallien@yahoo.fr>
The content of notifications on MacOS are not allowed to contain HTML
tags in it. Linux (Free Desktop) notifications may contain HTML tags
in their content. However, it is optional that the notification daemon
interprets the tags. The GNOME notification daemon does not interpret
HTML tags and even does not strip them off. KDE's daemon interprets
the tags. For now I think it's the best solution to remove the HTML
tags. In the future we should fire a action if the user clicks on the
notification and react on it and open the link then. This should work
on all platforms. But as this change involves working with the native
MacOS api and I don't have hardware for that at the moment for that I
will postpone it.
Fixes#2200
Signed-off-by: Felix Weilbach <felix.weilbach@nextcloud.com>
- This information is retrieved from the notifications endpoint.
- Add icons for the different pre defined status.
- Make functions available to QML to decide which status icon to display.
- Display the user status icon on the avatar and
move the online/offline connection status to the folder icon.
Signed-off-by: Camila <hello@camila.codes>
To better see what is going on when and if files are removed by the
client.
See also: #260, #1433, #2913
Signed-off-by: Felix Weilbach <felix.weilbach@nextcloud.com>
The bug does seem to just appear in special compiler
constellations. We're unsure why this fix works. To better see if this
fix works or if crashes still occur, we added some logging.
Signed-off-by: Felix Weilbach <felix.weilbach@nextcloud.com>
We should not rely on the product name because it is something the
user can change in the theming options on the server.
Fixes#3001
Signed-off-by: Felix Weilbach <felix.weilbach@nextcloud.com>
This adjustment is necessary because of the changes of the new account
wizard that were introduced with:
e0b7ef15b2
Signed-off-by: Felix Weilbach <felix.weilbach@nextcloud.com>
If the get job got an authentication required error on the account url
(not davUrl! at that stage we always get auth error there), then it is
safe to assume basic auth is used on the server. It is then kind of
pointless to use any other auth mode they will necessarily fail. Only
basic auth will do the job so force it.
Signed-off-by: Kevin Ottens <kevin.ottens@enioka.com>
This is necessary to be able to distinguish between "I decided on basic
by default" and "I didn't write any auth type". To make sure all the
jobs end up writing something we then implement the "I decided on basic
by default" in the slots connected to the job and we assert it in
checkAllDone()
Signed-off-by: Kevin Ottens <kevin.ottens@enioka.com>
There were a couple of shibboleth related enums left, since that auth
method isn't supported anymore remove the code tied to those enums. It
was dead code anyway.
Signed-off-by: Kevin Ottens <kevin.ottens@enioka.com>
Customizing of the palette will prevent the settings dialog from
display a dark theme correct.
Fixes#2993
Signed-off-by: Felix Weilbach <felix.weilbach@nextcloud.com>
Refactoring of User::isValueableactivity() because of changes
introduced with merge commit f17c52d.
Signed-off-by: Felix Weilbach <felix.weilbach@nextcloud.com>
When the client runs and a conflict gets detected, the sync engine runs
two times.
On the first run, the sync engine detects the conflict, marks the
file as a conflict and propagates that to the GUI. This leads to an
error notification with the original filename in the main dialog.
The sync engine runs then a second time. On this second run, the file
that originally caused the conflict is not anymore a conflict
file. Instead, the sync engine detects the conflicted copy and
propagates that file as a conflict to the GUI.
When opening the conflict dialog with the original file name (not the
conflicted copy) a crash happens. Usually, the two sync runs are really
fast, so the user does not notice the first notification. However, a
problem can occur if a conflict gets created while the client is not
running. Since then, the client does not do two sync runs. It does only
run once.
Signed-off-by: Felix Weilbach <felix.weilbach@nextcloud.com>
Added the configuration options
confirmExternalStorage
crashReporter
newBigFolderSizeLimit
useNewBigFolderSizeLimit
to the Windows registry
Signed-off-by: Marco Hald <marcohald@users.noreply.github.com>
Indeed the path we have is supposedly not fully qualified in case of a
sync folder which doesn't point to / on the remote end. But LSCOL works
with absolute paths on the server so make sure this is what we give it
out.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
This got broken during the huge discovery refactoring. I wrongly passed
the mangled name as is out of discovery, but coming from listing jobs it
was fully qualified while the jobs at propagation time and the db expect
those paths to be relative to the remote folder.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
Otherwise they won't be loaded automatically at startup leading to lots
of missing icons. Since they're now in a static library they need that
explicit loading.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
The test utils library collects all dependencies that are needed for
tests and gets automatically linked with every test.
Signed-off-by: Felix Weilbach <felix.weilbach@t-online.de>
Compiling nextcoud gui as a separate library. This is needed to more
easily write tests. The whole nextcloud application can now be linked
against the tests.
Signed-off-by: Felix Weilbach <felix.weilbach@nextcloud.com>
I went full steam on making it all public which is not really required,
it's only really QtWebSockets we're after. Could always be fine tuned
later on if this works as expected.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
This would only happen if the parent of the newly created folder would
be explicitly set to online only, hence why it went under the radar
previously.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
This account object was really only used during the initialization phase
or for forgetting the sensitive data. So let's receive it as parameter
there and pass it on from job to job as needed.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
The OS might request the same file again if we take too much time to
fulfill a request. So in case it's queueing the same one again instead
of bailing out just fail the second one and let the first one finish
properly.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
In case we'd been to slow to fullfill or we're still processing a
cancelled request better not just crash. We still log the issue though.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
This got broken previously when trying to reconcile during a
cherry-pick. This also repairs the case when the theme tells us the
default is to not select anything (not that we're using this right now
but in case we'd like to brand this).
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
We now favor APPLICATION_ICON_SET to isBranded() regarding the decision
to use PNG or SVG for icons.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
Indeed, that file size will almost always change between the 1 byte
placeholder and the hydrated file. Only when using the CfAPI on Windows
this won't be the case since because it will expose the original size
even for placeholders.
Also worth noting: the suffix backend didn't hit that case since the
filename changes (with suffix for placeholders, without for hydrated
files).
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
Ideally this will end up being the backend we use for both Linux and
macOS but that will require work with desktop environments on the Linux
side and to reverse engineering at least on xattr value on macOS.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
There's been a confusion between the chunk number and the chunk
offset leading to corruptions... Let's pass the proper offset to
the UploadDevice again.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
MSVC having so useless error messages it didn't quite point to the root
cause of the issue... it turns out that through the maze of macros
defined in the windows API, there's one which impacted the function
pointer definition of CfCloseHandle which would then not convert to
FileHandle::Deleter as expected. So I end up wrapping it in a lambda to
help... luckily this kind of lambdas decay into a simple function
pointer so there's likely no overhead it's just to coerce the compiler
into doing the right thing.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
For some reason MSVC manages to deduce the right constructor in Win64
mode but not in Win32 mode. So let's be more explicit about what we
return.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
Otherwise this would attempt to download the file everytime we check the
direct editor for a given file which wouldn't be adequate. Would also
lead to a deadlock in our case since that would happen in the main
thread and implicit hydration is driven from there as well.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
This comes with a test simulating an open request coming from another
process (although in our case it's really just a thread). The actual
hydration works as expected by cfapi, handling of encrypted files is for
now missing.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
For now this implements only the logic necessary to get a test suite
equivalent to the TestSyncVirtualFiles one to pass. It doesn't (yet)
honor request to fetch files from the system.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
Shouldn't be translated.
Just checked https://en.wikipedia.org/wiki/HTTP_ETag and all available localized pages.
Signed-off-by: rakekniven <mark.ziegler@rakekniven.de>
We will have all the code in public anyway so it can just be compiled
in. Thus no need to go through the plugin loading dance. Replaced the
loading with factory functions. Kept mostly the same structure
otherwise.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
It felt odd to be able to control the encryption status in the settings
dialog but not the availability. Also availability was controllable on
the root, so let's make it widely available.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
This got removed from the settings since in that case selective sync
isn't supported. Unfortunately that's also necessary to display them to
allow encrypting folders via the context menu.
So we display the subfolders again but in the case of VFS we disable the
ability to (un)check them. They just have an icon, a name and a context
menu.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
Otherwise we would not display the E2EE message if the account was
connected before the creation of the settings dialog. This was likely
caused by the delayed creation of the settings dialog.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
If we use those encrypted propagation code paths, we already know from
the discovery phase (and thus the journal db) that the folders are
encrypted so no need to check again.
This will remove another expensive round trip with the server.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
This step isn't necessary anymore, no one looks at ClientSideEncryption
for that information anyway.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
We used the same approach than for the FolderStatusModel by getting the
is-encrypted property straight from the LSCOL job.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
Thanks to the new discovery algorithm, we got all the freshest E2EE
information straight from the database so reuse it instead of going
through an in memory copy.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
It had a different path convention than all the other jobs, most likely
for legacy reasons because of the tight coupling it had to the settings
dialog.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
No need to look for a token on the outside we can just work properly by
keeping all the state encapsulated in the job.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
Thanks to the new discovery algorithm we got both mangled and original
file names in the item so no need to go through the database for
nothing.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
Now we pull the encrypted metadata during the discovery which is a
better approach than before. This shall remove the need for some of the
deep propfinds we have been using so far. It already simplifies the code
a bit for the download scenario.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
We now enforce the use of QStringLiteral and friends in some places,
but that feel through the cracks for some of the Windows specific code.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
We also don't have a version entry in the db if thne db is new.
As I don't expect regular updates from 1.5 this message can just be removed.
Fixes: #8004
[ fatal default ]:ASSERT: "last < rowCount(parent)" in file C:\_\17a9f6ae\qtbase-everywhere-src-5.12.9\src\corelib\itemmodels\qabstractitemmodel.cpp, line 2787
e1ca612c5d3087e02f6b7f8e454224e0b88e82ad stopped adding sub folders so we can return the actual size.
The OAuth authentication brings the broweser to the front, once thats done the wizard continues.
But the wizard ist now most probably hidden behind the browser
This code was actually not breaking most cookie handling by accident.
As the raw cookies where not split properly we added cookies with values like
"key: val; key2 = val2; key3 = val3"
When the code was corrected we overwrote the newer values in the jar with
the old ones from a request.
This was done because the propagator jobs where running in a thread a long
time ago, but this is no longer the case.
(Also QAtomicInt::load is marked as deprecated now)
For a usual file sync event we check for actual changes in the local file,
after an unlock the local file might be unchanged so we need to sync it anyhow.
Fixes: owncloud/enterprise#3609
The original code from csync was stopping at any error.
But we have been whitelisting soeme http error code one by one
to ignore the directory instead of aborting the sync.
However, as there are more requests to continue the sync in case
of error, just ignore most HTTP errors
Issue #7586
On windows we do a test to know if we should change the case of the files,
but that conflict with the test that checks if the file was still there
when the filename is actually the same. Which can happen with virtual files
as they have two representation (the one with and without suffix).
When an item is downloaded because it is restored, it shall be shown in the
sync protocol.
(It is also going to be shown in the not synchronized for a short while, but
that's fine)
When the gui thread blocks for several seconds it's possible for the
ConnectionValidator to timeout and decide that the account is
unreachable. It will then terminate all sync runs.
Increasing the timeout makes this less likely to happen. The tradeoff is
that real disconnects will not be detected as quickly.
This does not address the root cause but makes the symptom less likely
to appear.
Previously the source was deleted (or attempted to be deleted), even if
the new location was not acceptable for upload. This could make data
unavilable on the server.
For #7410
By introducing a PropagateRootDirectory job that explicitly
separates the directory deletion jobs from all the other jobs.
Note that this means that if there are errors in subJobs the
dirDeletionJobs won't get executed.
Previously the job would only become "active" when the downloads
started. That meant that arbitrarily many hash computations could be
queued at the same time.
Since the the file was opened during future creation this could lead to
a "too many open files" problem if there were lots of new-new conflicts.
To change this:
- Make PropagateDownload become active when computing a hash
asynchronously.
- Make the computation future open the file only once it gets run. This
will make it less likely for this problem to occur even if thousands
of these futures are queued.
For #7372
Previously fatal error texts were duplicated: Once they entered the
SyncResult via the SyncFileItem and once via syncError().
syncError is intended for folder-wide sync issues that are not pinned
to particular files. Thus that duplicated path is removed.
For #5088
Previously the pin states of deleted files stayed in the 'flags'
database and could be inadvertently reused when a new file with the same
name appeared. Now they are deleted.
To make this work right, the meaning of the 'path' column in the 'flags'
table was changed: Previously it never had the .owncloud file suffix.
Now it's the same as in metadata.path.
This takes the safe parts from #7274 for inclusion in 2.6. The more
elaborate database schema changes (why use 'path' the join the two
tables in the first place?) shall go into master.
Previously RequestEtagJob did return the etag verbatim (including extra
quotes) while the db had the parsed form. That caused the etag
comparison during discovery move detection to always fail. The test
didn't catch it because the etags there didn't have quotes.
Now:
- RequestEtagJob will parse the etag, leading to a consistent format
- Tests have etags with quotes, detecting the problem
- Close the UploadDevice to close the QFile after the PUT job is done.
This allows winvfs to get an oplock on the file later.
- Don't rely on QFile::fileName() to be valid after
openAndSeekFileSharedRead() was called. The way it is openend on
Windows makes it have an empty filename.
If one adds a new file to an online-only folder the previous behavior
was to upload the file in one sync and dehydrate it in the next. Now
these new files get set to Unspecified pin state, making them retain
their data.
Instead of all at once, to reduce peak memory use.
Changing UploadDevice in this way requires keeping the file open for the
duration of the upload. It also means changes to open(), seek(), close()
to ensure that uses of the device work right when a request needs to
be resent.
Since Qt does not yet transparently resend HTTP2 requests in some cases
we do it manually.
The test showed a problem where the initial non-200 reply would close
the target temporary file and the follow-up request couldn't store any
data. Removing that close() call is safe because there also is a
_saveBodyToFile flag that guards writes to the target file.
The previous patch ensured that the sqlite temporaries weren't deleted
and recreated for every sync run, but there was still time between
client startup and the first sync run where they would have the
"needs-sync" icon.
Previously "no-availability" meant db-error and querying the
availability of a nonexistant path returned AllHydrated.
Now, the availability has a DbError and a NoSuchItem error case.
Saying "Currently available locally" sounds more like an indicator than
"Availably locally" does. Centralizing translations avoids consistency
issues between shell context menus and sync folder context menu.
The db-close operation is likely a leftover from when the SyncEngine
owned its own db connection and serves no purpose anymore.
Closing the db causes the removal of the temporary wal and shm files.
These files are recreated when the db is opened again, which happens
almost immediately.
This is a problem for winvfs because the delete-recreate step wipes the
exclusion state on these files just after the sync is done. That meant
that the db temporaries permanently had a "needs sync" icon marker shown
in the explorer.
Avoiding reopening the db also reduces the number of log messages per
sync.
Previously these result codes during remote discovery of the sync root
would not cause an error and the discovery would get stuck.
Also extends RemoteDiscovery tests to check for errors on the root item.
Previously if one set the instruction to ERROR while forgetting to set
an error status, it'd propagate as FileIgnored. Now the default is
NormalError for INSTRUCTION_ERROR and FileIgnored for
INSTRUCTION_IGNORE.
The idea is that the user's question is "is this folder's data available
offline?" and not "does this folder have AlwaysLocal pin state?".
The the answers to the two questions can differ: an always-local
folder can have subitems that are not always-local and are dehydrated.
The new availability enum intends to describe the answer to the user's
actual question and can be derived from pin states. If pin states aren't
stored in the database the way of calculating availability will depend
on the vfs plugin.
The pin state is a per-item attribute that has an effect on _type:
AlwaysLocal dehydrated files will be marked for hydration and OnlineOnly
hydrated files will be marked for dehydration.
Where exactly this effect materializes depends on how the pin states are
stored. If they're stored in the db (suffix) the dbEntry._type is
changed during the discovery.
If the pin state is stored in the filesystem, the localEntry._type must
be adjusted by the plugin's stat callback.
This patch makes pin states behave more consistently between plugins.
Previously with suffix-vfs pin states only had an effect on new remote
files. Now the effect of pinning or unpinning files or directories is as
documented and similar to other plugins.
1. The _firstJob is usually deleted by the time the PropagateDirectory
finishes. (deleteLater() is called early)
2. The PropagateDirectory::_item and PropagateRemoteMkdir::_item point
to the same SyncFileItem anyway. This code is a leftover from when
each job had its own instance.
Previously removing the vfs suffix of a file always triggered a
conflict. Now it may just cause a file download.
This was done because users expected symmetry in the rename actions and
renaming foo -> foo.owncloud already triggers the "make the file
virtual" action. Now foo.owncloud -> foo triggers the "download the
contents" action.
Users can rename a file *and* add/remove the vfs suffix at the same time
leading to very complex sync actions. This patch doesn't add support for
them, but adds tests and makes sure these cases do not cause unintened
behavior.
The rename will be propagated, but the users's hydrate/dehydrate request
will be ignored.
This was not required with 2.5 because a size of 0 was ignorted when comparing
size by the csync updater, to be compatible with very old version of the database.
But the we discovery will still think the file is changed if the database contains
a size of 0
It seems that sometimes the tray implementation isn't ready on system
startup. Retrying later seems to not help. Delaying the start of the
client is the workaround that people have reported as effective.
When owncloud is started during desktop startup the tray may not yet
be running when the client starts. This will make the client attempt
to create a tray icon again after 10 seconds if there's no tray
during initial startup.
This could fix a problem where the client incorrectly decides to delete
local data.
Previously any sqlite3_step() return value that wasn't SQLITE_ROW would
be interpreted as "there's no more data here". Thus an sqlite error at a
bad time could cause the remote discovery to fail to read an unchanged
subtree from the database. These files would then be deleted locally.
With this change sqlite errors from sqlite3_step are detected and
logged. For the particular case of SyncJournalDb::getFilesBelowPath()
the error will now be propagated and the sync run will fail instead of
performing spurious deletes.
Note that many other database functions still don't distinguish
not-found from error cases. Most of them won't have as severe effects on
affected sync runs though.
It still reads and writes the old format too, but all newly stored
client certs will be in the new form.
For #6776 because Windows limits credential data to 512 bytes in older
versions.
By default, plugins are only searched next to the binary or next to the
other Qt plugins. This optional build variable allows another path to be
configured.
The idea is that on linux the oC packaging probably wants the binary in
something like /opt/owncloud/bin and the plugins in
/opt/owncloud/lib/plugins.
Similarly, distribution packagers probably don't want the plugins next
to the binary or next to the other Qt plugins. This flag allows them to
configure another path that the executable will look in.
doExpand() is called when the selective sync editing mode is enabled in
the folder settings view. Previously it'd set the expansion to be
exactly the root items. Now, it just expands any root items that are
currently collapsed, leaving all other item expansion unchanged.
With the recent bugfix to avoid sending messages on dead connections
0bfe7ac250c54f5415c0a794c7b271428e83c3cf
the client now crashed if readyRead() was received after disconnected()
for the socket as the listener for that connection was already removed.
This code fixes it by still invoking the handler from readyRead() but
passing a SocketListener that won't attempt to send messages.
As far as I'm aware local discovery can be skipped on folders that are
selective-sync blacklisted, so a local discovery is required when an
entry is removed from the blacklist.
Also rename
avoidReadFromDbOnNextSync() -> schedulePathForRemoteDiscovery()
since the old name might also imply it's not read from db in the local
discovery - which is not the case. Use Folder::
schedulePathForLocalDiscovery() for that.
Creating a new virtual file and replacing a file with a virtual one now
have their own text in the protocol, not just "Downloaded".
To do this, the SyncFileItem type is kept as
ItemTypeVirtualFileDehydration for these actions. Added new code to
ensure the type isn't written to the database.
While looking at this, I've also added documentation on SyncFileItem's
_file, _renameTarget, _originalFile and destination() because some of
the semantics weren't clear.
That change will be useful for the notifications. Previously the
dehydrated files were reported as "newly downloaded", now they're
reported as "updated".
That just complicated things. It's ok if Vfs is not a fully abstract
interface class.
The pinstate-in-db methods are instead provided directly on Vfs and
VfsSuffix and VfsOff use them to implement pin states.
The start() method is simply non-virtual and calls into startImpl() for
the plugin-specific startup code.
The block of code that propagated attributes etc from the previously
existing file was placed *after* the block that renamed the previously
existing file to a conflict name. That meant the propagation didn't work
in the conflict case.
- SyncJournalDB functions now behind internalPinStates() to avoid
accidental usage, when nearly everyone should go through Vfs.
- Rename Vfs::getPinState() to Vfs::pinState()
Any folder with a (potentially deeply) contained error will have
StatusWarning. StatusExcluded marks exclusions. The difference is useful
to know for VFS.
This will be used in conjunction with vfs plugins that detect whether a
file has a pending hydration/dehydration through independent means and
communicate that to the discovery through local file type.
Since 'placeholder' just means that it's an item of the special type
that the vfs plugin can deal with - no matter whether hydrated or
dehydrated - all done items should become placeholders. Even
directories.
Now every file that passes through updateMetadata() will be converted to
a placeholder if necessary.
On Linux and Windows the file watcher can't distinguish between changes
that were caused by the process itself, like during a sync operation,
and external changes. To work around that the client keeps a list of
files it has touched and blocks notifications on these files for a bit.
The duration of this block was originally and arbitrarily set at 15
seconds. During manual tests I regularly thought there was a bug when
syncs didn't trigger, when the only problem was that my changes happened
too close to a previous sync operation.
This change reduces the duration to three seconds. I imagine that this
is still enough.
Also use std::chrono while at it.
Also, calling deleteLater() on jobs is unnecessary (they autodelete
after finished()) and deleting the attached QSettings is also
unnecessary because the settings object is parented to the job.
Seeing "Currently available online only" for a currently hydrated file
was odd. It makes sense since current hydration status and pin state are
independent.
The new text will say something like "Currently available, but marked
online only" to better indicate that the file might be dehydrated later
since it wasn't pinned.
supportsSelectiveSync(): clearer than !supportsVirtualFiles() and allows
extra logic
isVfsOnOffSwitchPending(): Somewhat awkward way of dealing with the
phase between a user requesting vfs state to be switched and it
actually happening
slotDiscoveryJobFinished -> slotDiscoveryFinished
slotFinished -> slotPropagationFinished
This should be clearer. Particular the
slotFinished -> finalize -> emit finished()
chain was confusing before.
This allows enabling and disabling vfs.
To distinguish this operation from setting the root pin state, the
availability setting is adjusted as well to be similar to the
menu that shows in the shell extensions.
It has a destructor and these operations make sense. Particularly the
move is important for code like:
Result<x, y> foo() { Result<x, y> v; return v; }
because the move-ctor will not autogenerate if x or y are not trivially
destructible.