diff --git a/news.d/48.rc/fixed-editable-based-on-reliable-mime-type b/news.d/48.rc/fixed-editable-based-on-reliable-mime-type new file mode 100644 index 0000000..267694b --- /dev/null +++ b/news.d/48.rc/fixed-editable-based-on-reliable-mime-type @@ -0,0 +1 @@ +Decide if an image has a format that supports editing based on the reliable mime-type. That way a wrong file extension will not impact the detection of the format being editable. diff --git a/src/metadata.rs b/src/metadata.rs index ae7513f..e438402 100644 --- a/src/metadata.rs +++ b/src/metadata.rs @@ -105,17 +105,28 @@ impl Metadata { } pub fn mime_type(&self) -> Option { - self.file_info - .as_ref() - .and_then(|x| x.mime_type.as_ref()) - .map(|x| x.to_string()) + self.mime_type.clone() + } + + /// Unreliable mime type + /// + /// Before the image is successfully loaded, this mime type might be wrong + /// since it is not yet based on the more complex mime type detection used + /// by glyin. + pub fn unreliable_mime_type(&self) -> Option { + self.mime_type().or_else(|| { + self.file_info + .as_ref() + .and_then(|x| x.mime_type.as_ref()) + .map(|x| x.to_string()) + }) } pub fn format_name(&self) -> Option { self.image_info .as_ref() .and_then(|x| x.format_name.clone()) - .or_else(|| self.mime_type()) + .or_else(|| self.unreliable_mime_type()) } pub fn alpha_channel(&self) -> Option { diff --git a/src/widgets/image/loading.rs b/src/widgets/image/loading.rs index 1bd2d38..a9fb466 100644 --- a/src/widgets/image/loading.rs +++ b/src/widgets/image/loading.rs @@ -34,14 +34,14 @@ impl imp::LpImage { /// Set filename after filename changed async fn set_file_changed(&self, file: &gio::File) { let obj = self.obj(); - let prev_mime_type = obj.metadata().mime_type(); + let prev_mime_type = obj.metadata().unreliable_mime_type(); self.file.replace(Some(file.clone())); self.reload_file_info().await; // Reload if mime type changed since other decoding path might be responsible // now - if obj.metadata().mime_type() != prev_mime_type { + if obj.metadata().unreliable_mime_type() != prev_mime_type { obj.load(file).await; return; } @@ -80,6 +80,11 @@ impl imp::LpImage { self.emmit_metadata_changed(); obj.reset_rotation(); + glib::spawn_future_local(glib::clone!( + #[weak(rename_to=obj)] + self, + async move { obj.check_editable().await }, + )); } DecoderUpdate::Dimensions => { log::debug!("Received dimensions: {:?}", self.untransformed_dimensions()); @@ -360,8 +365,12 @@ impl LpImage { // Reset background color for reloads imp.set_background_color(None); - let (decoder, decoder_update) = - Decoder::new(file.clone(), self.metadata().mime_type(), tiles.clone()).await; + let (decoder, decoder_update) = Decoder::new( + file.clone(), + self.metadata().unreliable_mime_type(), + tiles.clone(), + ) + .await; let weak_obj = self.downgrade(); glib::spawn_future_local(async move { @@ -374,7 +383,5 @@ impl LpImage { }); imp.decoder.replace(Some(Arc::new(decoder))); - - imp.check_editable().await; } } diff --git a/src/widgets/image_page.rs b/src/widgets/image_page.rs index 589a8c5..115475c 100644 --- a/src/widgets/image_page.rs +++ b/src/widgets/image_page.rs @@ -231,7 +231,7 @@ impl LpImagePage { imp.stack.set_visible_child(&*imp.error_page); imp.error_more_info.set_visible(false); } else if image.specific_error() == DecoderError::UnsupportedFormat { - let mime_type = image.metadata().mime_type().unwrap_or_default(); + let mime_type = image.metadata().unreliable_mime_type().unwrap_or_default(); let content_type = gio::content_type_from_mime_type(&mime_type).unwrap_or_default(); let description = gio::content_type_get_description(&content_type).to_string();