From 62731ae766ce674def4d0e75ad00e89ae33e264f Mon Sep 17 00:00:00 2001 From: itdominator <1itdominator@gmail.com> Date: Mon, 23 Mar 2026 01:32:57 -0500 Subject: [PATCH] Improve file loading robustness and drag-and-drop handling - Add error handling for UTF-8 decoding to gracefully handle invalid bytes - Refactor DnD target handling with explicit target list and proper context completion - Remove completed TODO item for file open event emission - Clean up memory by deleting file contents after decoding --- TODO.md | 1 - .../code/mixins/source_view_dnd_mixin.py | 37 ++++++++++++++----- src/core/widgets/code/source_file.py | 8 +++- 3 files changed, 35 insertions(+), 11 deletions(-) diff --git a/TODO.md b/TODO.md index 7010e4f..133fb86 100644 --- a/TODO.md +++ b/TODO.md @@ -4,7 +4,6 @@ ___ 1. Add TreeSitter 1. Add Collapsable code blocks 1. Add Terminal plugin -1. Add event to emit on file open so plugins could try to open 1. Add Plugin to | and | to split views up, down, left, right 1. Add i to **lsp_manager** to list who implements xyz diff --git a/src/core/widgets/code/mixins/source_view_dnd_mixin.py b/src/core/widgets/code/mixins/source_view_dnd_mixin.py index bee3467..80af4f9 100644 --- a/src/core/widgets/code/mixins/source_view_dnd_mixin.py +++ b/src/core/widgets/code/mixins/source_view_dnd_mixin.py @@ -3,7 +3,10 @@ # Lib imports import gi gi.require_version('Gtk', '3.0') +#gi.require_version('Gdk', '3.0') from gi.repository import Gtk +#from gi.repository import Gdk + # Application imports @@ -12,25 +15,41 @@ from gi.repository import Gtk class SourceViewDnDMixin: def _set_up_dnd(self): - PLAIN_TEXT_TARGET_TYPE = 70 - URI_TARGET_TYPE = 80 - text_target = Gtk.TargetEntry.new('text/plain', Gtk.TargetFlags(0), PLAIN_TEXT_TARGET_TYPE) - uri_target = Gtk.TargetEntry.new('text/uri-list', Gtk.TargetFlags(0), URI_TARGET_TYPE) - targets = [ text_target, uri_target ] + URI_TARGET_TYPE = 10 + PLAIN_TEXT_TARGET_TYPE = 50 + + uri_target = Gtk.TargetEntry.new( + 'text/uri-list', Gtk.TargetFlags(0), URI_TARGET_TYPE + ) + text_target = Gtk.TargetEntry.new( + 'text/plain', Gtk.TargetFlags(0), PLAIN_TEXT_TARGET_TYPE + ) + targets = Gtk.TargetList.new([ uri_target, text_target ]) self.drag_dest_set_target_list(targets) - def _on_drag_data_received(self, widget, drag_context, x, y, data, info, time): - if info == 70: return + def _on_drag_data_received( + self, widget, drag_context, x, y, data, info, time + ): + target = data.get_target().name() - if info == 80: + if (info == 10) or (target == "text/uri-list"): uris = data.get_uris() - if not uris: uris = data.get_text().split("\n") self._on_uri_data_received(uris) + drag_context.finish(True, False, time) + + return + elif (info == 50) or (target == "text/plain"): + ... + else: + logger.info(f"DnD Dropped File Type: {target}") + + drag_context.finish(False, False, time) + def _on_uri_data_received(self, uris: list[str]): uris = self.command.filter_out_loaded_files(uris) if not uris: return diff --git a/src/core/widgets/code/source_file.py b/src/core/widgets/code/source_file.py index 1e3efc2..6fe1d7b 100644 --- a/src/core/widgets/code/source_file.py +++ b/src/core/widgets/code/source_file.py @@ -169,7 +169,12 @@ class SourceFile(GtkSource.File): loaded, contents, etag_out = gfile.load_contents() if not loaded: raise Exception("File couldn't be loaded...'") - text = contents.decode("UTF-8") + # Note: + # "strict" (default) -> raises an error on invalid bytes + # "ignore" -> skips invalid bytes entirely + # "replace" -> replaces invalid bytes with � + # "backslashreplace" -> uses escape sequences like \xFF + text = contents.decode("UTF-8", errors = "replace") info = gfile.query_info('standard::content-type', Gio.FileQueryInfoFlags.NONE, None) content_type = info.get_content_type() self.ftype = Gio.content_type_get_mime_type(content_type) \ @@ -177,6 +182,7 @@ class SourceFile(GtkSource.File): .replace("text/", "") \ .replace("x-", "") + del contents self.set_path(gfile) logger.debug(f"File content type: {self.ftype}") self._load_data(text)