General plug-in

Hi
I am confused, I wrote a plug-in but when I installed it, after restarting the glyph, the plug-in window shows (shouldn’t run by itself) next time the glyph starts, a plug-in crash message appears.
I use general plug-in

# encoding: utf-8
###########################################################################################################
#
#
# General Plugin
#
#
###########################################################################################################
import vanilla
import os
import json
import textwrap
import GlyphsApp
from AppKit import NSFont, NSColor, NSAttributedString, NSImage, NSEvent, NSOpenPanel, NSScreen, NSEventMaskKeyDown, NSFileHandlingPanelOKButton, NSForegroundColorAttributeName, NSFontAttributeName, NSCalibratedRGBColorSpace, NSImageScaleProportionallyUpOrDown
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
SCRIPT_FILE = os.path.join(GlyphsApp.GSGlyphsInfo.applicationSupportPath(), "Wall Script.txt")
COLOR_FILE = os.path.join(GlyphsApp.GSGlyphsInfo.applicationSupportPath(), "Wall Script Colors.txt")
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
TOTAL_SUB_WINDOWS = 4
ROWS = 4
COLS = 4
BOX_HEIGHT = 90
BOX_WIDTH = 140
GRID_SPACING = 10
TITLE_BAR_HEIGHT = 45
FONT_SIZE = 12
FONT_BOLD = NSFont.boldSystemFontOfSize_(FONT_SIZE)
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
PREDEFINED_COLORS = [
    NSColor.redColor(),
    NSColor.colorWithRed_green_blue_alpha_(0.0, 0.85, 0.0, 1.0),
    NSColor.blueColor(),
    NSColor.colorWithRed_green_blue_alpha_(1.0, 0.75, 0.0, 1.0),
    NSColor.colorWithRed_green_blue_alpha_(0.5, 0.0, 0.25, 1.0),
    NSColor.colorWithRed_green_blue_alpha_(0.0, 0.5, 0.0, 1.0),
    NSColor.colorWithRed_green_blue_alpha_(0.0, 0.0, 0.55, 1.0),
    NSColor.orangeColor(),
    NSColor.magentaColor(),
    NSColor.colorWithRed_green_blue_alpha_(0.5, 0.0, 1.0, 1.0),
    NSColor.colorWithRed_green_blue_alpha_(0.0, 0.8, 0.8, 1.0),
    NSColor.brownColor(),
    NSColor.colorWithRed_green_blue_alpha_(1.0, 0.0, 0.5, 1.0),
    NSColor.colorWithRed_green_blue_alpha_(0.25, 0.0, 0.5, 1.0),
    NSColor.colorWithRed_green_blue_alpha_(0.0, 0.4, 0.5, 1.0),
    NSColor.colorWithRed_green_blue_alpha_(1.0, 1.0, 1.0, 0.1)
]
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
def settings(self):
	self.name = 'Wall Script'
	self.keyboardShortcut : 'Command+9'
	Glyphs.menu[WINDOW_MENU].append(newMenuItem)
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
def nscolor_to_rgb(color):
    """Convert NSColor to an RGB tuple."""
    color = color.colorUsingColorSpaceName_(NSCalibratedRGBColorSpace)
    return (color.redComponent(), color.greenComponent(), color.blueComponent(), color.alphaComponent())

def rgb_to_nscolor(rgb):
    """Convert an RGB tuple to NSColor."""
    return NSColor.colorWithRed_green_blue_alpha_(rgb[0], rgb[1], rgb[2], rgb[3])
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# Place color window buttons without text in the center of the screen.
def make_color_window(color_options, callback):
    BUTTON_SIZE = 40
    BUTTONS_PER_ROW = 4
    GRID_SPACING = 20
    width = BUTTONS_PER_ROW * (BUTTON_SIZE + GRID_SPACING) + GRID_SPACING - 10
    height = (len(color_options) / BUTTONS_PER_ROW) * (BUTTON_SIZE + GRID_SPACING) + GRID_SPACING - 8

    # Create the window with default position
    w = vanilla.Window((width, height), "Select Color", closable=True)

    # Get the main screen's frame
    screen_frame = NSScreen.mainScreen().frame()
    
    # Calculate the position to center the window
    x_pos = (screen_frame.size.width - width) / 2
    y_pos = (screen_frame.size.height - height) / 2
    
    # Set the window's position
    w.setPosSize((x_pos, y_pos, width, height))

    for i, color in enumerate(color_options):
        row = i // BUTTONS_PER_ROW
        col = i % BUTTONS_PER_ROW
        x_pos = GRID_SPACING + col * (BUTTON_SIZE + GRID_SPACING) - 5
        y_pos = GRID_SPACING + row * (BUTTON_SIZE + GRID_SPACING) - 5

        # Create vanilla button with no title
        button = vanilla.Button((x_pos, y_pos, BUTTON_SIZE, BUTTON_SIZE), "", callback=callback)
        button.color = color
        
        # Get NSButton instance from vanilla button
        ns_button = button.getNSButton()
        ns_button.setWantsLayer_(True)
        ns_button.layer().setBackgroundColor_(color.CGColor())
        ns_button.layer().setCornerRadius_(5)
        ns_button.layer().setBorderWidth_(0)
        ns_button.setBordered_(False)
        ns_button.setImageScaling_(NSImageScaleProportionallyUpOrDown)
        
        setattr(w, f"button_{i}", button)
    
    return w
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
if 'CustomColorPickerWindowUnique' not in globals():
    class CustomColorPickerWindowUnique(vanilla.Window):
        def __init__(self, color_options, callback):
            self.callback = callback
            self.w = make_color_window(color_options, self.color_selected)
            self.w.open()

        def color_selected(self, sender):
            self.callback(sender.color)
            self.w.close()
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
class ScriptGridWindow:
    def __init__(self):
        self.scripts = {}  # Initialize the scripts attribute
        self.load_scripts()
        self.load_colors()
        self.update_total_sub_windows()
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
#Other lines come here
#Other lines come here
#Other lines come here
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# Initialize the window
ScriptGridWindow()

Did you use the plugin template? It defines a class that define the main plugin. Need to put your code into that class.

Yes, I do that, but after restarting the glyphs app, the plug-in window shows at glyph opened (shouldn’t run by itself) and the next time the glyphs app starts, a plug-in crash message appears and wants to remove it.

The code you posted above is not a plugin template. You can find the template in GitHub - schriftgestalt/GlyphsSDK: Scripting SDK for Glyphs.

Is it ok to use this?

# encoding: utf-8

###########################################################################################################
#
#
# General Plugin
#
# Read the docs:
# https://github.com/schriftgestalt/GlyphsSDK/tree/master/Python%20Templates/General%20Plugin
#
#
###########################################################################################################

from __future__ import division, print_function, unicode_literals
import objc
from GlyphsApp import Glyphs, EDIT_MENU
from GlyphsApp.plugins import GeneralPlugin
from AppKit import NSMenuItem


class ____PluginClassName____(GeneralPlugin):

	@objc.python_method
	def settings(self):
		self.name = Glyphs.localize({
			'en': 'My General Plug-in',
			'de': 'Mein allgemeines Plug-in',
			'fr': 'Ma extension générale',
			'es': 'Mi plugin general',
			'pt': 'Meu plug-in geral',
		})

	@objc.python_method
	def start(self):
		if Glyphs.versionNumber >= 3.3:
			newMenuItem = NSMenuItem(self.name, callback=self.showWindow_, target=self)
		else:
			newMenuItem = NSMenuItem(self.name, self.showWindow_)
		Glyphs.menu[EDIT_MENU].append(newMenuItem)

	def showWindow_(self, sender):
		"""Do something like show a window """
		print("show Windows")

	@objc.python_method
	def __file__(self):
		"""Please leave this method unchanged"""
		return __file__

I put these lines at the beginning

# encoding: utf-8

###########################################################################################################
#
#
#
#
#
###########################################################################################################

from __future__ import division, print_function, unicode_literals
import objc
from GlyphsApp import Glyphs, EDIT_MENU
from GlyphsApp.plugins import GeneralPlugin
from AppKit import NSMenuItem

import vanilla
import os
import json
import textwrap
import GlyphsApp
from AppKit import NSFont, NSColor, NSAttributedString, NSImage, NSEvent, NSOpenPanel, NSScreen, NSEventMaskKeyDown, NSFileHandlingPanelOKButton, NSForegroundColorAttributeName, NSFontAttributeName, NSCalibratedRGBColorSpace, NSImageScaleProportionallyUpOrDown
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
SCRIPT_FILE = os.path.join(GlyphsApp.GSGlyphsInfo.applicationSupportPath(), "Wall Script.txt")
COLOR_FILE = os.path.join(GlyphsApp.GSGlyphsInfo.applicationSupportPath(), "Wall Script Colors.txt")
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
TOTAL_SUB_WINDOWS = 4
ROWS = 4
COLS = 4
BOX_HEIGHT = 90
BOX_WIDTH = 140
GRID_SPACING = 10
TITLE_BAR_HEIGHT = 45
FONT_SIZE = 12
FONT_BOLD = NSFont.boldSystemFontOfSize_(FONT_SIZE)
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
PREDEFINED_COLORS = [
    NSColor.redColor(),
    NSColor.colorWithRed_green_blue_alpha_(0.0, 0.85, 0.0, 1.0),
    NSColor.blueColor(),
    NSColor.colorWithRed_green_blue_alpha_(1.0, 0.75, 0.0, 1.0),
    NSColor.colorWithRed_green_blue_alpha_(0.5, 0.0, 0.25, 1.0),
    NSColor.colorWithRed_green_blue_alpha_(0.0, 0.5, 0.0, 1.0),
    NSColor.colorWithRed_green_blue_alpha_(0.0, 0.0, 0.55, 1.0),
    NSColor.orangeColor(),
    NSColor.magentaColor(),
    NSColor.colorWithRed_green_blue_alpha_(0.5, 0.0, 1.0, 1.0),
    NSColor.colorWithRed_green_blue_alpha_(0.0, 0.8, 0.8, 1.0),
    NSColor.brownColor(),
    NSColor.colorWithRed_green_blue_alpha_(1.0, 0.0, 0.5, 1.0),
    NSColor.colorWithRed_green_blue_alpha_(0.25, 0.0, 0.5, 1.0),
    NSColor.colorWithRed_green_blue_alpha_(0.0, 0.4, 0.5, 1.0),
    NSColor.colorWithRed_green_blue_alpha_(1.0, 1.0, 1.0, 0.1)
]
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
def nscolor_to_rgb(color):
    """Convert NSColor to an RGB tuple."""
    color = color.colorUsingColorSpaceName_(NSCalibratedRGBColorSpace)
    return (color.redComponent(), color.greenComponent(), color.blueComponent(), color.alphaComponent())

def rgb_to_nscolor(rgb):
    """Convert an RGB tuple to NSColor."""
    return NSColor.colorWithRed_green_blue_alpha_(rgb[0], rgb[1], rgb[2], rgb[3])
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# Place color window buttons without text in the center of the screen.
def make_color_window(color_options, callback):
    BUTTON_SIZE = 40
    BUTTONS_PER_ROW = 4
    GRID_SPACING = 20
    width = BUTTONS_PER_ROW * (BUTTON_SIZE + GRID_SPACING) + GRID_SPACING - 10
    height = (len(color_options) / BUTTONS_PER_ROW) * (BUTTON_SIZE + GRID_SPACING) + GRID_SPACING - 8

    # Create the window with default position
    w = vanilla.Window((width, height), "Select Color", closable=True)

    # Get the main screen's frame
    screen_frame = NSScreen.mainScreen().frame()
    
    # Calculate the position to center the window
    x_pos = (screen_frame.size.width - width) / 2
    y_pos = (screen_frame.size.height - height) / 2
    
    # Set the window's position
    w.setPosSize((x_pos, y_pos, width, height))

    for i, color in enumerate(color_options):
        row = i // BUTTONS_PER_ROW
        col = i % BUTTONS_PER_ROW
        x_pos = GRID_SPACING + col * (BUTTON_SIZE + GRID_SPACING) - 5
        y_pos = GRID_SPACING + row * (BUTTON_SIZE + GRID_SPACING) - 5

        # Create vanilla button with no title
        button = vanilla.Button((x_pos, y_pos, BUTTON_SIZE, BUTTON_SIZE), "", callback=callback)
        button.color = color
        
        # Get NSButton instance from vanilla button
        ns_button = button.getNSButton()
        ns_button.setWantsLayer_(True)
        ns_button.layer().setBackgroundColor_(color.CGColor())
        ns_button.layer().setCornerRadius_(5)
        ns_button.layer().setBorderWidth_(0)
        ns_button.setBordered_(False)
        ns_button.setImageScaling_(NSImageScaleProportionallyUpOrDown)
        
        setattr(w, f"button_{i}", button)
    
    return w
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
if 'CustomColorPickerWindowUnique' not in globals():
    class CustomColorPickerWindowUnique(vanilla.Window):
        def __init__(self, color_options, callback):
            self.callback = callback
            self.w = make_color_window(color_options, self.color_selected)
            self.w.open()

        def color_selected(self, sender):
            self.callback(sender.color)
            self.w.close()

then rename the class

#rename to
class WallScript:
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    @objc.python_method
    def settings(self):
        self.name = Glyphs.localize({
            'en': 'Wall Script',
        })

    @objc.python_method
    def start(self):
        if Glyphs.versionNumber >= 3.3:
            newMenuItem = NSMenuItem(self.name, callback=self.WallScript, target=self)
        else:
            newMenuItem = NSMenuItem(self.name, self.WallScript)
        Glyphs.menu[WINDOW_MENU].append(newMenuItem)
        self.keyboardShortcut = 'command+9'

    @objc.python_method
    def __file__(self):
        """Please leave this method unchanged"""
        return __file__

then, the next line comes

    def __init__(self):
        self.scripts = {}  # Initialize the scripts attribute
        self.load_scripts()
        self.load_colors()
        self.update_total_sub_windows()
#more lines com here
#more lines com here
#more lines com here
#more lines com here
#more lines com here

and at the end

# Initialize the window
WallScript()

where I did mistake?

Can you just look at the plugin template? It’s all described on the GitHub repository I linked.

Why are you trying to initialise a window?

You only need to change the parts with underscores. Keep the(GeneralPlugin). And you don’t need to instantiate the plugin itself. That is done by Glyphs.

But in your case, it might be easier to just use the script assign a shortcut to open it. It should work as good as the plugin solution.