Text and cursor in tab via Python

I noticed that recently (for several weeks or months), some of my Python scripts do not work properly any more: Edit Next Glyph (based on Rainer’s Activate Next Glyph) and Jump to Alternate, both of which I use very frequently.

After using the latter, I even experience the situation that, after opening a font (but before using the script), using the built-in Edit Background does funny things, like showing the background of the wrong glyph. Something in the stored text must be corrupt, which even survives the closing of the file and app.

The error only seems to occur when glyphs are in the tab that contain a period in their name.

As also Rainer’s script does not work correctly in this case (need to apply the script twice to move to the next glyph if periods are involved), I assume there have been some unexpected changes from Glyphs’ side?

Any ideas how this can be fixed from my side? It seems the relation between GSEditViewController.textCursor and GSEditViewController.text (or GSEditViewController.string or GSEditViewController.layers) is somewhat unclear and unpredictable.

Yes. I have similar issues with the Master Stepper plug-in (where you can Ctrl-click a button for editing the next/previous displayed layer). Towards the end of a text, especially when there are linebreaks, a larger number (20+) glyphs and a number of unencoded glyphs, it is, for instance, hard to deterine if the cursor is already at the end of the text and I need to jump to the first layer or not.

The visible count of glyphs and the characters in the underlying string is different. That can happen when there are OpenType features, or for glyphs that are encoded in the upper plane (and all glyphs that don’t have a unicode will get an upper plane code assigned internally to be accessible.
The python API is trying to hide that fact but this is tricky and somehow tries too much.

This is the code from the Text Tool when you press the left arrow key (translated to python):

view = currTab.graphicView()
selectedLayerRange = view.selectedLayerRange()

if selectedLayerRange.length > 0:
	#Selections that are not insertion points should simply collapse to their start.
	selectedLayerRange.length = 0
elif selectedLayerRange.location > 0:
	# Selections that already are insertion points should move one glyph to the left, if possible.
	selectedLayerRange.location -= 1
view.setSelectedLayerRange_(selectedLayerRange)

I hopefully improved that:

  1. I added a setter for `tab.layersCursor´.
  2. I might change the behavior of the “.layers” property to give the layers as they visible in the edit view. Now it would give the layers without the features applied. To get to the base characters, one can use the “tab.text” property or disable the features him/herself. Any objections?

Sounds good! I’d be pragmatic. Any solution that allows me to achieve what I want will be fine.

Btw, there is another script of mine that uses the text-in-tab API: Toggle Backup Layer. I really use it a lot. Crunching the text in the tab seems rather inefficient and it is noticeably slow when there is a lot of text in the tab. All the script wants to do is simulate clicking on the backup layer or main layer in the layers palette (but with a keyboard shortcut so that I can keep my eyes on the glyph shape). Is there a faster and more elegant way to switch the currently active layer via Python?

1 Like

Thanks, this works perfectly for me. I just updated my Prev/Next Glyph scripts (without using the new API methods): fix behaviour in current version of Glyphs · justanotherfoundry/freemix-glyphsapp@588c0ff · GitHub

1 Like

The improved “layersCursor” API can make that a bit nicer:

tab.layersCursor = tab.layersCursor - 1

instead of:

tab.graphicView().setSelectedLayerRange_(NSRange(tab.layersCursor - 1, 0))
2 Likes