[PATCH 1 of 4] fileview: set a font after clearing the lexer (fixes #6003)

3 views
Skip to first unread message

Matt Harbison

unread,
Jan 14, 2025, 10:09:52 PMJan 14
to thg...@googlegroups.com
# HG changeset patch
# User Matt Harbison <matt_h...@yahoo.com>
# Date 1736886461 18000
# Tue Jan 14 15:27:41 2025 -0500
# Branch stable
# Node ID 47ceb4b5ded604b0ea722d8cafe5b9bcc3e37571
# Parent d3777c97c6cf1f3241ef5a6c841f0011b6f61975
# EXP-Topic issue-6003
fileview: set a font after clearing the lexer (fixes #6003)

This is further work on 95ab09489701. I still have no idea what's going on here,
but a simple reproduction of the problem that this fixes is:

1) launch thg with the Revision Details widget, and type "pack" in the file
filter area
2) Press the button to show all revision controlled files in the tree and
expand out `contrib/packaging/macos`
3) Select "print_platform_files.py" (file content displays correctly)
4) Select "requirements-py3.txt" (file contents has an unexpected font)
5) Select "requirements-pyqt6.txt" (file contents has correct monspaced font)

After that, selecting another *.py file shows the correct contents. Selecting a
text file will show with a bad font, the second text file will show with the
correct monospace font, etc.

My thinking is that somehow, changing to a None lexer is mangling the font on
the QSci component. Selecting the second text file will call `display()` again,
which sets the font on it again. It sets the lexer to None again of course, but
it's already None, so does nothing/skips a block of code/whatever.

Note that prior to 95ab09489701, this set the font after setting the lexer to
None. But we still have to set the font before setting a real lexer to fix the
original problem, so now we handle both ways.

diff --git a/tortoisehg/hgqt/fileview.py b/tortoisehg/hgqt/fileview.py
--- a/tortoisehg/hgqt/fileview.py
+++ b/tortoisehg/hgqt/fileview.py
@@ -841,8 +841,15 @@
if fd.contents:
filename = fd.filePath()
lexer = lexers.getlexer(self._ui, filename, fd.contents, self)
- self._sci.setFont(qtlib.getfont('fontlog').font())
- self._sci.setLexer(lexer)
+ newFont = qtlib.getfont('fontlog').font()
+
+ if lexer is not None:
+ self._sci.setFont(newFont)
+ self._sci.setLexer(lexer)
+ else:
+ self._sci.setLexer(lexer)
+ self._sci.setFont(newFont)
+
self._sci.setText(fd.fileText())

self._sci.setMarginsFont(self._sci.font())

Matt Harbison

unread,
Jan 14, 2025, 10:09:58 PMJan 14
to thg...@googlegroups.com
# HG changeset patch
# User Matt Harbison <matt_h...@yahoo.com>
# Date 1736890686 18000
# Tue Jan 14 16:38:06 2025 -0500
# Branch stable
# Node ID d79536d768756db4df65a8784a472f0a73298dae
# Parent 47ceb4b5ded604b0ea722d8cafe5b9bcc3e37571
# EXP-Topic issue-6003
qt5: apply the recent lexer fix to all other users

With the lexer font issue seemingly fixed with a known reproducible problem in
the previous commit, apply that same change (set font before setting a lexer,
but after clearing a lexer) to all of the other places with a similar pattern.
This is basically a backout of 95ab09489701, and reapplying it more carefully.
There were a few other changes in that commit that are unaffected, because they
were near an unconditional setting of a lexer.

diff --git a/tortoisehg/hgqt/filedialogs.py b/tortoisehg/hgqt/filedialogs.py
--- a/tortoisehg/hgqt/filedialogs.py
+++ b/tortoisehg/hgqt/filedialogs.py
@@ -523,8 +523,13 @@
sci.setMarginLineNumbers(1, True)
sci.SendScintilla(sci.SCI_SETSELEOLFILLED, True)

- sci.setFont(qtlib.getfont('fontdiff').font())
- sci.setLexer(lexer)
+ font = qtlib.getfont('fontdiff').font()
+ if lexer is not None:
+ sci.setFont(font)
+ sci.setLexer(lexer)
+ else:
+ sci.setLexer(lexer)
+ sci.setFont(font)

sci.setReadOnly(True)
sci.setUtf8(True)
diff --git a/tortoisehg/hgqt/messageentry.py b/tortoisehg/hgqt/messageentry.py
--- a/tortoisehg/hgqt/messageentry.py
+++ b/tortoisehg/hgqt/messageentry.py
@@ -76,13 +76,14 @@
def applylexer(self):
font = qtlib.getfont('fontcomment').font()
self.fontHeight = QFontMetrics(font).height()
- self.setFont(font)
if qtlib.readBool(QSettings(), 'msgentry/lexer', True):
+ self.setFont(font)
self.setLexer(QsciLexerMakefile(self))
self.lexer().setColor(QColor(Qt.GlobalColor.red), QsciLexerMakefile.Error)
self.lexer().setFont(font)
else:
self.setLexer(None)
+ self.setFont(font)

@pyqtSlot(QPoint)
def menuRequested(self, point):
diff --git a/tortoisehg/hgqt/rejects.py b/tortoisehg/hgqt/rejects.py
--- a/tortoisehg/hgqt/rejects.py
+++ b/tortoisehg/hgqt/rejects.py
@@ -126,8 +126,15 @@
return
earlybytes = hglib.fromunicode(editor.text(), 'replace')[:4096]
lexer = lexers.getlexer(ui, hglib.tounicode(path), earlybytes, self)
- editor.setFont(qtlib.getfont('fontlog').font())
- editor.setLexer(lexer)
+
+ font = qtlib.getfont('fontlog').font()
+ if lexer is not None:
+ editor.setFont(font)
+ editor.setLexer(lexer)
+ else:
+ editor.setLexer(lexer)
+ editor.setFont(font)
+
editor.setMarginLineNumbers(1, True)
editor.setMarginWidth(1, str(editor.lines())+'X')


Matt Harbison

unread,
Jan 14, 2025, 10:10:04 PMJan 14
to thg...@googlegroups.com
# HG changeset patch
# User Matt Harbison <matt_h...@yahoo.com>
# Date 1736888702 18000
# Tue Jan 14 16:05:02 2025 -0500
# Branch stable
# Node ID 7053741f567846319ecf088c7a4098f6bc760a7d
# Parent d79536d768756db4df65a8784a472f0a73298dae
# EXP-Topic issue-6003
csinfo: migrate several callers to the new `updateItems()` method

More whack-a-mole related to a015c03d91c6, 2dcff69f6563, d6687bcaf716, and
8aa97d83492b. I caught `commit.py`, `csinfo.py` (the second change),
`resolve.py`, `revdetails.py`, and `update.py` by running the app with
`pythonw.exe thg --nofork` instead of `python.exe thg --nofork` on Windows, and
it complained that there's no `flush()` on None in the old function that's
trying to emit a deprecation warning. No sign of the deprecation warning when
running with the latter command. The remainder were found by grepping for
`\.update\(`, excluding `tests/` and `contrib/`, and examining the 69 matches.

diff --git a/tortoisehg/hgqt/backout.py b/tortoisehg/hgqt/backout.py
--- a/tortoisehg/hgqt/backout.py
+++ b/tortoisehg/hgqt/backout.py
@@ -269,7 +269,7 @@
def repositoryChanged(self) -> None:
'repository has detected a change to changelog or parents'
pctx = self.repo[b'.']
- self.localCsInfo.update(pctx)
+ self.localCsInfo.updateItems(pctx)

def canExit(self) -> bool:
'can backout tool be closed?'
@@ -609,5 +609,5 @@
self.layout().addStretch(1)

def currentPage(self) -> None:
- self.bkCsInfo.update(self.repo[b'tip'])
+ self.bkCsInfo.updateItems(self.repo[b'tip'])
self.wizard().setOption(QWizard.WizardOption.NoCancelButton, True)
diff --git a/tortoisehg/hgqt/commit.py b/tortoisehg/hgqt/commit.py
--- a/tortoisehg/hgqt/commit.py
+++ b/tortoisehg/hgqt/commit.py
@@ -610,7 +610,7 @@
self.stwidget.refreshWctx()
custom = self.wdirinfo.custom.copy()
custom['isAmend'] = curraction._name == 'amend'
- self.wdirinfo.update(custom=custom)
+ self.wdirinfo.updateItems(custom=custom)
self.committb.setText(curraction._text)
self.lastAction = curraction._name

@@ -855,7 +855,7 @@

# Update wdir csinfo widget
self.wdirinfo.set_revision(None)
- self.wdirinfo.update()
+ self.wdirinfo.updateItems()

# This is ugly, but want pnlabel to have the same alignment/style/etc
# as wdirinfo, so extract the needed parts of wdirinfo's markup. Would
diff --git a/tortoisehg/hgqt/csinfo.py b/tortoisehg/hgqt/csinfo.py
--- a/tortoisehg/hgqt/csinfo.py
+++ b/tortoisehg/hgqt/csinfo.py
@@ -467,7 +467,7 @@

if 'expandable' in self.csstyle and self.csstyle['expandable']:
if self.expand_btn.parentWidget() is None:
- self.expand_btn.clicked.connect(lambda: self.update())
+ self.expand_btn.clicked.connect(lambda: self.updateItems())
margin = QHBoxLayout()
margin.setContentsMargins(3, 3, 3, 3)
margin.addWidget(self.expand_btn, 0, Qt.AlignmentFlag.AlignTop)
@@ -513,7 +513,7 @@

def set_expanded(self, state):
self.expand_btn.set_expanded(state)
- self.update()
+ self.updateItems()

def is_expanded(self):
return self.expand_btn.is_expanded()
diff --git a/tortoisehg/hgqt/filedialogs.py b/tortoisehg/hgqt/filedialogs.py
--- a/tortoisehg/hgqt/filedialogs.py
+++ b/tortoisehg/hgqt/filedialogs.py
@@ -389,7 +389,7 @@
self.textView.display(fd)
self.textView.verticalScrollBar().setValue(pos)
self.revpanel.set_revision(rev)
- self.revpanel.update(repo = self.repo)
+ self.revpanel.updateItems(repo = self.repo)

@pyqtSlot()
def _onRevisionSelectionChanged(self):
diff --git a/tortoisehg/hgqt/graft.py b/tortoisehg/hgqt/graft.py
--- a/tortoisehg/hgqt/graft.py
+++ b/tortoisehg/hgqt/graft.py
@@ -195,7 +195,7 @@

def _updateSource(self, idx: int) -> None:
self._updateSourceTitle(idx)
- self.cslist.update(self.sourcelist[idx:])
+ self.cslist.updateItems(self.sourcelist[idx:])

@pyqtSlot(bool)
def _onCheckFinished(self, clean: bool) -> None:
diff --git a/tortoisehg/hgqt/matching.py b/tortoisehg/hgqt/matching.py
--- a/tortoisehg/hgqt/matching.py
+++ b/tortoisehg/hgqt/matching.py
@@ -220,7 +220,7 @@
self.rev_to_match_info.setVisible(False)
self.rev_to_match_info_text.setVisible(True)
def csinfo_update(ctx):
- self.rev_to_match_info.update(ctx)
+ self.rev_to_match_info.updateItems(ctx)
set_csinfo_mode(True)
def csinfo_set_text(text):
self.rev_to_match_info_text.setText(text)
diff --git a/tortoisehg/hgqt/merge.py b/tortoisehg/hgqt/merge.py
--- a/tortoisehg/hgqt/merge.py
+++ b/tortoisehg/hgqt/merge.py
@@ -293,7 +293,7 @@
def repositoryChanged(self):
'repository has detected a change to changelog or parents'
pctx = self.repo[b'.']
- self.localCsInfo.update(pctx)
+ self.localCsInfo.updateItems(pctx)

def canExit(self):
'can merge tool be closed?'
@@ -582,7 +582,7 @@
def currentPage(self):
super(CommitPage, self).currentPage()
self.wizard().setOption(QWizard.WizardOption.NoDefaultButton, True)
- self.mergeCsInfo.update() # show post-merge state
+ self.mergeCsInfo.updateItems() # show post-merge state

self.msgEntry.setText(commit.mergecommitmessage(self.repo))
self.msgEntry.moveCursorToEnd()
@@ -687,5 +687,5 @@

def currentPage(self):
super(ResultPage, self).currentPage()
- self.mergeCsInfo.update(self.repo[b'tip'])
+ self.mergeCsInfo.updateItems(self.repo[b'tip'])
self.wizard().setOption(QWizard.WizardOption.NoCancelButton, True)
diff --git a/tortoisehg/hgqt/p4pending.py b/tortoisehg/hgqt/p4pending.py
--- a/tortoisehg/hgqt/p4pending.py
+++ b/tortoisehg/hgqt/p4pending.py
@@ -86,7 +86,7 @@
except (error.Abort, error.RepoLookupError) as e:
revs = []
self.cslist.clear()
- self.cslist.update(revs)
+ self.cslist.updateItems(revs)
sensitive = not curcl.endswith(b'(submitted)')
self.bb.button(QDialogButtonBox.StandardButton.Ok).setEnabled(sensitive)
self.bb.button(QDialogButtonBox.StandardButton.Discard).setEnabled(sensitive)
diff --git a/tortoisehg/hgqt/prune.py b/tortoisehg/hgqt/prune.py
--- a/tortoisehg/hgqt/prune.py
+++ b/tortoisehg/hgqt/prune.py
@@ -126,7 +126,7 @@
revs = pycompat.maplist(int, bytes(sess.readAll()).splitlines())
else:
revs = []
- self._cslist.update(revs)
+ self._cslist.updateItems(revs)
self.commandChanged.emit()

def canRunCommand(self) -> bool:
diff --git a/tortoisehg/hgqt/rebase.py b/tortoisehg/hgqt/rebase.py
--- a/tortoisehg/hgqt/rebase.py
+++ b/tortoisehg/hgqt/rebase.py
@@ -249,8 +249,8 @@
oldsource = self.opts.get('source', '.')
olddest = self.opts.get('dest', '.')

- self.sourcecsinfo.update(target=olddest)
- self.destcsinfo.update(target=oldsource)
+ self.sourcecsinfo.updateItems(target=olddest)
+ self.destcsinfo.updateItems(target=oldsource)

self.opts['source'] = olddest
self.opts['dest'] = oldsource
diff --git a/tortoisehg/hgqt/resolve.py b/tortoisehg/hgqt/resolve.py
--- a/tortoisehg/hgqt/resolve.py
+++ b/tortoisehg/hgqt/resolve.py
@@ -110,7 +110,7 @@
localrevtitle = qtlib.LabeledSeparator(_('Local revision '
'information'))
localrevinfo = csinfo.create(repo)
- localrevinfo.update(self.mergeState.localctx)
+ localrevinfo.updateItems(self.mergeState.localctx)
vbox.addWidget(localrevtitle)
vbox.addWidget(localrevinfo)
vbox.addStretch()
@@ -121,7 +121,7 @@
otherrevtitle = qtlib.LabeledSeparator(_('Other revision '
'information'))
otherrevinfo = csinfo.create(repo)
- otherrevinfo.update(self.mergeState.otherctx)
+ otherrevinfo.updateItems(self.mergeState.otherctx)

vbox.addWidget(otherrevtitle)
vbox.addWidget(otherrevinfo)
diff --git a/tortoisehg/hgqt/revdetails.py b/tortoisehg/hgqt/revdetails.py
--- a/tortoisehg/hgqt/revdetails.py
+++ b/tortoisehg/hgqt/revdetails.py
@@ -310,7 +310,7 @@
'called by repowidget when repoview changes revisions'
self.ctx = ctx = self.repo[rev]
self.revpanel.set_revision(rev)
- self.revpanel.update(repo=self.repo)
+ self.revpanel.updateItems(repo=self.repo)
msg = ctx.description()
inlinetags = self._repoagent.configBool(
'tortoisehg', 'issue.inlinetags')
diff --git a/tortoisehg/hgqt/thgimport.py b/tortoisehg/hgqt/thgimport.py
--- a/tortoisehg/hgqt/thgimport.py
+++ b/tortoisehg/hgqt/thgimport.py
@@ -245,7 +245,7 @@
if not patches:
self.cslist.clear()
else:
- self.cslist.update([os.path.abspath(p) for p in patches])
+ self.cslist.updateItems([os.path.abspath(p) for p in patches])
self.updatestatus()
self._updateUi()

diff --git a/tortoisehg/hgqt/thgstrip.py b/tortoisehg/hgqt/thgstrip.py
--- a/tortoisehg/hgqt/thgstrip.py
+++ b/tortoisehg/hgqt/thgstrip.py
@@ -148,7 +148,7 @@
striprevs = list(self.repo.changelog.descendants([rev]))
striprevs.append(rev)
striprevs.sort()
- self.cslist.update(striprevs)
+ self.cslist.updateItems(striprevs)
return True

@pyqtSlot()
diff --git a/tortoisehg/hgqt/update.py b/tortoisehg/hgqt/update.py
--- a/tortoisehg/hgqt/update.py
+++ b/tortoisehg/hgqt/update.py
@@ -200,10 +200,10 @@

@pyqtSlot()
def update_info(self) -> None:
- self.p1_info.update(self.ctxs[0].node())
+ self.p1_info.updateItems(self.ctxs[0].node())
merge = len(self.ctxs) == 2
if merge:
- self.p2_info.update(self.ctxs[1].node())
+ self.p2_info.updateItems(self.ctxs[1].node())
new_rev = hglib.fromunicode(self.rev_combo.currentText())
if new_rev == b'null':
self.target_info.setText(_('remove working directory'))
@@ -216,7 +216,7 @@
and not new_ctx.bookmarks():
self.target_info.setText(_('(same as parent)'))
else:
- self.target_info.update(new_ctx)
+ self.target_info.updateItems(new_ctx)
# only show the path combo when there are multiple paths
# and the target revision has subrepos
showpathcombo = self.path_combo.count() > 1 and \

Matt Harbison

unread,
Jan 14, 2025, 10:10:10 PMJan 14
to thg...@googlegroups.com
# HG changeset patch
# User Matt Harbison <matt_h...@yahoo.com>
# Date 1736895046 18000
# Tue Jan 14 17:50:46 2025 -0500
# Branch stable
# Node ID 57d400609ed3a9226cf7c953c7c831a34bca4c83
# Parent 7053741f567846319ecf088c7a4098f6bc760a7d
# EXP-Topic issue-6003
prune: use a utility method to convert QByteArray to bytes

This was flagged by PyCharm, and the same change made in 14f6de816861.

diff --git a/tortoisehg/hgqt/prune.py b/tortoisehg/hgqt/prune.py
--- a/tortoisehg/hgqt/prune.py
+++ b/tortoisehg/hgqt/prune.py
@@ -123,7 +123,8 @@
# new query is already or about to be running
return
if ret == 0:
- revs = pycompat.maplist(int, bytes(sess.readAll()).splitlines())
+ data = qtlib.qbytearray_or_bytes_to_bytes(sess.readAll())
+ revs = pycompat.maplist(int, data.splitlines())
else:
revs = []
self._cslist.updateItems(revs)

Matt Harbison

unread,
Jan 14, 2025, 10:11:23 PMJan 14
to TortoiseHg Developers
I think after this, we're ready for the 6.9 release.

Yuya Nishihara

unread,
Jan 15, 2025, 8:02:46 AMJan 15
to Matt Harbison, thg...@googlegroups.com
On Tue, 14 Jan 2025 22:09:41 -0500, Matt Harbison wrote:
> # HG changeset patch
> # User Matt Harbison <matt_h...@yahoo.com>
> # Date 1736888702 18000
> # Tue Jan 14 16:05:02 2025 -0500
> # Branch stable
> # Node ID 7053741f567846319ecf088c7a4098f6bc760a7d
> # Parent d79536d768756db4df65a8784a472f0a73298dae
> # EXP-Topic issue-6003
> csinfo: migrate several callers to the new `updateItems()` method

Queued 3 and 4, thanks.

Yuya Nishihara

unread,
Jan 15, 2025, 8:02:49 AMJan 15
to Matt Harbison, thg...@googlegroups.com
Suppose lexer font precedes, maybe we can simply do
self._sci.setFont(newFont)
self._sci.setLexer(lexer)
self._sci.setFont(newFont) # self._sci.setFont(self._sci.font()) might also work?
?

If it doesn't work, I would add helper function that sets lexer or font.
Reply all
Reply to author
Forward
0 new messages