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
This commit is contained in:
2026-03-23 01:32:57 -05:00
parent b5cec0d049
commit 62731ae766
3 changed files with 35 additions and 11 deletions

View File

@@ -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

View File

@@ -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 <20>
# "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)