-
Notifications
You must be signed in to change notification settings - Fork 344
Conversation
The relevant event will no longer be triggered after the shortcut is unregistered. If the same key is registered again, the original callback will be replaced with new one. Therefore, we don't need to find the registered key from the map. Besides, we don't need to parse the accelerator, too. An error will be returned if the method failed.
1. Add test case 2. Add doc to README.md 3. Handle `ctx.Err` in functions
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR.
Before diving into the details, let's reorganize your changes a bit 👍
event.go
Outdated
@@ -29,6 +29,7 @@ type Event struct { | |||
Displays *EventDisplays `json:"displays,omitempty"` | |||
Enable *bool `json:"enable,omitempty"` | |||
FilePath string `json:"filePath,omitempty"` | |||
GlobalShortcut *GlobalShortcut `json:"globalShortcut,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of using GlobalShortcut
directly here, could you:
- create a specific
EventGlobalShortcuts
struct containing json fields only? - remove json fields from
GlobalShortcuts
- make sure you add an
s
at the end of allglobal shortcut
occurences
astilectron.go
Outdated
@@ -187,6 +187,10 @@ func (a *Astilectron) Start() (err error) { | |||
} else { | |||
synchronousFunc(a.worker.Context(), a, nil, "app.event.ready") | |||
} | |||
|
|||
// Initialize global Shortcuts | |||
InitGlobalShortcuts(a.worker.Context(), a.dispatcher, a.identifier, a.writer) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of making the Global Shortcut methods/variables global to the package, could you:
- create a
GlobalShortcuts
struct that will contain the*object
and registered callbacks - add a
globalShortcuts *GlobalShortcuts
variable to theAstilectron
struct - add a
newGlobalShortcuts()
method that creates a*GlobalShortcuts
(and does the other instantiating stuff that your InitGlobalShortcuts() does) and call this method after creating the dock - add a
GlobalShortcuts()
method to theAstilectron
struct that will returna.globalShortcuts
- add
Register()
,IsRegistered()
,Unregister()
andUnregisterAll()
methods to theGlobalShortcuts
struct
Thanks for your suggestion! I've followed your instructions to make some changes, have a look at it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've not finished reviewing all the PR but I'll continue once the requested changes will be made 👍
global_shortcut.go
Outdated
@@ -0,0 +1,123 @@ | |||
package astilectron |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you rename the file to global_shortcuts.go
?
global_shortcut.go
Outdated
import "context" | ||
|
||
const ( | ||
EventNameGlobalShortcutCmdRegister = "global.shortcuts.event.registered" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you make sure the events here are the same as in Javascript?
global_shortcut.go
Outdated
EventNameGlobalShortcutEventTriggered = "global.shortcuts.event.triggered" | ||
) | ||
|
||
type callback func() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you rename this type to globalShortcutsCallback
?
global_shortcut.go
Outdated
// GlobalShortcuts represents a global shortcut | ||
type GlobalShortcuts struct { | ||
*object | ||
callbacks map[string]*callback // Store all registered Global Shortcuts |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You will need to add a *sync.Mutex
as well and use it anywhere you read/write in the map
global_shortcut.go
Outdated
|
||
func newGlobalShortcuts(ctx context.Context, d *dispatcher, i *identifier, w *writer) (gs *GlobalShortcuts) { | ||
var obj = newObject(ctx, d, i, w, i.new()) | ||
gs = &GlobalShortcuts{object: obj, callbacks: make(map[string]*callback)} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you avoid creating the var obj
and instead gs = &GlobalShortcuts{object: newObject(ctx, d, i, w, i.new()), ...}
and below gs.On(...)
?
global_shortcut.go
Outdated
} | ||
|
||
// globalShortcutHandler Handle the GlobalShortcuts event triggered from astilectron | ||
func globalShortcutHandler(gs *GlobalShortcuts, accelerator string) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you make this function part of the GlobalShortcuts
struct instead and rename it to execCallback
:
func (gs *GlobalShortcuts) execCallback(accelerator string) {
// TODO Lock mutex
// Exec callback
}
Changes have been made, have a look at it. |
This is an interesting feature. What is missing to merge and tag it? |
astilectron.go
Outdated
@@ -187,6 +192,7 @@ func (a *Astilectron) Start() (err error) { | |||
} else { | |||
synchronousFunc(a.worker.Context(), a, nil, "app.event.ready") | |||
} | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could your remove this empty line ?
global_shortcuts.go
Outdated
|
||
const ( | ||
EventNameGlobalShortcutsCmdRegister = "global.shortcuts.cmd.register" | ||
EventNameGlobalShortcutsCmdIsRegistered = "global.shortcuts.cmd.is.register" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add the missing ed
at the end of global.shortcuts.cmd.is.register
?
global_shortcuts.go
Outdated
|
||
type globalShortcutsCallback func() | ||
|
||
// GlobalShortcuts represents a global shortcut |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you replace the comment with // GlobalShortcuts represents global shortcuts
?
global_shortcuts.go
Outdated
type GlobalShortcuts struct { | ||
*object | ||
m *sync.Mutex | ||
callbacks map[string]*globalShortcutsCallback // Store all registered Global Shortcuts |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you remove the comment here?
global_shortcuts.go
Outdated
return | ||
} | ||
|
||
// IsRegistered Check if a global shortcut is registered |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you update the comment to IsRegistered checks whether a global shortcut is registered
Also could you make the same modifications I proposed for the previous function?
global_shortcuts.go
Outdated
return | ||
} | ||
|
||
// Unregister Unregister a global shortcut |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you update the comment to Unregister unregisters a global shortcut
Also could you make the same modifications I proposed for the previous function?
global_shortcuts.go
Outdated
return | ||
} | ||
|
||
// No need to find the callback from the map and delete it |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do think cleaning the map is still a good idea
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason why I didn't clean the map is that there are extra costs to determine the corresponded shortcut to be removed from the map. For example, a user registered an event with Ctrl+Shift+S
then unregistered with S+Shift+Ctrl
, expected that shortcut should be unregistred. Therefore Ctrl+Shift+S
should be removed from the map.
A more complex case: registered with CtrlOrCmd+X
then unregistered with Cmd+X
, expected that shortcut is unregistered. Therefore CtrlOrCmd+X
should be removed from the map.
It's too complex to determine the equivalent shortcuts, the best way is to let electron decide whether the shortcuts should be registered or unregistered.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mmm last time I used shortcuts in JS, Ctrl+Shift+S
was different than S+Shift+Ctrl
🤔 Therefore wanting to register a shortcut Ctrl+Shift+S
and unregister it with S+Shift+Ctrl
should not work in Electron 🤔
Nevertheless, I think it's not too much to ask the developer to be consistent in the accelerator he/she uses when registering/unregistering a shortcut. Also I'd rather keep the map the closest to reality.
Therefore, I'd rather see the map cleaned 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mmm last time I used shortcuts in JS, Ctrl+Shift+S was different than S+Shift+Ctrl 🤔 Therefore wanting to register a shortcut Ctrl+Shift+S and unregister it with S+Shift+Ctrl should not work in Electron 🤔
Howerver, the combination of ctrl
+shift
+S
was unregistered successfully.
Therefore, I'd rather see the map cleaned 👍
Sure thing
That PR got lost in my notifications, my apologies. I've reviewed it and made comments 👍 |
@asticode Hi, I've followed suggestions to make changes, have a look at it. astilectron is also updated! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the last changes, there are 2 remaining points 👍
I'll also check the JS PR 👍
global_shortcuts.go
Outdated
m *sync.Mutex | ||
} | ||
|
||
var callbacks map[string]*globalShortcutsCallback |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you not use a pointer to globalShortcutsCallback
in the map?
global_shortcuts.go
Outdated
return | ||
} | ||
|
||
// No need to find the callback from the map and delete it |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mmm last time I used shortcuts in JS, Ctrl+Shift+S
was different than S+Shift+Ctrl
🤔 Therefore wanting to register a shortcut Ctrl+Shift+S
and unregister it with S+Shift+Ctrl
should not work in Electron 🤔
Nevertheless, I think it's not too much to ask the developer to be consistent in the accelerator he/she uses when registering/unregistering a shortcut. Also I'd rather keep the map the closest to reality.
Therefore, I'd rather see the map cleaned 👍
@asticode Hi, I've updated, have a look at it 👍 |
global_shortcuts.go
Outdated
m *sync.Mutex | ||
} | ||
|
||
var callbacks map[string]globalShortcutsCallback |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I missed it in my previous reviews, but could you move callbacks
to the GlobalShortcuts
struct and make sure you initialize it with make(map[string]globalShortcutsCallback)
in newGlobalShortcuts?
|
||
// Send an event to astilectron to unregister the global shortcut | ||
_, err = synchronousEvent(gs.ctx, gs, gs.w, Event{Name: EventNameGlobalShortcutsCmdUnregister, TargetID: gs.id, GlobalShortcuts: &EventGlobalShortcuts{Accelerator: accelerator}}, EventNameGlobalShortcutsEventUnregistered) | ||
if err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't it be instead:
if err != nil {
return
}
gs.m.Lock()
delete(callbacks, accelerator)
gs.m.Unlock()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah.. yes, my fault
@asticode I've updated, have a look at the latest changes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've merged the JS PR but we need to update the astilectron here as well.
Also I've found a minor issue to fix 👍
global_shortcuts.go
Outdated
} | ||
return | ||
}) | ||
gs.callbacks = make(map[string]globalShortcutsCallback) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you remove this line?
"net" | ||
"os/exec" | ||
"runtime" | ||
"time" | ||
|
||
"github.com/asticode/go-astikit" | ||
) | ||
|
||
// Versions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you update DefaultVersionAstilectron
to v0.58.0
below?
@asticode Hi, minor issues are fixed, have a look at it |
Thanks for sticking with this PR! ❤️ |
Solved #392
This PR implements globalShortcut like electron.
4 methods are implemented:
register
,isRegistered
,unregister
,unregisterAll
.I was going to implement these methods as static methods of
GlobalShortcut
struct. Unfortunately, Go doesn't support static method. so an alternative way is implemented. See follow examples:TODO
Register
Is Registered
Unregister
Unregister all