Skip to content
This repository was archived by the owner on Apr 12, 2023. It is now read-only.

Commit c406d0c

Browse files
committed
Don't create exit button as child view
It gets us in to infinite loop when trying to show/hide a child view when entering/leaving the parent view, because moving the cursor to child view will mark mouse leaving the parent which then tries to hide the child view. This only happens for GTK+.
1 parent cf273ad commit c406d0c

File tree

3 files changed

+61
-68
lines changed

3 files changed

+61
-68
lines changed

lib/theme/dark/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ const darkTheme = {
2424
presenceColor: '#9FEAF9',
2525
presencePadding: 3,
2626
presenceRadius: 4,
27+
exitButtonRadius: 7,
28+
exitButtonXHeight: 5,
2729
},
2830
chatBox: {
2931
borderColor: '#E5E5E5',

lib/view/channel-exit.js

Lines changed: 0 additions & 49 deletions
This file was deleted.

lib/view/channel-item.js

Lines changed: 59 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
const gui = require('gui')
22

33
const ChatWindow = require('./chat-window')
4-
const ChannelExit = require('./channel-exit')
54
const {theme} = require('../controller/theme-manager')
65

76
class ChannelItem {
@@ -21,6 +20,7 @@ class ChannelItem {
2120
}
2221

2322
this.hover = false
23+
this.hoverExitButton = false
2424
this.isSelected = false
2525
this.disabled = false
2626

@@ -30,23 +30,17 @@ class ChannelItem {
3030
this.view.onDraw = this._draw.bind(this)
3131
this.view.onMouseEnter = () => {
3232
this.hover = true
33-
if (this.channelExit && this.channel.mentions === 0)
34-
this.channelExit.view.setVisible(true)
33+
this.hoverExitButton = false
3534
this.view.schedulePaint()
3635
}
3736
this.view.onMouseLeave = () => {
3837
this.hover = false
39-
if (this.channelExit)
40-
this.channelExit.view.setVisible(false)
38+
this.hoverExitButton = false
4139
this.view.schedulePaint()
4240
}
4341
this.view.onMouseUp = this._click.bind(this)
44-
if (this.channel.type === 'dm') {
45-
this.channelExit = new ChannelExit()
46-
this.channelExit.view.setVisible(false)
47-
this.channelExit.view.onMouseUp = this._clickExit.bind(this)
48-
this.view.addChildView(this.channelExit.view)
49-
}
42+
if (channel.type === 'dm')
43+
this.view.onMouseMove = this._updateExitButtonHover.bind(this)
5044
}
5145

5246
unload() {
@@ -120,9 +114,12 @@ class ChannelItem {
120114
// Draw mentions count.
121115
if (this.channel.mentions > 0)
122116
this._drawMentionsCount(painter, mentionsRadius, padding + textRect.width, bounds.height, textRect.height)
123-
// Draw presence indicator.
124-
if (this.channel.type === 'dm')
117+
// Draw DM-specific items.
118+
if (this.channel.type === 'dm') {
125119
this._drawPresenceIndicator(painter, bounds, attributes)
120+
if (this.hover && this.channel.mentions === 0)
121+
this._drawExitButton(painter, bounds, attributes)
122+
}
126123
}
127124

128125
_drawMentionsCount(painter, radius, x, height, textHeight) {
@@ -168,7 +165,56 @@ class ChannelItem {
168165
}
169166
}
170167

168+
_drawExitButton(painter, bounds, attributes) {
169+
const {exitButtonXHeight, exitButtonRadius, padding} = theme.channelItem
170+
const xPos = bounds.width - padding - exitButtonRadius
171+
const arcPos = {x: xPos, y: bounds.height / 2}
172+
painter.setStrokeColor(this.hoverExitButton ? theme.channelItem.selectedColor
173+
: theme.channelItem.normalColor)
174+
painter.beginPath()
175+
painter.setLineWidth(1)
176+
painter.arc(arcPos, exitButtonRadius, 0, 2 * Math.PI)
177+
painter.translate({x: xPos, y: (bounds.height - exitButtonXHeight) / 2})
178+
painter.moveTo({x: -(exitButtonXHeight / 2), y: 0})
179+
painter.lineTo({x: exitButtonXHeight / 2, y: exitButtonXHeight})
180+
painter.moveTo({x: - (exitButtonXHeight / 2), y: exitButtonXHeight})
181+
painter.lineTo({x: exitButtonXHeight / 2, y: 0})
182+
painter.stroke()
183+
}
184+
185+
_updateExitButtonHover(view, event) {
186+
if (this.channel.mentions > 0) {
187+
this.hoverExitButton = false
188+
this.view.schedulePaint()
189+
return
190+
}
191+
const {exitButtonXHeight, exitButtonRadius, padding} = theme.channelItem
192+
const bounds = view.getBounds()
193+
const rect = {
194+
left: bounds.width - padding - exitButtonRadius * 2,
195+
top: bounds.height / 2 - exitButtonRadius,
196+
right: bounds.width - padding,
197+
bottom: bounds.height - exitButtonRadius,
198+
}
199+
const hoverExitButton = event.positionInView.x >= rect.left &
200+
event.positionInView.x <= rect.right &
201+
event.positionInView.y >= rect.top &
202+
event.positionInView.y <= rect.bottom
203+
if (this.hoverExitButton != hoverExitButton) {
204+
this.hoverExitButton = hoverExitButton
205+
this.view.schedulePaint()
206+
}
207+
}
208+
171209
_click(view, event) {
210+
// Click on the exit button.
211+
if (this.hoverExitButton) {
212+
if (event.button === 1)
213+
this._leave()
214+
return true
215+
}
216+
217+
// Click on the channel item.
172218
if (event.button === 1) {
173219
// Left click to open channel.
174220
this.parent.selectChannelItem(this)
@@ -190,12 +236,6 @@ class ChannelItem {
190236
}
191237
}
192238

193-
_clickExit(view, event) {
194-
if (event.button === 1)
195-
this._leave()
196-
return true
197-
}
198-
199239
_popup() {
200240
const bounds = this.parent.mainWindow.chatBox.view.getBounds()
201241
new ChatWindow(this.channel, bounds)

0 commit comments

Comments
 (0)