Make dynamic buttons work along with click events
This commit is contained in:
parent
703b5738c8
commit
7857c83ea1
11 changed files with 203 additions and 20 deletions
|
@ -283,7 +283,7 @@ void Window::OnExecuteWindowsCommand(const std::string& command_name) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::OnTouchBarItemResult(const std::string& item_type, const std::string& item_id) {
|
void Window::OnTouchBarItemResult(const std::string& item_type, const std::string& item_id) {
|
||||||
Emit("_touch-bar-interaction", item_type, item_id);
|
Emit("-touch-bar-interaction", item_type, item_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN)
|
||||||
|
@ -844,8 +844,12 @@ void Window::SetVibrancy(mate::Arguments* args) {
|
||||||
window_->SetVibrancy(type);
|
window_->SetVibrancy(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::InitTouchBar() {
|
void Window::DestroyTouchBar() {
|
||||||
window_->InitTouchBar();
|
window_->DestroyTouchBar();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Window::SetTouchBar(mate::Arguments* args) {
|
||||||
|
window_->SetTouchBar(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t Window::ID() const {
|
int32_t Window::ID() const {
|
||||||
|
@ -968,7 +972,8 @@ void Window::BuildPrototype(v8::Isolate* isolate,
|
||||||
.SetMethod("setAutoHideCursor", &Window::SetAutoHideCursor)
|
.SetMethod("setAutoHideCursor", &Window::SetAutoHideCursor)
|
||||||
#endif
|
#endif
|
||||||
.SetMethod("setVibrancy", &Window::SetVibrancy)
|
.SetMethod("setVibrancy", &Window::SetVibrancy)
|
||||||
.SetMethod("initTouchBar", &Window::InitTouchBar)
|
.SetMethod("_destroyTouchBar", &Window::DestroyTouchBar)
|
||||||
|
.SetMethod("_setTouchBar", &Window::SetTouchBar)
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN)
|
||||||
.SetMethod("hookWindowMessage", &Window::HookWindowMessage)
|
.SetMethod("hookWindowMessage", &Window::HookWindowMessage)
|
||||||
.SetMethod("isWindowMessageHooked", &Window::IsWindowMessageHooked)
|
.SetMethod("isWindowMessageHooked", &Window::IsWindowMessageHooked)
|
||||||
|
|
|
@ -204,7 +204,8 @@ class Window : public mate::TrackableObject<Window>,
|
||||||
void SetAutoHideCursor(bool auto_hide);
|
void SetAutoHideCursor(bool auto_hide);
|
||||||
|
|
||||||
void SetVibrancy(mate::Arguments* args);
|
void SetVibrancy(mate::Arguments* args);
|
||||||
void InitTouchBar();
|
void DestroyTouchBar();
|
||||||
|
void SetTouchBar(mate::Arguments* args);
|
||||||
|
|
||||||
v8::Local<v8::Value> WebContents(v8::Isolate* isolate);
|
v8::Local<v8::Value> WebContents(v8::Isolate* isolate);
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include "content/public/browser/render_widget_host_view.h"
|
#include "content/public/browser/render_widget_host_view.h"
|
||||||
#include "content/public/common/content_switches.h"
|
#include "content/public/common/content_switches.h"
|
||||||
#include "ipc/ipc_message_macros.h"
|
#include "ipc/ipc_message_macros.h"
|
||||||
|
#include "native_mate/constructor.h"
|
||||||
#include "native_mate/dictionary.h"
|
#include "native_mate/dictionary.h"
|
||||||
#include "third_party/skia/include/core/SkRegion.h"
|
#include "third_party/skia/include/core/SkRegion.h"
|
||||||
#include "ui/gfx/codec/png_codec.h"
|
#include "ui/gfx/codec/png_codec.h"
|
||||||
|
@ -340,7 +341,10 @@ void NativeWindow::SetAutoHideCursor(bool auto_hide) {
|
||||||
void NativeWindow::SetVibrancy(const std::string& filename) {
|
void NativeWindow::SetVibrancy(const std::string& filename) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void NativeWindow::InitTouchBar() {
|
void NativeWindow::DestroyTouchBar() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void NativeWindow::SetTouchBar(mate::Arguments* args) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void NativeWindow::FocusOnWebView() {
|
void NativeWindow::FocusOnWebView() {
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "extensions/browser/app_window/size_constraints.h"
|
#include "extensions/browser/app_window/size_constraints.h"
|
||||||
#include "ui/gfx/image/image.h"
|
#include "ui/gfx/image/image.h"
|
||||||
#include "ui/gfx/image/image_skia.h"
|
#include "ui/gfx/image/image_skia.h"
|
||||||
|
#include "native_mate/constructor.h"
|
||||||
|
|
||||||
class SkRegion;
|
class SkRegion;
|
||||||
|
|
||||||
|
@ -170,7 +171,8 @@ class NativeWindow : public base::SupportsUserData,
|
||||||
virtual void SetVibrancy(const std::string& type);
|
virtual void SetVibrancy(const std::string& type);
|
||||||
|
|
||||||
// Touchbar API
|
// Touchbar API
|
||||||
virtual void InitTouchBar();
|
virtual void DestroyTouchBar();
|
||||||
|
virtual void SetTouchBar(mate::Arguments* args);
|
||||||
|
|
||||||
// Webview APIs.
|
// Webview APIs.
|
||||||
virtual void FocusOnWebView();
|
virtual void FocusOnWebView();
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include "atom/browser/native_window.h"
|
#include "atom/browser/native_window.h"
|
||||||
#include "base/mac/scoped_nsobject.h"
|
#include "base/mac/scoped_nsobject.h"
|
||||||
#include "content/public/browser/render_widget_host.h"
|
#include "content/public/browser/render_widget_host.h"
|
||||||
|
#include "native_mate/constructor.h"
|
||||||
|
|
||||||
@class AtomNSWindow;
|
@class AtomNSWindow;
|
||||||
@class AtomNSWindowDelegate;
|
@class AtomNSWindowDelegate;
|
||||||
|
@ -100,7 +101,9 @@ class NativeWindowMac : public NativeWindow,
|
||||||
void SetAutoHideCursor(bool auto_hide) override;
|
void SetAutoHideCursor(bool auto_hide) override;
|
||||||
|
|
||||||
void SetVibrancy(const std::string& type) override;
|
void SetVibrancy(const std::string& type) override;
|
||||||
void InitTouchBar() override;
|
void DestroyTouchBar() override;
|
||||||
|
void SetTouchBar(mate::Arguments* args) override;
|
||||||
|
std::vector<mate::Dictionary> GetTouchBarItems();
|
||||||
|
|
||||||
// content::RenderWidgetHost::InputEventObserver:
|
// content::RenderWidgetHost::InputEventObserver:
|
||||||
void OnInputEvent(const blink::WebInputEvent& event) override;
|
void OnInputEvent(const blink::WebInputEvent& event) override;
|
||||||
|
@ -155,6 +158,8 @@ class NativeWindowMac : public NativeWindow,
|
||||||
base::scoped_nsobject<AtomNSWindow> window_;
|
base::scoped_nsobject<AtomNSWindow> window_;
|
||||||
base::scoped_nsobject<AtomNSWindowDelegate> window_delegate_;
|
base::scoped_nsobject<AtomNSWindowDelegate> window_delegate_;
|
||||||
|
|
||||||
|
std::vector<mate::Dictionary> touch_bar_items_;
|
||||||
|
|
||||||
// Event monitor for scroll wheel event.
|
// Event monitor for scroll wheel event.
|
||||||
id wheel_event_monitor_;
|
id wheel_event_monitor_;
|
||||||
|
|
||||||
|
|
|
@ -352,6 +352,8 @@ bool ScopedDisableResize::disable_resize_ = false;
|
||||||
- (void)setEnableLargerThanScreen:(bool)enable;
|
- (void)setEnableLargerThanScreen:(bool)enable;
|
||||||
- (void)enableWindowButtonsOffset;
|
- (void)enableWindowButtonsOffset;
|
||||||
- (void)reloadTouchBar;
|
- (void)reloadTouchBar;
|
||||||
|
- (void)resetTouchBar;
|
||||||
|
- (NSTouchBar*)touchBarFromMutatableArray:(NSMutableArray<NSTouchBarItemIdentifier>*)items;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface AtomNSWindow () <NSTouchBarDelegate>
|
@interface AtomNSWindow () <NSTouchBarDelegate>
|
||||||
|
@ -359,6 +361,7 @@ bool ScopedDisableResize::disable_resize_ = false;
|
||||||
|
|
||||||
@implementation AtomNSWindow
|
@implementation AtomNSWindow
|
||||||
NSMutableArray<NSTouchBarItemIdentifier>* bar_items_ = [[NSMutableArray alloc] init];
|
NSMutableArray<NSTouchBarItemIdentifier>* bar_items_ = [[NSMutableArray alloc] init];
|
||||||
|
std::map<std::string, std::string> button_labels;
|
||||||
|
|
||||||
- (void)setShell:(atom::NativeWindowMac*)shell {
|
- (void)setShell:(atom::NativeWindowMac*)shell {
|
||||||
shell_ = shell;
|
shell_ = shell;
|
||||||
|
@ -368,24 +371,52 @@ bool ScopedDisableResize::disable_resize_ = false;
|
||||||
enable_larger_than_screen_ = enable;
|
enable_larger_than_screen_ = enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)resetTouchBar {
|
||||||
|
bar_items_ = [[NSMutableArray alloc] init];
|
||||||
|
self.touchBar = nil;
|
||||||
|
NSLog(@"Destroying TouchBar");
|
||||||
|
}
|
||||||
|
|
||||||
- (void)reloadTouchBar {
|
- (void)reloadTouchBar {
|
||||||
bar_items_ = [[NSMutableArray alloc] init];
|
bar_items_ = [[NSMutableArray alloc] init];
|
||||||
[bar_items_ addObject:@"com.electron.tb.button.1"];
|
std::vector<mate::Dictionary> items = shell_->GetTouchBarItems();
|
||||||
[bar_items_ addObject:@"com.electron.tb.button.2"];
|
std::map<std::string, std::string> new_button_labels;
|
||||||
|
button_labels = new_button_labels;
|
||||||
|
|
||||||
|
NSLog(@"reload");
|
||||||
|
for (mate::Dictionary &item : items ) {
|
||||||
|
NSLog(@"reload iter");
|
||||||
|
std::string type;
|
||||||
|
std::string item_id;
|
||||||
|
if (item.Get("type", &type) && item.Get("id", &item_id)) {
|
||||||
|
NSLog(@"type: %@", [NSString stringWithUTF8String:type.c_str()]);
|
||||||
|
NSLog(@"id: %@", [NSString stringWithUTF8String:item_id.c_str()]);
|
||||||
|
if (type == "button") {
|
||||||
|
std::string label;
|
||||||
|
if (item.Get("label", &label)) {
|
||||||
|
[bar_items_ addObject:[NSString stringWithFormat:@"%@%@", ButtonIdentifier, [NSString stringWithUTF8String:item_id.c_str()]]];
|
||||||
|
button_labels.insert(make_pair(item_id, label));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// [bar_items_ addObject:@"com.electron.tb.button.1"];
|
||||||
|
// [bar_items_ addObject:@"com.electron.tb.button.2"];
|
||||||
[bar_items_ addObject:NSTouchBarItemIdentifierOtherItemsProxy];
|
[bar_items_ addObject:NSTouchBarItemIdentifierOtherItemsProxy];
|
||||||
NSLog(@"Reloading Touch Bar --> '%@'", bar_items_[1]);
|
// NSLog(@"Reloading Touch Bar --> '%@'", bar_items_[1]);
|
||||||
self.touchBar = nil;
|
self.touchBar = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSTouchBar *)makeTouchBar {
|
- (NSTouchBar *)makeTouchBar {
|
||||||
NSLog(@"Making Touch Bar");
|
NSLog(@"Making Touch Bar");
|
||||||
|
return [self touchBarFromMutatableArray:bar_items_];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSTouchBar *)touchBarFromMutatableArray:(NSMutableArray<NSTouchBarItemIdentifier>*)items {
|
||||||
NSTouchBar* bar = [[NSTouchBar alloc] init];
|
NSTouchBar* bar = [[NSTouchBar alloc] init];
|
||||||
bar.delegate = self;
|
bar.delegate = self;
|
||||||
|
|
||||||
// Set the default ordering of items.
|
bar.defaultItemIdentifiers = [items copy];
|
||||||
|
|
||||||
// NSLog(@"%@", bar_items_[1]);
|
|
||||||
bar.defaultItemIdentifiers = [bar_items_ copy];
|
|
||||||
|
|
||||||
return bar;
|
return bar;
|
||||||
}
|
}
|
||||||
|
@ -412,7 +443,7 @@ static NSTouchBarItemIdentifier LabelIdentifier = @"com.electron.tb.label.";
|
||||||
if ([identifier hasPrefix:ButtonIdentifier]) {
|
if ([identifier hasPrefix:ButtonIdentifier]) {
|
||||||
NSString *idCopy = [identifier copy];
|
NSString *idCopy = [identifier copy];
|
||||||
idCopy = [identifier substringFromIndex:[ButtonIdentifier length]];
|
idCopy = [identifier substringFromIndex:[ButtonIdentifier length]];
|
||||||
NSButton *theButton = [NSButton buttonWithTitle:@"Electron Button" target:self action:@selector(buttonAction:)];
|
NSButton *theButton = [NSButton buttonWithTitle:[NSString stringWithUTF8String:button_labels[std::string([idCopy UTF8String])].c_str()] target:self action:@selector(buttonAction:)];
|
||||||
theButton.tag = [idCopy floatValue];
|
theButton.tag = [idCopy floatValue];
|
||||||
|
|
||||||
NSCustomTouchBarItem *customItem = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier];
|
NSCustomTouchBarItem *customItem = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier];
|
||||||
|
@ -1420,8 +1451,22 @@ void NativeWindowMac::SetVibrancy(const std::string& type) {
|
||||||
[effect_view setMaterial:vibrancyType];
|
[effect_view setMaterial:vibrancyType];
|
||||||
}
|
}
|
||||||
|
|
||||||
void NativeWindowMac::InitTouchBar() {
|
void NativeWindowMac::DestroyTouchBar() {
|
||||||
[window_ reloadTouchBar];
|
[window_ resetTouchBar];
|
||||||
|
}
|
||||||
|
|
||||||
|
void NativeWindowMac::SetTouchBar(mate::Arguments* args) {
|
||||||
|
std::vector<mate::Dictionary> items;
|
||||||
|
LOG(ERROR) << "FOO";
|
||||||
|
if (args->GetNext(&items)) {
|
||||||
|
LOG(ERROR) << "BAR";
|
||||||
|
touch_bar_items_ = items;
|
||||||
|
[window_ reloadTouchBar];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<mate::Dictionary> NativeWindowMac::GetTouchBarItems() {
|
||||||
|
return touch_bar_items_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NativeWindowMac::OnInputEvent(const blink::WebInputEvent& event) {
|
void NativeWindowMac::OnInputEvent(const blink::WebInputEvent& event) {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
const {app, BrowserWindow} = require('electron')
|
const {app, BrowserWindow,TouchBar} = require('electron')
|
||||||
const path = require('path')
|
const path = require('path')
|
||||||
|
|
||||||
let mainWindow = null
|
let mainWindow = null
|
||||||
|
@ -24,5 +24,14 @@ exports.load = (appUrl) => {
|
||||||
mainWindow = new BrowserWindow(options)
|
mainWindow = new BrowserWindow(options)
|
||||||
mainWindow.loadURL(appUrl)
|
mainWindow.loadURL(appUrl)
|
||||||
mainWindow.focus()
|
mainWindow.focus()
|
||||||
|
|
||||||
|
mainWindow.setTouchBar(new TouchBar([
|
||||||
|
new (TouchBar.Button)({
|
||||||
|
label: 'Hello World!',
|
||||||
|
click: () => {
|
||||||
|
console.log('Hello World Clicked')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
]))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
'lib/browser/api/session.js',
|
'lib/browser/api/session.js',
|
||||||
'lib/browser/api/screen.js',
|
'lib/browser/api/screen.js',
|
||||||
'lib/browser/api/system-preferences.js',
|
'lib/browser/api/system-preferences.js',
|
||||||
|
'lib/browser/api/touch-bar.js',
|
||||||
'lib/browser/api/tray.js',
|
'lib/browser/api/tray.js',
|
||||||
'lib/browser/api/web-contents.js',
|
'lib/browser/api/web-contents.js',
|
||||||
'lib/browser/chrome-extension.js',
|
'lib/browser/chrome-extension.js',
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
const {ipcMain} = require('electron')
|
const {ipcMain,TouchBar} = require('electron')
|
||||||
const {EventEmitter} = require('events')
|
const {EventEmitter} = require('events')
|
||||||
const {BrowserWindow} = process.atomBinding('window')
|
const {BrowserWindow} = process.atomBinding('window')
|
||||||
const v8Util = process.atomBinding('v8_util')
|
const v8Util = process.atomBinding('v8_util')
|
||||||
|
@ -131,6 +131,11 @@ BrowserWindow.prototype._init = function () {
|
||||||
return this.webContents.devToolsWebContents
|
return this.webContents.devToolsWebContents
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Proxy TouchBar events
|
||||||
|
this.on('-touch-bar-interaction', (event, item_type, id, ...args) => {
|
||||||
|
TouchBar._event(id, ...args)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
BrowserWindow.getFocusedWindow = () => {
|
BrowserWindow.getFocusedWindow = () => {
|
||||||
|
@ -198,4 +203,15 @@ Object.assign(BrowserWindow.prototype, {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// TouchBar API
|
||||||
|
BrowserWindow.prototype.setTouchBar = function (touchBar) {
|
||||||
|
if (touchBar === null || typeof touchBar === 'undefined') {
|
||||||
|
this._destroyTouchBar();
|
||||||
|
} else if (Array.isArray(touchBar)) {
|
||||||
|
this._setTouchBar((new TouchBar(touchBar)).toJSON());
|
||||||
|
} else {
|
||||||
|
this._setTouchBar(touchBar.toJSON())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = BrowserWindow
|
module.exports = BrowserWindow
|
||||||
|
|
|
@ -103,6 +103,12 @@ Object.defineProperties(exports, {
|
||||||
return require('../system-preferences')
|
return require('../system-preferences')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
TouchBar: {
|
||||||
|
enumerable: true,
|
||||||
|
get: function () {
|
||||||
|
return require('../touch-bar')
|
||||||
|
}
|
||||||
|
},
|
||||||
Tray: {
|
Tray: {
|
||||||
enumerable: true,
|
enumerable: true,
|
||||||
get: function () {
|
get: function () {
|
||||||
|
|
89
lib/browser/api/touch-bar.js
Normal file
89
lib/browser/api/touch-bar.js
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
const {EventEmitter} = require('events')
|
||||||
|
const {app} = require('electron')
|
||||||
|
|
||||||
|
class TouchBar {
|
||||||
|
constructor (items) {
|
||||||
|
this.items = items;
|
||||||
|
if (!Array.isArray(items)) {
|
||||||
|
throw new Error('The items object provided has to be an array')
|
||||||
|
}
|
||||||
|
console.log(items)
|
||||||
|
items.forEach((item) => {
|
||||||
|
if (!item.id) {
|
||||||
|
throw new Error('Each item must be an instance of a TouchBarItem')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
toJSON () {
|
||||||
|
return this.items.map((item) => item.toJSON ? item.toJSON() : item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let item_id_incrementor = 1
|
||||||
|
const item_event_handlers = {}
|
||||||
|
|
||||||
|
TouchBar._event = (id, ...args) => {
|
||||||
|
const id_parts = id.split('.')
|
||||||
|
const item_id = id_parts[id_parts.length - 1]
|
||||||
|
if (item_event_handlers[item_id]) item_event_handlers[item_id](...args)
|
||||||
|
}
|
||||||
|
|
||||||
|
class TouchBarItem {
|
||||||
|
constructor (config) {
|
||||||
|
this.id = item_id_incrementor++
|
||||||
|
const mConfig = Object.assign({}, config || {})
|
||||||
|
Object.defineProperty(this, 'config', {
|
||||||
|
configurable: false,
|
||||||
|
enumerable: false,
|
||||||
|
get: () => mConfig
|
||||||
|
})
|
||||||
|
this.config.id = `${this.config.id || this.id}`;
|
||||||
|
this.config.type = 'button';
|
||||||
|
if (typeof this.config !== 'object' || this.config === null) {
|
||||||
|
throw new Error('Provided config must be a non-null object')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
toJSON () {
|
||||||
|
return this.config
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TouchBar.Button = class TouchBarButton extends TouchBarItem {
|
||||||
|
constructor (config) {
|
||||||
|
super(config)
|
||||||
|
this.config.type = 'button';
|
||||||
|
const click = config.click
|
||||||
|
if (typeof click === 'function') {
|
||||||
|
item_event_handlers[`${this.id}`] = click
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TouchBar.ColorPicker = class TouchBarColorPicker extends TouchBarItem {
|
||||||
|
constructor (config) {
|
||||||
|
super(config)
|
||||||
|
this.config.type = 'colorpicker';
|
||||||
|
const change = config.change
|
||||||
|
if (typeof change === 'function') {
|
||||||
|
item_event_handlers[`${this.id}`] = change
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TouchBar.Label = class TouchBarLabel extends TouchBarItem {}
|
||||||
|
|
||||||
|
TouchBar.List = class TouchBarList extends TouchBarItem {}
|
||||||
|
|
||||||
|
TouchBar.Slider = class TouchBarSlider extends TouchBarItem {
|
||||||
|
constructor (config) {
|
||||||
|
super(config)
|
||||||
|
const change = config.change
|
||||||
|
if (typeof change === 'function') {
|
||||||
|
item_event_handlers[this.id] = change
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = TouchBar;
|
Loading…
Add table
Add a link
Reference in a new issue