develop #14

Merged
itdominator merged 28 commits from develop into master 2025-12-28 04:37:29 +00:00
1272 changed files with 61497 additions and 45582 deletions
Showing only changes of commit 76a4b2e0e2 - Show all commits

View File

@@ -64,16 +64,56 @@ class RenameWidget:
def set_to_title_case(self, widget, eve=None): def set_to_title_case(self, widget, eve=None):
self._rename_fname.set_text( self._rename_fname.get_text().title() ) bounds = self._rename_fname.get_selection_bounds()
fname = self._rename_fname.get_text()
if bounds:
start, end = bounds
replace = fname[start:end]
fname = fname.replace(replace, replace.title())
else:
fname = fname.title()
self._rename_fname.set_text(fname)
def set_to_upper_case(self, widget, eve=None): def set_to_upper_case(self, widget, eve=None):
self._rename_fname.set_text( self._rename_fname.get_text().upper() ) bounds = self._rename_fname.get_selection_bounds()
fname = self._rename_fname.get_text()
if bounds:
start, end = bounds
replace = fname[start:end]
fname = fname.replace(replace, replace.upper())
else:
fname = fname.upper()
self._rename_fname.set_text(fname)
def set_to_lower_case(self, widget, eve=None): def set_to_lower_case(self, widget, eve=None):
self._rename_fname.set_text( self._rename_fname.get_text().lower() ) bounds = self._rename_fname.get_selection_bounds()
fname = self._rename_fname.get_text()
if bounds:
start, end = bounds
replace = fname[start:end]
fname = fname.replace(replace, replace.lower())
else:
fname = fname.lower()
self._rename_fname.set_text(fname)
def set_to_invert_case(self, widget, eve=None): def set_to_invert_case(self, widget, eve=None):
self._rename_fname.set_text( self._rename_fname.get_text().swapcase() ) bounds = self._rename_fname.get_selection_bounds()
fname = self._rename_fname.get_text()
if bounds:
start, end = bounds
replace = fname[start:end]
fname = fname.replace(replace, replace.swapcase())
else:
fname = fname.swapcase()
self._rename_fname.set_text(fname)
def hide_rename_file_menu(self, widget=None, eve=None): def hide_rename_file_menu(self, widget=None, eve=None):
self._rename_file_menu.hide() self._rename_file_menu.hide()

View File

@@ -100,13 +100,15 @@ class TabMixin(GridMixin):
icon_grid.unparent() icon_grid.unparent()
scroll.unparent() scroll.unparent()
Gtk.main_iteration_do(False)
gc.collect()
logger.debug(f"Reference count for tab_box is: {tab_box.__grefcount__}") logger.debug(f"Reference count for tab_box is: {tab_box.__grefcount__}")
logger.debug(f"Reference count for icon_grid is: {icon_grid.__grefcount__}") logger.debug(f"Reference count for icon_grid is: {icon_grid.__grefcount__}")
logger.debug(f"Reference count for scroll is: {scroll.__grefcount__}") logger.debug(f"Reference count for scroll is: {scroll.__grefcount__}")
del tab_box
del icon_grid
del scroll
gc.collect()
if not settings_manager.is_trace_debug(): if not settings_manager.is_trace_debug():
self.fm_controller.save_state() self.fm_controller.save_state()

View File

@@ -9,8 +9,8 @@ from gi.repository import Gtk
from gi.repository import Gdk from gi.repository import Gdk
from gi.repository import GdkPixbuf from gi.repository import GdkPixbuf
# Application imports # Application imports
from utils.cbindings import gtkmemreaper
@@ -48,19 +48,23 @@ class IconGridWidget(Gtk.IconView):
def _setup_signals(self): def _setup_signals(self):
... ...
def _setup_additional_signals(self, grid_icon_single_click, def _setup_additional_signals(self,
grid_icon_double_click, grid_icon_single_click,
grid_set_selected_items, grid_icon_double_click,
grid_on_drag_set, grid_set_selected_items,
grid_on_drag_data_received, grid_on_drag_set,
grid_on_drag_motion): grid_on_drag_data_received,
grid_on_drag_motion
):
self._handler_ids.append(self.connect("button_release_event", grid_icon_single_click)) self._handler_ids = [
self._handler_ids.append(self.connect("item-activated", grid_icon_double_click)) self.connect("button_release_event", grid_icon_single_click),
self._handler_ids.append(self.connect("selection-changed", grid_set_selected_items)) self.connect("item-activated", grid_icon_double_click),
self._handler_ids.append(self.connect("drag-data-get", grid_on_drag_set)) self.connect("selection-changed", grid_set_selected_items),
self._handler_ids.append(self.connect("drag-data-received", grid_on_drag_data_received)) self.connect("drag-data-get", grid_on_drag_set),
self._handler_ids.append(self.connect("drag-motion", grid_on_drag_motion)) self.connect("drag-data-received", grid_on_drag_data_received),
self.connect("drag-motion", grid_on_drag_motion)
]
def _load_widgets(self): def _load_widgets(self):
self.clear_and_set_new_store() self.clear_and_set_new_store()
@@ -113,10 +117,14 @@ class IconGridWidget(Gtk.IconView):
if icon: if icon:
logger.debug(f"Reference count for icon is: {icon.__grefcount__}") logger.debug(f"Reference count for icon is: {icon.__grefcount__}")
icon.run_dispose() icon.run_dispose()
# icon_ptr = int(hash(icon)) # WARNING: not stable across runs
# gtkmemreaper.free_pixbuf(icon_ptr)
del icon del icon
store.clear() store.clear()
store.run_dispose() store.run_dispose()
# store_ptr = int(hash(store)) # WARNING: not stable across runs
# gtkmemreaper.free_list_store(store)
del store del store
gc.collect() gc.collect()

View File

@@ -0,0 +1,20 @@
# Python imports
import pkg_resources
import importlib.util
# Lib imports
# Application imports
def __bootstrap__():
__file__ = pkg_resources.resource_filename(__name__, 'gtkmemreaper.cpython-313-x86_64-linux-gnu.so')
spec = importlib.util.spec_from_file_location(
__name__,
__file__
)
mod = importlib.util.module_from_spec(spec)
spec.loader.exec_module(mod)
__bootstrap__()

View File

@@ -1,42 +1,45 @@
#include <Python.h> #include <Python.h>
#include <gtk.h> #include <gtk/gtk.h>
#include <cairo.h> #include <cairo.h>
#include <gdk-pixbuf/gdk-pixbuf.h> #include <gdk-pixbuf/gdk-pixbuf.h>
#include <stdlib.h> #include <stdlib.h>
// static PyObject* free_pixbuf(PyObject* self, PyObject* args) { // static PyObject* free_pixbuf(PyObject* self, PyObject* args) {
static void free_pixbuf(PyObject* self, PyObject* args) { static PyObject* free_pixbuf(PyObject* self, PyObject* args) {
PyObject *py_pixbuf; PyObject *py_pixbuf;
if (!PyArg_ParseTuple(args, "O", &py_pixbuf)) { if (!PyArg_ParseTuple(args, "O", &py_pixbuf)) {
return NULL; Py_RETURN_NONE;
} }
GdkPixbuf *pixbuf = (GdkPixbuf *) PyLong_AsVoidPtr(py_pixbuf); GdkPixbuf *pixbuf = (GdkPixbuf *) PyLong_AsVoidPtr(py_pixbuf);
if (!GDK_IS_PIXBUF(pixbuf)) { if (!GDK_IS_PIXBUF(pixbuf)) {
PyErr_SetString(PyExc_TypeError, "Invalid GdkPixbuf pointer."); PyErr_SetString(PyExc_TypeError, "Invalid GdkPixbuf pointer.");
return NULL; Py_RETURN_NONE;
} }
g_free(pixbuf); g_object_unref(pixbuf);
// return PyBytes_FromStringAndSize((const char *) cairo_data, buffer_size); g_assert_null(pixbuf);
Py_RETURN_NONE;
} }
static void free_list_store(PyObject* self, PyObject* args) { static PyObject* free_list_store(PyObject* self, PyObject* args) {
PyObject *py_list_store; PyObject *py_list_store;
if (!PyArg_ParseTuple(args, "O", &py_list_store)) { if (!PyArg_ParseTuple(args, "O", &py_list_store)) {
return NULL; Py_RETURN_NONE;
} }
GtkListStore *list_store = (GtkListStore *) PyLong_AsVoidPtr(py_list_store); GtkListStore *list_store = (GtkListStore *) PyLong_AsVoidPtr(py_list_store);
if (!GTK_IS_LIST_STORE(list_store)) { if (!GTK_IS_LIST_STORE(list_store)) {
PyErr_SetString(PyExc_TypeError, "Invalid Gtk.ListStore pointer."); PyErr_SetString(PyExc_TypeError, "Invalid Gtk.ListStore pointer.");
return NULL; Py_RETURN_NONE;
} }
g_object_unref(list_store); g_object_unref(list_store);
g_assert_null(list_store);
Py_RETURN_NONE;
} }

View File

@@ -8,7 +8,7 @@ from subprocess import check_output
pkg_config_args = ["gdk-pixbuf-2.0", "cairo", "gtk"] pkg_config_args = ["gdk-pixbuf-2.0", "cairo", "gtk+-3.0"]
def get_pkgconfig_flags(flag_type): def get_pkgconfig_flags(flag_type):
return check_output(["pkg-config", flag_type] + pkg_config_args).decode().split() return check_output(["pkg-config", flag_type] + pkg_config_args).decode().split()