Skip to content

Instantly share code, notes, and snippets.

@alessaba
Created July 21, 2026 12:08
Show Gist options
  • Select an option

  • Save alessaba/a3f8db2ab37a24c4d175f1c45304207c to your computer and use it in GitHub Desktop.

Select an option

Save alessaba/a3f8db2ab37a24c4d175f1c45304207c to your computer and use it in GitHub Desktop.
Set IDAPro Custom icon on macOS. Put into ~/.idapro/plugins. Edit icon path from Edit>Plugins
from pathlib import Path
import json
import ida_idaapi
from PySide6 import QtCore, QtGui, QtWidgets
CONFIG_FILE = Path.home() / ".idapro" / "custom_icon.json"
DEFAULT_ICON = Path.home() / ".idapro" / "custom_icon.png"
ICON = DEFAULT_ICON
def load_config():
global ICON
try:
if CONFIG_FILE.exists():
data = json.loads(CONFIG_FILE.read_text())
ICON = Path(data.get("icon", str(DEFAULT_ICON)))
except Exception as e:
print(f"[dock_icon] Failed to load config: {e}")
ICON = DEFAULT_ICON
def save_config():
try:
CONFIG_FILE.parent.mkdir(parents=True, exist_ok=True)
CONFIG_FILE.write_text(
json.dumps({"icon": str(ICON)}, indent=4)
)
except Exception as e:
print(f"[dock_icon] Failed to save config: {e}")
def apply_icon():
icon = QtGui.QIcon(str(ICON))
if icon.isNull():
print(f"[dock_icon] Cannot load: {ICON}")
return
app = QtWidgets.QApplication.instance()
if app is None:
return
app.setWindowIcon(icon)
# Aggiorna anche tutte le finestre già aperte
for window in app.topLevelWidgets():
window.setWindowIcon(icon)
print(f"[dock_icon] Icon applied: {ICON}")
class ConfigDialog(QtWidgets.QDialog):
def __init__(self, current_path, parent=None):
super().__init__(parent)
self.setWindowTitle("Dock Icon Configuration")
self.setMinimumWidth(600)
layout = QtWidgets.QVBoxLayout(self)
row = QtWidgets.QHBoxLayout()
self.edit = QtWidgets.QLineEdit(current_path)
row.addWidget(self.edit)
browse = QtWidgets.QPushButton("Browse...")
browse.clicked.connect(self.browse)
row.addWidget(browse)
layout.addLayout(row)
buttons = QtWidgets.QDialogButtonBox()
buttons.addButton(QtWidgets.QDialogButtonBox.StandardButton.Ok)
buttons.addButton(QtWidgets.QDialogButtonBox.StandardButton.Cancel)
buttons.accepted.connect(self.accept)
buttons.rejected.connect(self.reject)
layout.addWidget(buttons)
def browse(self):
filename, _ = QtWidgets.QFileDialog.getOpenFileName(
self,
"Select icon",
self.edit.text(),
"Images (*.png *.ico *.icns *.svg);;All files (*)",
)
if filename:
self.edit.setText(filename)
@property
def path(self):
return self.edit.text().strip()
class DockIconPlugin(ida_idaapi.plugin_t):
flags = ida_idaapi.PLUGIN_FIX
comment = "Overrides IDA's Qt application icon"
help = ""
wanted_name = "Dock icon override"
wanted_hotkey = ""
def init(self):
load_config()
QtCore.QTimer.singleShot(0, apply_icon)
QtCore.QTimer.singleShot(1000, apply_icon)
return ida_idaapi.PLUGIN_KEEP
def run(self, arg):
global ICON
dlg = ConfigDialog(str(ICON))
if dlg.exec() == QtWidgets.QDialog.Accepted:
new_icon = Path(dlg.path)
if not new_icon.exists():
QtWidgets.QMessageBox.warning(
None,
"Invalid path",
"The selected file does not exist.",
)
return
ICON = new_icon
save_config()
apply_icon()
def term(self):
pass
def PLUGIN_ENTRY():
return DockIconPlugin()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment