fix(cloud-files): Pin loest Hydration aus, Icon-Refresh via SHChangeNotify
CfSetPinState aendert nur das Pin-Flag - ohne expliziten Call passiert am Disk-Inhalt nichts und das Explorer-Icon bleibt unveraendert. Darum klickte "Immer offline verfuegbar" scheinbar ins Leere. - Bei Pin: CfHydratePlaceholder triggert FETCH_DATA und laedt die Datei komplett herunter - Bei Unpin: CfDehydratePlaceholder (war schon da) - Nach jeder Zustandsaenderung SHChangeNotify(SHCNE_UPDATEITEM) damit das Overlay-Icon sofort neu gezeichnet wird, ohne dass der User F5 druecken muss - Log bekommt zusaetzlich hydrate_err fuer Debugging Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
78615d8897
commit
dd40c55f7d
|
|
@ -560,11 +560,22 @@ pub fn set_pin_state(file: &Path, pinned: bool) -> Result<(), String> {
|
|||
CF::CfSetPinState(handle, state, CF::CF_SET_PIN_FLAG_NONE, None)
|
||||
};
|
||||
|
||||
// "Speicher freigeben" (unpin): sofort dehydrieren, damit der Platz
|
||||
// wirklich frei wird. CfSetPinState allein aendert nur den Zustand.
|
||||
// Der Rueckgabewert wird geloggt aber nicht hart als Fehler gewertet,
|
||||
// weil die Datei evtl. schon dehydriert ist.
|
||||
let dehydrate_err = if !pinned && set_res.is_ok() {
|
||||
// Hydrate bei Pin / Dehydrate bei Unpin. CfSetPinState aendert nur
|
||||
// das Flag - ohne explizite Hydrate-/Dehydrate-Calls passiert am
|
||||
// Disk-Inhalt und am Icon nichts Sichtbares.
|
||||
let (hydrate_err, dehydrate_err) = if set_res.is_ok() {
|
||||
if pinned {
|
||||
let r = unsafe {
|
||||
CF::CfHydratePlaceholder(
|
||||
handle,
|
||||
0,
|
||||
-1,
|
||||
CF::CF_HYDRATE_FLAG_NONE,
|
||||
None,
|
||||
)
|
||||
};
|
||||
(r.err().map(|e| format!("{:?}", e)), None)
|
||||
} else {
|
||||
let r = unsafe {
|
||||
CF::CfDehydratePlaceholder(
|
||||
handle,
|
||||
|
|
@ -574,15 +585,19 @@ pub fn set_pin_state(file: &Path, pinned: bool) -> Result<(), String> {
|
|||
None,
|
||||
)
|
||||
};
|
||||
r.err().map(|e| format!("{:?}", e))
|
||||
(None, r.err().map(|e| format!("{:?}", e)))
|
||||
}
|
||||
} else {
|
||||
None
|
||||
(None, None)
|
||||
};
|
||||
|
||||
unsafe {
|
||||
let _ = windows::Win32::Foundation::CloseHandle(handle);
|
||||
}
|
||||
|
||||
// Explorer Icon-Overlay aktualisieren
|
||||
notify_file_update(file);
|
||||
|
||||
// Log-Verzeichnis ist der Mount-Ordner oder dessen Parent
|
||||
let log_dir = file
|
||||
.ancestors()
|
||||
|
|
@ -592,10 +607,11 @@ pub fn set_pin_state(file: &Path, pinned: bool) -> Result<(), String> {
|
|||
log_msg(
|
||||
&log_dir,
|
||||
&format!(
|
||||
"set_pin_state file={} pinned={} result={:?} dehydrate_err={:?}",
|
||||
"set_pin_state file={} pinned={} result={:?} hydrate_err={:?} dehydrate_err={:?}",
|
||||
file.display(),
|
||||
pinned,
|
||||
set_res,
|
||||
hydrate_err,
|
||||
dehydrate_err
|
||||
),
|
||||
);
|
||||
|
|
@ -603,3 +619,21 @@ pub fn set_pin_state(file: &Path, pinned: bool) -> Result<(), String> {
|
|||
set_res.map_err(|e| format!("CfSetPinState: {e}"))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Sagt dem Shell "diese Datei hat sich geaendert" damit das Overlay-
|
||||
/// Icon (Wolke/Haken) aktualisiert wird, ohne dass der User F5 druecken
|
||||
/// muss.
|
||||
fn notify_file_update(file: &Path) {
|
||||
use windows::Win32::UI::Shell::{SHChangeNotify, SHCNE_UPDATEITEM, SHCNF_PATHW};
|
||||
let Ok(w) = U16CString::from_str(file.to_string_lossy().as_ref()) else {
|
||||
return;
|
||||
};
|
||||
unsafe {
|
||||
SHChangeNotify(
|
||||
SHCNE_UPDATEITEM,
|
||||
SHCNF_PATHW,
|
||||
Some(w.as_ptr() as _),
|
||||
None,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue