From fde18e485ff7cbc7b2e33dade8e81136f06a5b60 Mon Sep 17 00:00:00 2001 From: "Kali Kaneko (leap communications)" Date: Thu, 8 Aug 2019 00:19:33 +0200 Subject: [pkg] remove vendor --- vendor/github.com/getlantern/systray/.gitignore | 11 - vendor/github.com/getlantern/systray/LICENSE | 202 ------ vendor/github.com/getlantern/systray/README.md | 50 -- vendor/github.com/getlantern/systray/systray.go | 181 ------ vendor/github.com/getlantern/systray/systray.h | 14 - .../github.com/getlantern/systray/systray_darwin.m | 249 ------- .../github.com/getlantern/systray/systray_linux.c | 217 ------- .../getlantern/systray/systray_nonwindows.go | 99 --- .../getlantern/systray/systray_windows.go | 721 --------------------- .../getlantern/systray/systray_windows_test.go | 132 ---- 10 files changed, 1876 deletions(-) delete mode 100644 vendor/github.com/getlantern/systray/.gitignore delete mode 100644 vendor/github.com/getlantern/systray/LICENSE delete mode 100644 vendor/github.com/getlantern/systray/README.md delete mode 100644 vendor/github.com/getlantern/systray/systray.go delete mode 100644 vendor/github.com/getlantern/systray/systray.h delete mode 100644 vendor/github.com/getlantern/systray/systray_darwin.m delete mode 100644 vendor/github.com/getlantern/systray/systray_linux.c delete mode 100644 vendor/github.com/getlantern/systray/systray_nonwindows.go delete mode 100644 vendor/github.com/getlantern/systray/systray_windows.go delete mode 100644 vendor/github.com/getlantern/systray/systray_windows_test.go (limited to 'vendor/github.com/getlantern/systray') diff --git a/vendor/github.com/getlantern/systray/.gitignore b/vendor/github.com/getlantern/systray/.gitignore deleted file mode 100644 index ae7e06b..0000000 --- a/vendor/github.com/getlantern/systray/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -example/example -*~ -*.swp -*.exe -Release -Debug -*.sdf -dll/systray_unsigned.dll -out.txt -.vs -on_exit*.txt diff --git a/vendor/github.com/getlantern/systray/LICENSE b/vendor/github.com/getlantern/systray/LICENSE deleted file mode 100644 index 3ee0162..0000000 --- a/vendor/github.com/getlantern/systray/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2014 Brave New Software Project, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/getlantern/systray/README.md b/vendor/github.com/getlantern/systray/README.md deleted file mode 100644 index 626c132..0000000 --- a/vendor/github.com/getlantern/systray/README.md +++ /dev/null @@ -1,50 +0,0 @@ -Package systray is a cross platfrom Go library to place an icon and menu in the notification area. -Tested on Windows 8, Mac OSX, Ubuntu 14.10 and Debian 7.6. - -## Usage -```go -func main() { - // Should be called at the very beginning of main(). - systray.Run(onReady, onExit) -} - -func onReady() { - systray.SetIcon(icon.Data) - systray.SetTitle("Awesome App") - systray.SetTooltip("Pretty awesome超级棒") - mQuit := systray.AddMenuItem("Quit", "Quit the whole app") - - // Sets the icon of a menu item. Only available on Mac. - mQuit.SetIcon(icon.Data) -} - -func onExit() { - // clean up here -} -``` -Menu item can be checked and / or disabled. Methods except `Run()` can be invoked from any goroutine. See demo code under `example` folder. - -## Platform specific concerns - -### Linux - -```sh -sudo apt-get install libgtk-3-dev libappindicator3-dev -``` -Checked menu item not implemented on Linux yet. - -## Try - -Under `example` folder. -Place tray icon under `icon`, and use `make_icon.bat` or `make_icon.sh`, whichever suit for your os, to convert the icon to byte array. -Your icon should be .ico file under Windows, whereas .ico, .jpg and .png is supported on other platform. - -```sh -go get -go run main.go -``` - -## Credits - -- https://github.com/xilp/systray -- https://github.com/cratonica/trayhost diff --git a/vendor/github.com/getlantern/systray/systray.go b/vendor/github.com/getlantern/systray/systray.go deleted file mode 100644 index d433173..0000000 --- a/vendor/github.com/getlantern/systray/systray.go +++ /dev/null @@ -1,181 +0,0 @@ -/* -Package systray is a cross platfrom Go library to place an icon and menu in the -notification area. -Supports Windows, Mac OSX and Linux currently. -Methods can be called from any goroutine except Run(), which should be called -at the very beginning of main() to lock at main thread. -*/ -package systray - -import ( - "runtime" - "sync" - "sync/atomic" - - "github.com/getlantern/golog" -) - -var ( - hasStarted = int64(0) - hasQuit = int64(0) -) - -// MenuItem is used to keep track each menu item of systray -// Don't create it directly, use the one systray.AddMenuItem() returned -type MenuItem struct { - // ClickedCh is the channel which will be notified when the menu item is clicked - ClickedCh chan struct{} - - // id uniquely identify a menu item, not supposed to be modified - id int32 - // title is the text shown on menu item - title string - // tooltip is the text shown when pointing to menu item - tooltip string - // disabled menu item is grayed out and has no effect when clicked - disabled bool - // checked menu item has a tick before the title - checked bool -} - -var ( - log = golog.LoggerFor("systray") - - systrayReady func() - systrayExit func() - menuItems = make(map[int32]*MenuItem) - menuItemsLock sync.RWMutex - - currentID = int32(-1) -) - -// Run initializes GUI and starts the event loop, then invokes the onReady -// callback. -// It blocks until systray.Quit() is called. -// Should be called at the very beginning of main() to lock at main thread. -func Run(onReady func(), onExit func()) { - runtime.LockOSThread() - atomic.StoreInt64(&hasStarted, 1) - - if onReady == nil { - systrayReady = func() {} - } else { - // Run onReady on separate goroutine to avoid blocking event loop - readyCh := make(chan interface{}) - go func() { - <-readyCh - onReady() - }() - systrayReady = func() { - close(readyCh) - } - } - - // unlike onReady, onExit runs in the event loop to make sure it has time to - // finish before the process terminates - if onExit == nil { - onExit = func() {} - } - systrayExit = onExit - - nativeLoop() -} - -// Quit the systray -func Quit() { - if atomic.LoadInt64(&hasStarted) == 1 && atomic.CompareAndSwapInt64(&hasQuit, 0, 1) { - quit() - } -} - -// AddMenuItem adds menu item with designated title and tooltip, returning a channel -// that notifies whenever that menu item is clicked. -// -// It can be safely invoked from different goroutines. -func AddMenuItem(title string, tooltip string) *MenuItem { - id := atomic.AddInt32(¤tID, 1) - item := &MenuItem{nil, id, title, tooltip, false, false} - item.ClickedCh = make(chan struct{}) - item.update() - return item -} - -// AddSeparator adds a separator bar to the menu -func AddSeparator() { - addSeparator(atomic.AddInt32(¤tID, 1)) -} - -// SetTitle set the text to display on a menu item -func (item *MenuItem) SetTitle(title string) { - item.title = title - item.update() -} - -// SetTooltip set the tooltip to show when mouse hover -func (item *MenuItem) SetTooltip(tooltip string) { - item.tooltip = tooltip - item.update() -} - -// Disabled checkes if the menu item is disabled -func (item *MenuItem) Disabled() bool { - return item.disabled -} - -// Enable a menu item regardless if it's previously enabled or not -func (item *MenuItem) Enable() { - item.disabled = false - item.update() -} - -// Disable a menu item regardless if it's previously disabled or not -func (item *MenuItem) Disable() { - item.disabled = true - item.update() -} - -// Hide hides a menu item -func (item *MenuItem) Hide() { - hideMenuItem(item) -} - -// Show shows a previously hidden menu item -func (item *MenuItem) Show() { - showMenuItem(item) -} - -// Checked returns if the menu item has a check mark -func (item *MenuItem) Checked() bool { - return item.checked -} - -// Check a menu item regardless if it's previously checked or not -func (item *MenuItem) Check() { - item.checked = true - item.update() -} - -// Uncheck a menu item regardless if it's previously unchecked or not -func (item *MenuItem) Uncheck() { - item.checked = false - item.update() -} - -// update propogates changes on a menu item to systray -func (item *MenuItem) update() { - menuItemsLock.Lock() - defer menuItemsLock.Unlock() - menuItems[item.id] = item - addOrUpdateMenuItem(item) -} - -func systrayMenuItemSelected(id int32) { - menuItemsLock.RLock() - item := menuItems[id] - menuItemsLock.RUnlock() - select { - case item.ClickedCh <- struct{}{}: - // in case no one waiting for the channel - default: - } -} diff --git a/vendor/github.com/getlantern/systray/systray.h b/vendor/github.com/getlantern/systray/systray.h deleted file mode 100644 index 36bcf98..0000000 --- a/vendor/github.com/getlantern/systray/systray.h +++ /dev/null @@ -1,14 +0,0 @@ -extern void systray_ready(); -extern void systray_on_exit(); -extern void systray_menu_item_selected(int menu_id); -int nativeLoop(void); - -void setIcon(const char* iconBytes, int length); -void setMenuItemIcon(const char* iconBytes, int length, int menuId); -void setTitle(char* title); -void setTooltip(char* tooltip); -void add_or_update_menu_item(int menuId, char* title, char* tooltip, short disabled, short checked); -void add_separator(int menuId); -void hide_menu_item(int menuId); -void show_menu_item(int menuId); -void quit(); diff --git a/vendor/github.com/getlantern/systray/systray_darwin.m b/vendor/github.com/getlantern/systray/systray_darwin.m deleted file mode 100644 index 91cc0de..0000000 --- a/vendor/github.com/getlantern/systray/systray_darwin.m +++ /dev/null @@ -1,249 +0,0 @@ -#import -#include "systray.h" - -#ifndef NSControlStateValueOff - #define NSControlStateValueOff NSOffState -#endif - -#ifndef NSControlStateValueOn - #define NSControlStateValueOn NSOnState -#endif - -@interface MenuItem : NSObject -{ - @public - NSNumber* menuId; - NSString* title; - NSString* tooltip; - short disabled; - short checked; -} --(id) initWithId: (int)theMenuId - withTitle: (const char*)theTitle - withTooltip: (const char*)theTooltip - withDisabled: (short)theDisabled - withChecked: (short)theChecked; - @end - @implementation MenuItem - -(id) initWithId: (int)theMenuId - withTitle: (const char*)theTitle - withTooltip: (const char*)theTooltip - withDisabled: (short)theDisabled - withChecked: (short)theChecked -{ - menuId = [NSNumber numberWithInt:theMenuId]; - title = [[NSString alloc] initWithCString:theTitle - encoding:NSUTF8StringEncoding]; - tooltip = [[NSString alloc] initWithCString:theTooltip - encoding:NSUTF8StringEncoding]; - disabled = theDisabled; - checked = theChecked; - return self; -} -@end - -@interface AppDelegate: NSObject - - (void) add_or_update_menu_item:(MenuItem*) item; - - (IBAction)menuHandler:(id)sender; - @property (assign) IBOutlet NSWindow *window; - @end - - @implementation AppDelegate -{ - NSStatusItem *statusItem; - NSMenu *menu; - NSCondition* cond; -} - -@synthesize window = _window; - -- (void)applicationDidFinishLaunching:(NSNotification *)aNotification -{ - self->statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength]; - self->menu = [[NSMenu alloc] init]; - [self->menu setAutoenablesItems: FALSE]; - [self->statusItem setMenu:self->menu]; - systray_ready(); -} - -- (void)applicationWillTerminate:(NSNotification *)aNotification -{ - systray_on_exit(); -} - -- (void)setIcon:(NSImage *)image { - statusItem.button.image = image; - [self updateTitleButtonStyle]; -} - -- (void)setTitle:(NSString *)title { - statusItem.button.title = title; - [self updateTitleButtonStyle]; -} - --(void)updateTitleButtonStyle { - if (statusItem.button.image != nil) { - if ([statusItem.button.title length] == 0) { - statusItem.button.imagePosition = NSImageOnly; - } else { - statusItem.button.imagePosition = NSImageLeft; - } - } else { - statusItem.button.imagePosition = NSNoImage; - } -} - - -- (void)setTooltip:(NSString *)tooltip { - statusItem.button.toolTip = tooltip; -} - -- (IBAction)menuHandler:(id)sender -{ - NSNumber* menuId = [sender representedObject]; - systray_menu_item_selected(menuId.intValue); -} - -- (void) add_or_update_menu_item:(MenuItem*) item -{ - NSMenuItem* menuItem; - int existedMenuIndex = [menu indexOfItemWithRepresentedObject: item->menuId]; - if (existedMenuIndex == -1) { - menuItem = [menu addItemWithTitle:item->title action:@selector(menuHandler:) keyEquivalent:@""]; - [menuItem setTarget:self]; - [menuItem setRepresentedObject: item->menuId]; - - } - else { - menuItem = [menu itemAtIndex: existedMenuIndex]; - [menuItem setTitle:item->title]; - } - [menuItem setToolTip:item->tooltip]; - if (item->disabled == 1) { - menuItem.enabled = FALSE; - } else { - menuItem.enabled = TRUE; - } - if (item->checked == 1) { - menuItem.state = NSControlStateValueOn; - } else { - menuItem.state = NSControlStateValueOff; - } -} - -- (void) add_separator:(NSNumber*) menuId -{ - [menu addItem: [NSMenuItem separatorItem]]; -} - -- (void) hide_menu_item:(NSNumber*) menuId -{ - NSMenuItem* menuItem; - int existedMenuIndex = [menu indexOfItemWithRepresentedObject: menuId]; - if (existedMenuIndex == -1) { - return; - } - menuItem = [menu itemAtIndex: existedMenuIndex]; - [menuItem setHidden:TRUE]; -} - -- (void)setMenuItemIcon:(NSArray*)imageAndMenuId { - NSImage* image = [imageAndMenuId objectAtIndex:0]; - NSNumber* menuId = [imageAndMenuId objectAtIndex:1]; - - NSMenuItem* menuItem; - int existedMenuIndex = [menu indexOfItemWithRepresentedObject: menuId]; - if (existedMenuIndex == -1) { - return; - } - menuItem = [menu itemAtIndex: existedMenuIndex]; - menuItem.image = image; -} - -- (void) show_menu_item:(NSNumber*) menuId -{ - NSMenuItem* menuItem; - int existedMenuIndex = [menu indexOfItemWithRepresentedObject: menuId]; - if (existedMenuIndex == -1) { - return; - } - menuItem = [menu itemAtIndex: existedMenuIndex]; - [menuItem setHidden:FALSE]; -} - -- (void) quit -{ - [NSApp terminate:self]; -} - -@end - -int nativeLoop(void) { - AppDelegate *delegate = [[AppDelegate alloc] init]; - [[NSApplication sharedApplication] setDelegate:delegate]; - [NSApp run]; - return EXIT_SUCCESS; -} - -void runInMainThread(SEL method, id object) { - [(AppDelegate*)[NSApp delegate] - performSelectorOnMainThread:method - withObject:object - waitUntilDone: YES]; -} - -void setIcon(const char* iconBytes, int length) { - NSData* buffer = [NSData dataWithBytes: iconBytes length:length]; - NSImage *image = [[NSImage alloc] initWithData:buffer]; - [image setSize:NSMakeSize(18, 18)]; - runInMainThread(@selector(setIcon:), (id)image); -} - -void setMenuItemIcon(const char* iconBytes, int length, int menuId) { - NSData* buffer = [NSData dataWithBytes: iconBytes length:length]; - NSImage *image = [[NSImage alloc] initWithData:buffer]; - [image setSize:NSMakeSize(18, 18)]; - - NSNumber *mId = [NSNumber numberWithInt:menuId]; - runInMainThread(@selector(setMenuItemIcon:), @[image, (id)mId]); -} - -void setTitle(char* ctitle) { - NSString* title = [[NSString alloc] initWithCString:ctitle - encoding:NSUTF8StringEncoding]; - free(ctitle); - runInMainThread(@selector(setTitle:), (id)title); -} - -void setTooltip(char* ctooltip) { - NSString* tooltip = [[NSString alloc] initWithCString:ctooltip - encoding:NSUTF8StringEncoding]; - free(ctooltip); - runInMainThread(@selector(setTooltip:), (id)tooltip); -} - -void add_or_update_menu_item(int menuId, char* title, char* tooltip, short disabled, short checked) { - MenuItem* item = [[MenuItem alloc] initWithId: menuId withTitle: title withTooltip: tooltip withDisabled: disabled withChecked: checked]; - free(title); - free(tooltip); - runInMainThread(@selector(add_or_update_menu_item:), (id)item); -} - -void add_separator(int menuId) { - NSNumber *mId = [NSNumber numberWithInt:menuId]; - runInMainThread(@selector(add_separator:), (id)mId); -} - -void hide_menu_item(int menuId) { - NSNumber *mId = [NSNumber numberWithInt:menuId]; - runInMainThread(@selector(hide_menu_item:), (id)mId); -} - -void show_menu_item(int menuId) { - NSNumber *mId = [NSNumber numberWithInt:menuId]; - runInMainThread(@selector(show_menu_item:), (id)mId); -} - -void quit() { - runInMainThread(@selector(quit), nil); -} diff --git a/vendor/github.com/getlantern/systray/systray_linux.c b/vendor/github.com/getlantern/systray/systray_linux.c deleted file mode 100644 index 72cd614..0000000 --- a/vendor/github.com/getlantern/systray/systray_linux.c +++ /dev/null @@ -1,217 +0,0 @@ -#include -#include -#include -#include -#include -#include "systray.h" - -static AppIndicator *global_app_indicator; -static GtkWidget *global_tray_menu = NULL; -static GList *global_menu_items = NULL; -static char temp_file_name[PATH_MAX] = ""; - -typedef struct { - GtkWidget *menu_item; - int menu_id; -} MenuItemNode; - -typedef struct { - int menu_id; - char* title; - char* tooltip; - short disabled; - short checked; -} MenuItemInfo; - -int nativeLoop(void) { - gtk_init(0, NULL); - global_app_indicator = app_indicator_new("systray", "", - APP_INDICATOR_CATEGORY_APPLICATION_STATUS); - app_indicator_set_status(global_app_indicator, APP_INDICATOR_STATUS_ACTIVE); - global_tray_menu = gtk_menu_new(); - app_indicator_set_menu(global_app_indicator, GTK_MENU(global_tray_menu)); - systray_ready(); - gtk_main(); - systray_on_exit(); - return 0; -} - -void _unlink_temp_file() { - if (strlen(temp_file_name) != 0) { - int ret = unlink(temp_file_name); - if (ret == -1) { - printf("failed to remove temp icon file %s: %s\n", temp_file_name, strerror(errno)); - } - temp_file_name[0] = '\0'; - } -} - -// runs in main thread, should always return FALSE to prevent gtk to execute it again -gboolean do_set_icon(gpointer data) { - _unlink_temp_file(); - char *tmpdir = getenv("TMPDIR"); - if (NULL == tmpdir) { - tmpdir = "/tmp"; - } - strncpy(temp_file_name, tmpdir, PATH_MAX-1); - strncat(temp_file_name, "/systray_XXXXXX", PATH_MAX-1); - temp_file_name[PATH_MAX-1] = '\0'; - - GBytes* bytes = (GBytes*)data; - int fd = mkstemp(temp_file_name); - if (fd == -1) { - printf("failed to create temp icon file %s: %s\n", temp_file_name, strerror(errno)); - return FALSE; - } - gsize size = 0; - gconstpointer icon_data = g_bytes_get_data(bytes, &size); - ssize_t written = write(fd, icon_data, size); - close(fd); - if(written != size) { - printf("failed to write temp icon file %s: %s\n", temp_file_name, strerror(errno)); - return FALSE; - } - app_indicator_set_icon_full(global_app_indicator, temp_file_name, ""); - app_indicator_set_attention_icon_full(global_app_indicator, temp_file_name, ""); - g_bytes_unref(bytes); - return FALSE; -} - -void _systray_menu_item_selected(int *id) { - systray_menu_item_selected(*id); -} - -// runs in main thread, should always return FALSE to prevent gtk to execute it again -gboolean do_add_or_update_menu_item(gpointer data) { - MenuItemInfo *mii = (MenuItemInfo*)data; - GList* it; - for(it = global_menu_items; it != NULL; it = it->next) { - MenuItemNode* item = (MenuItemNode*)(it->data); - if(item->menu_id == mii->menu_id){ - gtk_menu_item_set_label(GTK_MENU_ITEM(item->menu_item), mii->title); - break; - } - } - - // menu id doesn't exist, add new item - if(it == NULL) { - GtkWidget *menu_item = gtk_menu_item_new_with_label(mii->title); - int *id = malloc(sizeof(int)); - *id = mii->menu_id; - g_signal_connect_swapped(G_OBJECT(menu_item), "activate", G_CALLBACK(_systray_menu_item_selected), id); - gtk_menu_shell_append(GTK_MENU_SHELL(global_tray_menu), menu_item); - - MenuItemNode* new_item = malloc(sizeof(MenuItemNode)); - new_item->menu_id = mii->menu_id; - new_item->menu_item = menu_item; - GList* new_node = malloc(sizeof(GList)); - new_node->data = new_item; - new_node->next = global_menu_items; - if(global_menu_items != NULL) { - global_menu_items->prev = new_node; - } - global_menu_items = new_node; - it = new_node; - } - GtkWidget * menu_item = GTK_WIDGET(((MenuItemNode*)(it->data))->menu_item); - gtk_widget_set_sensitive(menu_item, mii->disabled == 1 ? FALSE : TRUE); - gtk_widget_show(menu_item); - - free(mii->title); - free(mii->tooltip); - free(mii); - return FALSE; -} - -gboolean do_add_separator(gpointer data) { - GtkWidget *separator = gtk_separator_menu_item_new(); - gtk_menu_shell_append(GTK_MENU_SHELL(global_tray_menu), separator); - gtk_widget_show(separator); - return FALSE; -} - -// runs in main thread, should always return FALSE to prevent gtk to execute it again -gboolean do_hide_menu_item(gpointer data) { - MenuItemInfo *mii = (MenuItemInfo*)data; - GList* it; - for(it = global_menu_items; it != NULL; it = it->next) { - MenuItemNode* item = (MenuItemNode*)(it->data); - if(item->menu_id == mii->menu_id){ - gtk_widget_hide(GTK_WIDGET(item->menu_item)); - break; - } - } - return FALSE; -} - -// runs in main thread, should always return FALSE to prevent gtk to execute it again -gboolean do_show_menu_item(gpointer data) { - MenuItemInfo *mii = (MenuItemInfo*)data; - GList* it; - for(it = global_menu_items; it != NULL; it = it->next) { - MenuItemNode* item = (MenuItemNode*)(it->data); - if(item->menu_id == mii->menu_id){ - gtk_widget_show(GTK_WIDGET(item->menu_item)); - break; - } - } - return FALSE; -} - -// runs in main thread, should always return FALSE to prevent gtk to execute it again -gboolean do_quit(gpointer data) { - _unlink_temp_file(); - // app indicator doesn't provide a way to remove it, hide it as a workaround - app_indicator_set_status(global_app_indicator, APP_INDICATOR_STATUS_PASSIVE); - gtk_main_quit(); - return FALSE; -} - -void setIcon(const char* iconBytes, int length) { - GBytes* bytes = g_bytes_new_static(iconBytes, length); - g_idle_add(do_set_icon, bytes); -} - -void setTitle(char* ctitle) { - app_indicator_set_label(global_app_indicator, ctitle, ""); - free(ctitle); -} - -void setTooltip(char* ctooltip) { - free(ctooltip); -} - -void setMenuItemIcon(const char* iconBytes, int length, int menuId) { -} - -void add_or_update_menu_item(int menu_id, char* title, char* tooltip, short disabled, short checked) { - MenuItemInfo *mii = malloc(sizeof(MenuItemInfo)); - mii->menu_id = menu_id; - mii->title = title; - mii->tooltip = tooltip; - mii->disabled = disabled; - mii->checked = checked; - g_idle_add(do_add_or_update_menu_item, mii); -} - -void add_separator(int menu_id) { - MenuItemInfo *mii = malloc(sizeof(MenuItemInfo)); - mii->menu_id = menu_id; - g_idle_add(do_add_separator, mii); -} - -void hide_menu_item(int menu_id) { - MenuItemInfo *mii = malloc(sizeof(MenuItemInfo)); - mii->menu_id = menu_id; - g_idle_add(do_hide_menu_item, mii); -} - -void show_menu_item(int menu_id) { - MenuItemInfo *mii = malloc(sizeof(MenuItemInfo)); - mii->menu_id = menu_id; - g_idle_add(do_show_menu_item, mii); -} - -void quit() { - g_idle_add(do_quit, NULL); -} diff --git a/vendor/github.com/getlantern/systray/systray_nonwindows.go b/vendor/github.com/getlantern/systray/systray_nonwindows.go deleted file mode 100644 index 4868b55..0000000 --- a/vendor/github.com/getlantern/systray/systray_nonwindows.go +++ /dev/null @@ -1,99 +0,0 @@ -// +build !windows - -package systray - -/* -#cgo linux pkg-config: gtk+-3.0 appindicator3-0.1 -#cgo darwin CFLAGS: -DDARWIN -x objective-c -fobjc-arc -#cgo darwin LDFLAGS: -framework Cocoa - -#include "systray.h" -*/ -import "C" - -import ( - "unsafe" -) - -func nativeLoop() { - C.nativeLoop() -} - -func quit() { - C.quit() -} - -// SetIcon sets the systray icon. -// iconBytes should be the content of .ico for windows and .ico/.jpg/.png -// for other platforms. -func SetIcon(iconBytes []byte) { - cstr := (*C.char)(unsafe.Pointer(&iconBytes[0])) - C.setIcon(cstr, (C.int)(len(iconBytes))) -} - -// SetTitle sets the systray title, only available on Mac. -func SetTitle(title string) { - C.setTitle(C.CString(title)) -} - -// SetTooltip sets the systray tooltip to display on mouse hover of the tray icon, -// only available on Mac and Windows. -func SetTooltip(tooltip string) { - C.setTooltip(C.CString(tooltip)) -} - -func addOrUpdateMenuItem(item *MenuItem) { - var disabled C.short - if item.disabled { - disabled = 1 - } - var checked C.short - if item.checked { - checked = 1 - } - C.add_or_update_menu_item( - C.int(item.id), - C.CString(item.title), - C.CString(item.tooltip), - disabled, - checked, - ) -} - -// SetIcon sets the icon of a menu item. Only available on Mac. -// iconBytes should be the content of .ico/.jpg/.png -func (item *MenuItem) SetIcon(iconBytes []byte) { - cstr := (*C.char)(unsafe.Pointer(&iconBytes[0])) - C.setMenuItemIcon(cstr, (C.int)(len(iconBytes)), C.int(item.id)) -} - -func addSeparator(id int32) { - C.add_separator(C.int(id)) -} - -func hideMenuItem(item *MenuItem) { - C.hide_menu_item( - C.int(item.id), - ) -} - -func showMenuItem(item *MenuItem) { - C.show_menu_item( - C.int(item.id), - ) -} - -//export systray_ready -func systray_ready() { - systrayReady() -} - -//export systray_on_exit -func systray_on_exit() { - systrayExit() -} - -//export systray_menu_item_selected -func systray_menu_item_selected(cID C.int) { - systrayMenuItemSelected(int32(cID)) -} diff --git a/vendor/github.com/getlantern/systray/systray_windows.go b/vendor/github.com/getlantern/systray/systray_windows.go deleted file mode 100644 index ae9c838..0000000 --- a/vendor/github.com/getlantern/systray/systray_windows.go +++ /dev/null @@ -1,721 +0,0 @@ -// +build windows - -package systray - -import ( - "crypto/md5" - "encoding/hex" - "io/ioutil" - "os" - "path/filepath" - "sort" - "syscall" - "unsafe" - - "golang.org/x/sys/windows" -) - -// Helpful sources: https://github.com/golang/exp/blob/master/shiny/driver/internal/win32 - -var ( - k32 = windows.NewLazySystemDLL("Kernel32.dll") - s32 = windows.NewLazySystemDLL("Shell32.dll") - u32 = windows.NewLazySystemDLL("User32.dll") - pGetModuleHandle = k32.NewProc("GetModuleHandleW") - pShellNotifyIcon = s32.NewProc("Shell_NotifyIconW") - pCreatePopupMenu = u32.NewProc("CreatePopupMenu") - pCreateWindowEx = u32.NewProc("CreateWindowExW") - pDefWindowProc = u32.NewProc("DefWindowProcW") - pDeleteMenu = u32.NewProc("DeleteMenu") - pDestroyWindow = u32.NewProc("DestroyWindow") - pDispatchMessage = u32.NewProc("DispatchMessageW") - pGetCursorPos = u32.NewProc("GetCursorPos") - pGetMenuItemID = u32.NewProc("GetMenuItemID") - pGetMessage = u32.NewProc("GetMessageW") - pInsertMenuItem = u32.NewProc("InsertMenuItemW") - pLoadIcon = u32.NewProc("LoadIconW") - pLoadImage = u32.NewProc("LoadImageW") - pLoadCursor = u32.NewProc("LoadCursorW") - pPostMessage = u32.NewProc("PostMessageW") - pPostQuitMessage = u32.NewProc("PostQuitMessage") - pRegisterClass = u32.NewProc("RegisterClassExW") - pRegisterWindowMessage = u32.NewProc("RegisterWindowMessageW") - pSetForegroundWindow = u32.NewProc("SetForegroundWindow") - pSetMenuInfo = u32.NewProc("SetMenuInfo") - pSetMenuItemInfo = u32.NewProc("SetMenuItemInfoW") - pShowWindow = u32.NewProc("ShowWindow") - pTrackPopupMenu = u32.NewProc("TrackPopupMenu") - pTranslateMessage = u32.NewProc("TranslateMessage") - pUnregisterClass = u32.NewProc("UnregisterClassW") - pUpdateWindow = u32.NewProc("UpdateWindow") -) - -// Contains window class information. -// It is used with the RegisterClassEx and GetClassInfoEx functions. -// https://msdn.microsoft.com/en-us/library/ms633577.aspx -type wndClassEx struct { - Size, Style uint32 - WndProc uintptr - ClsExtra, WndExtra int32 - Instance, Icon, Cursor, Background windows.Handle - MenuName, ClassName *uint16 - IconSm windows.Handle -} - -// Registers a window class for subsequent use in calls to the CreateWindow or CreateWindowEx function. -// https://msdn.microsoft.com/en-us/library/ms633587.aspx -func (w *wndClassEx) register() error { - w.Size = uint32(unsafe.Sizeof(*w)) - res, _, err := pRegisterClass.Call(uintptr(unsafe.Pointer(w))) - if res == 0 { - return err - } - return nil -} - -// Unregisters a window class, freeing the memory required for the class. -// https://msdn.microsoft.com/en-us/library/ms644899.aspx -func (w *wndClassEx) unregister() error { - res, _, err := pUnregisterClass.Call( - uintptr(unsafe.Pointer(w.ClassName)), - uintptr(w.Instance), - ) - if res == 0 { - return err - } - return nil -} - -// Contains information that the system needs to display notifications in the notification area. -// Used by Shell_NotifyIcon. -// https://msdn.microsoft.com/en-us/library/windows/desktop/bb773352(v=vs.85).aspx -// https://msdn.microsoft.com/en-us/library/windows/desktop/bb762159 -type notifyIconData struct { - Size uint32 - Wnd windows.Handle - ID, Flags, CallbackMessage uint32 - Icon windows.Handle - Tip [128]uint16 - State, StateMask uint32 - Info [256]uint16 - Timeout, Version uint32 - InfoTitle [64]uint16 - InfoFlags uint32 - GuidItem windows.GUID - BalloonIcon windows.Handle -} - -func (nid *notifyIconData) add() error { - const NIM_ADD = 0x00000000 - res, _, err := pShellNotifyIcon.Call( - uintptr(NIM_ADD), - uintptr(unsafe.Pointer(nid)), - ) - if res == 0 { - return err - } - return nil -} - -func (nid *notifyIconData) modify() error { - const NIM_MODIFY = 0x00000001 - res, _, err := pShellNotifyIcon.Call( - uintptr(NIM_MODIFY), - uintptr(unsafe.Pointer(nid)), - ) - if res == 0 { - return err - } - return nil -} - -func (nid *notifyIconData) delete() error { - const NIM_DELETE = 0x00000002 - res, _, err := pShellNotifyIcon.Call( - uintptr(NIM_DELETE), - uintptr(unsafe.Pointer(nid)), - ) - if res == 0 { - return err - } - return nil -} - -// Contains information about a menu item. -// https://msdn.microsoft.com/en-us/library/windows/desktop/ms647578(v=vs.85).aspx -type menuItemInfo struct { - Size, Mask, Type, State uint32 - ID uint32 - SubMenu, Checked, Unchecked windows.Handle - ItemData uintptr - TypeData *uint16 - Cch uint32 - Item windows.Handle -} - -// The POINT structure defines the x- and y- coordinates of a point. -// https://msdn.microsoft.com/en-us/library/windows/desktop/dd162805(v=vs.85).aspx -type point struct { - X, Y int32 -} - -// Contains information about loaded resources -type winTray struct { - instance, - icon, - cursor, - window, - menu windows.Handle - - loadedImages map[string]windows.Handle - nid *notifyIconData - wcex *wndClassEx - - wmSystrayMessage, - wmTaskbarCreated uint32 - - visibleItems []uint32 -} - -// Loads an image from file and shows it in tray. -// LoadImage: https://msdn.microsoft.com/en-us/library/windows/desktop/ms648045(v=vs.85).aspx -// Shell_NotifyIcon: https://msdn.microsoft.com/en-us/library/windows/desktop/bb762159(v=vs.85).aspx -func (t *winTray) setIcon(src string) error { - const IMAGE_ICON = 1 // Loads an icon - const LR_LOADFROMFILE = 0x00000010 // Loads the stand-alone image from the file - const NIF_ICON = 0x00000002 - - // Save and reuse handles of loaded images - h, ok := t.loadedImages[src] - if !ok { - srcPtr, err := windows.UTF16PtrFromString(src) - if err != nil { - return err - } - res, _, err := pLoadImage.Call( - 0, - uintptr(unsafe.Pointer(srcPtr)), - IMAGE_ICON, - 64, - 64, - LR_LOADFROMFILE, - ) - if res == 0 { - return err - } - h = windows.Handle(res) - t.loadedImages[src] = h - } - - t.nid.Icon = h - t.nid.Flags |= NIF_ICON - t.nid.Size = uint32(unsafe.Sizeof(*t.nid)) - - return t.nid.modify() -} - -// Sets tooltip on icon. -// Shell_NotifyIcon: https://msdn.microsoft.com/en-us/library/windows/desktop/bb762159(v=vs.85).aspx -func (t *winTray) setTooltip(src string) error { - const NIF_TIP = 0x00000004 - b, err := windows.UTF16FromString(src) - if err != nil { - return err - } - copy(t.nid.Tip[:], b[:]) - t.nid.Flags |= NIF_TIP - t.nid.Size = uint32(unsafe.Sizeof(*t.nid)) - - return t.nid.modify() -} - -var wt winTray - -// WindowProc callback function that processes messages sent to a window. -// https://msdn.microsoft.com/en-us/library/windows/desktop/ms633573(v=vs.85).aspx -func (t *winTray) wndProc(hWnd windows.Handle, message uint32, wParam, lParam uintptr) (lResult uintptr) { - const ( - WM_COMMAND = 0x0111 - WM_DESTROY = 0x0002 - WM_ENDSESSION = 0x16 - WM_RBUTTONUP = 0x0205 - WM_LBUTTONUP = 0x0202 - ) - switch message { - case WM_COMMAND: - menuId := int32(wParam) - if menuId != -1 { - systrayMenuItemSelected(menuId) - } - case WM_DESTROY: - // same as WM_ENDSESSION, but throws 0 exit code after all - defer pPostQuitMessage.Call(uintptr(int32(0))) - fallthrough - case WM_ENDSESSION: - if t.nid != nil { - t.nid.delete() - } - systrayExit() - case t.wmSystrayMessage: - switch lParam { - case WM_RBUTTONUP, WM_LBUTTONUP: - t.showMenu() - } - case t.wmTaskbarCreated: // on explorer.exe restarts - t.nid.add() - default: - // Calls the default window procedure to provide default processing for any window messages that an application does not process. - // https://msdn.microsoft.com/en-us/library/windows/desktop/ms633572(v=vs.85).aspx - lResult, _, _ = pDefWindowProc.Call( - uintptr(hWnd), - uintptr(message), - uintptr(wParam), - uintptr(lParam), - ) - } - return -} - -func (t *winTray) initInstance() error { - const IDI_APPLICATION = 32512 - const IDC_ARROW = 32512 // Standard arrow - // https://msdn.microsoft.com/en-us/library/windows/desktop/ms633548(v=vs.85).aspx - const SW_HIDE = 0 - const CW_USEDEFAULT = 0x80000000 - // https://msdn.microsoft.com/en-us/library/windows/desktop/ms632600(v=vs.85).aspx - const ( - WS_CAPTION = 0x00C00000 - WS_MAXIMIZEBOX = 0x00010000 - WS_MINIMIZEBOX = 0x00020000 - WS_OVERLAPPED = 0x00000000 - WS_SYSMENU = 0x00080000 - WS_THICKFRAME = 0x00040000 - - WS_OVERLAPPEDWINDOW = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX - ) - // https://msdn.microsoft.com/en-us/library/windows/desktop/ff729176 - const ( - CS_HREDRAW = 0x0002 - CS_VREDRAW = 0x0001 - ) - const NIF_MESSAGE = 0x00000001 - - // https://msdn.microsoft.com/en-us/library/windows/desktop/ms644931(v=vs.85).aspx - const WM_USER = 0x0400 - - const ( - className = "SystrayClass" - windowName = "" - ) - - t.wmSystrayMessage = WM_USER + 1 - - taskbarEventNamePtr, _ := windows.UTF16PtrFromString("TaskbarCreated") - // https://msdn.microsoft.com/en-us/library/windows/desktop/ms644947 - res, _, err := pRegisterWindowMessage.Call( - uintptr(unsafe.Pointer(taskbarEventNamePtr)), - ) - t.wmTaskbarCreated = uint32(res) - - t.loadedImages = make(map[string]windows.Handle) - - instanceHandle, _, err := pGetModuleHandle.Call(0) - if instanceHandle == 0 { - return err - } - t.instance = windows.Handle(instanceHandle) - - // https://msdn.microsoft.com/en-us/library/windows/desktop/ms648072(v=vs.85).aspx - iconHandle, _, err := pLoadIcon.Call(0, uintptr(IDI_APPLICATION)) - if iconHandle == 0 { - return err - } - t.icon = windows.Handle(iconHandle) - - // https://msdn.microsoft.com/en-us/library/windows/desktop/ms648391(v=vs.85).aspx - cursorHandle, _, err := pLoadCursor.Call(0, uintptr(IDC_ARROW)) - if cursorHandle == 0 { - return err - } - t.cursor = windows.Handle(cursorHandle) - - classNamePtr, err := windows.UTF16PtrFromString(className) - if err != nil { - return err - } - - windowNamePtr, err := windows.UTF16PtrFromString(windowName) - if err != nil { - return err - } - - t.wcex = &wndClassEx{ - Style: CS_HREDRAW | CS_VREDRAW, - WndProc: windows.NewCallback(t.wndProc), - Instance: t.instance, - Icon: t.icon, - Cursor: t.cursor, - Background: windows.Handle(6), // (COLOR_WINDOW + 1) - ClassName: classNamePtr, - IconSm: t.icon, - } - if err := t.wcex.register(); err != nil { - return err - } - - windowHandle, _, err := pCreateWindowEx.Call( - uintptr(0), - uintptr(unsafe.Pointer(classNamePtr)), - uintptr(unsafe.Pointer(windowNamePtr)), - uintptr(WS_OVERLAPPEDWINDOW), - uintptr(CW_USEDEFAULT), - uintptr(CW_USEDEFAULT), - uintptr(CW_USEDEFAULT), - uintptr(CW_USEDEFAULT), - uintptr(0), - uintptr(0), - uintptr(t.instance), - uintptr(0), - ) - if windowHandle == 0 { - return err - } - t.window = windows.Handle(windowHandle) - - pShowWindow.Call( - uintptr(t.window), - uintptr(SW_HIDE), - ) - - pUpdateWindow.Call( - uintptr(t.window), - ) - - t.nid = ¬ifyIconData{ - Wnd: windows.Handle(t.window), - ID: 100, - Flags: NIF_MESSAGE, - CallbackMessage: t.wmSystrayMessage, - } - t.nid.Size = uint32(unsafe.Sizeof(*t.nid)) - - return t.nid.add() -} - -func (t *winTray) createMenu() error { - const MIM_APPLYTOSUBMENUS = 0x80000000 // Settings apply to the menu and all of its submenus - - menuHandle, _, err := pCreatePopupMenu.Call() - if menuHandle == 0 { - return err - } - t.menu = windows.Handle(menuHandle) - - // https://msdn.microsoft.com/en-us/library/windows/desktop/ms647575(v=vs.85).aspx - mi := struct { - Size, Mask, Style, Max uint32 - Background windows.Handle - ContextHelpID uint32 - MenuData uintptr - }{ - Mask: MIM_APPLYTOSUBMENUS, - } - mi.Size = uint32(unsafe.Sizeof(mi)) - - res, _, err := pSetMenuInfo.Call( - uintptr(t.menu), - uintptr(unsafe.Pointer(&mi)), - ) - if res == 0 { - return err - } - return nil -} - -func (t *winTray) addOrUpdateMenuItem(menuId int32, title string, disabled, checked bool) error { - // https://msdn.microsoft.com/en-us/library/windows/desktop/ms647578(v=vs.85).aspx - const ( - MIIM_FTYPE = 0x00000100 - MIIM_STRING = 0x00000040 - MIIM_ID = 0x00000002 - MIIM_STATE = 0x00000001 - ) - const MFT_STRING = 0x00000000 - const ( - MFS_CHECKED = 0x00000008 - MFS_DISABLED = 0x00000003 - ) - titlePtr, err := windows.UTF16PtrFromString(title) - if err != nil { - return err - } - - mi := menuItemInfo{ - Mask: MIIM_FTYPE | MIIM_STRING | MIIM_ID | MIIM_STATE, - Type: MFT_STRING, - ID: uint32(menuId), - TypeData: titlePtr, - Cch: uint32(len(title)), - } - if disabled { - mi.State |= MFS_DISABLED - } - if checked { - mi.State |= MFS_CHECKED - } - mi.Size = uint32(unsafe.Sizeof(mi)) - - // We set the menu item info based on the menuID - res, _, err := pSetMenuItemInfo.Call( - uintptr(t.menu), - uintptr(menuId), - 0, - uintptr(unsafe.Pointer(&mi)), - ) - - if res == 0 { - t.addToVisibleItems(menuId) - position := t.getVisibleItemIndex(menuId) - res, _, err = pInsertMenuItem.Call( - uintptr(t.menu), - uintptr(position), - 1, - uintptr(unsafe.Pointer(&mi)), - ) - if res == 0 { - t.delFromVisibleItems(menuId) - return err - } - } - - return nil -} - -func (t *winTray) addSeparatorMenuItem(menuId int32) error { - // https://msdn.microsoft.com/en-us/library/windows/desktop/ms647578(v=vs.85).aspx - const ( - MIIM_FTYPE = 0x00000100 - MIIM_ID = 0x00000002 - MIIM_STATE = 0x00000001 - ) - const MFT_SEPARATOR = 0x00000800 - - mi := menuItemInfo{ - Mask: MIIM_FTYPE | MIIM_ID | MIIM_STATE, - Type: MFT_SEPARATOR, - ID: uint32(menuId), - } - - mi.Size = uint32(unsafe.Sizeof(mi)) - - t.addToVisibleItems(menuId) - position := t.getVisibleItemIndex(menuId) - - res, _, err := pInsertMenuItem.Call( - uintptr(t.menu), - uintptr(position), - 1, - uintptr(unsafe.Pointer(&mi)), - ) - if res == 0 { - return err - } - - return nil -} - -func (t *winTray) hideMenuItem(menuId int32) error { - // https://msdn.microsoft.com/en-us/library/windows/desktop/ms647629(v=vs.85).aspx - const MF_BYCOMMAND = 0x00000000 - const ERROR_SUCCESS syscall.Errno = 0 - - res, _, err := pDeleteMenu.Call( - uintptr(t.menu), - uintptr(uint32(menuId)), - MF_BYCOMMAND, - ) - if res == 0 && err.(syscall.Errno) != ERROR_SUCCESS { - return err - } - t.delFromVisibleItems(menuId) - - return nil -} - -func (t *winTray) showMenu() error { - const ( - TPM_BOTTOMALIGN = 0x0020 - TPM_LEFTALIGN = 0x0000 - ) - p := point{} - res, _, err := pGetCursorPos.Call(uintptr(unsafe.Pointer(&p))) - if res == 0 { - return err - } - pSetForegroundWindow.Call(uintptr(t.window)) - - res, _, err = pTrackPopupMenu.Call( - uintptr(t.menu), - TPM_BOTTOMALIGN|TPM_LEFTALIGN, - uintptr(p.X), - uintptr(p.Y), - 0, - uintptr(t.window), - 0, - ) - if res == 0 { - return err - } - - return nil -} - -func (t *winTray) delFromVisibleItems(val int32) { - for i, itemval := range t.visibleItems { - if uint32(val) == itemval { - t.visibleItems = append(t.visibleItems[:i], t.visibleItems[i+1:]...) - break - } - } -} - -func (t *winTray) addToVisibleItems(val int32) { - newvisible := append(t.visibleItems, uint32(val)) - sort.Slice(newvisible, func(i, j int) bool { return newvisible[i] < newvisible[j] }) - t.visibleItems = newvisible -} - -func (t *winTray) getVisibleItemIndex(val int32) int { - for i, itemval := range t.visibleItems { - if uint32(val) == itemval { - return i - } - } - return -1 -} - -func nativeLoop() { - if err := wt.initInstance(); err != nil { - log.Errorf("Unable to init instance: %v", err) - return - } - - if err := wt.createMenu(); err != nil { - log.Errorf("Unable to create menu: %v", err) - return - } - - defer func() { - pDestroyWindow.Call(uintptr(wt.window)) - wt.wcex.unregister() - }() - - go systrayReady() - - // Main message pump. - m := &struct { - WindowHandle windows.Handle - Message uint32 - Wparam uintptr - Lparam uintptr - Time uint32 - Pt point - }{} - for { - ret, _, err := pGetMessage.Call(uintptr(unsafe.Pointer(m)), 0, 0, 0) - - // If the function retrieves a message other than WM_QUIT, the return value is nonzero. - // If the function retrieves the WM_QUIT message, the return value is zero. - // If there is an error, the return value is -1 - // https://msdn.microsoft.com/en-us/library/windows/desktop/ms644936(v=vs.85).aspx - switch int32(ret) { - case -1: - log.Errorf("Error at message loop: %v", err) - return - case 0: - return - default: - pTranslateMessage.Call(uintptr(unsafe.Pointer(m))) - pDispatchMessage.Call(uintptr(unsafe.Pointer(m))) - } - } -} - -func quit() { - const WM_CLOSE = 0x0010 - - pPostMessage.Call( - uintptr(wt.window), - WM_CLOSE, - 0, - 0, - ) -} - -// SetIcon sets the systray icon. -// iconBytes should be the content of .ico for windows and .ico/.jpg/.png -// for other platforms. -func SetIcon(iconBytes []byte) { - bh := md5.Sum(iconBytes) - dataHash := hex.EncodeToString(bh[:]) - iconFilePath := filepath.Join(os.TempDir(), "systray_temp_icon_"+dataHash) - - if _, err := os.Stat(iconFilePath); os.IsNotExist(err) { - if err := ioutil.WriteFile(iconFilePath, iconBytes, 0644); err != nil { - log.Errorf("Unable to write icon data to temp file: %v", err) - return - } - } - - if err := wt.setIcon(iconFilePath); err != nil { - log.Errorf("Unable to set icon: %v", err) - return - } -} - -// SetTitle sets the systray title, only available on Mac. -func SetTitle(title string) { - // do nothing -} - -// SetIcon sets the icon of a menu item. Only available on Mac. -func (item *MenuItem) SetIcon(iconBytes []byte) { - // do nothing -} - -// SetTooltip sets the systray tooltip to display on mouse hover of the tray icon, -// only available on Mac and Windows. -func SetTooltip(tooltip string) { - if err := wt.setTooltip(tooltip); err != nil { - log.Errorf("Unable to set tooltip: %v", err) - return - } -} - -func addOrUpdateMenuItem(item *MenuItem) { - err := wt.addOrUpdateMenuItem(item.id, item.title, item.disabled, item.checked) - if err != nil { - log.Errorf("Unable to addOrUpdateMenuItem: %v", err) - return - } -} - -func addSeparator(id int32) { - err := wt.addSeparatorMenuItem(id) - if err != nil { - log.Errorf("Unable to addSeparator: %v", err) - return - } -} - -func hideMenuItem(item *MenuItem) { - err := wt.hideMenuItem(item.id) - if err != nil { - log.Errorf("Unable to hideMenuItem: %v", err) - return - } -} - -func showMenuItem(item *MenuItem) { - addOrUpdateMenuItem(item) -} diff --git a/vendor/github.com/getlantern/systray/systray_windows_test.go b/vendor/github.com/getlantern/systray/systray_windows_test.go deleted file mode 100644 index 7cb6c75..0000000 --- a/vendor/github.com/getlantern/systray/systray_windows_test.go +++ /dev/null @@ -1,132 +0,0 @@ -// +build windows - -package systray - -import ( - "io/ioutil" - "runtime" - "sync/atomic" - "testing" - "time" - "unsafe" - - "golang.org/x/sys/windows" -) - -const iconFilePath = "example/icon/iconwin.ico" - -func TestBaseWindowsTray(t *testing.T) { - systrayReady = func() {} - systrayExit = func() {} - - runtime.LockOSThread() - - if err := wt.initInstance(); err != nil { - t.Fatalf("initInstance failed: %s", err) - } - - if err := wt.createMenu(); err != nil { - t.Fatalf("createMenu failed: %s", err) - } - - defer func() { - pDestroyWindow.Call(uintptr(wt.window)) - wt.wcex.unregister() - }() - - if err := wt.setIcon(iconFilePath); err != nil { - t.Errorf("SetIcon failed: %s", err) - } - - if err := wt.setTooltip("Cyrillic tooltip тест:)"); err != nil { - t.Errorf("SetIcon failed: %s", err) - } - - var id int32 = 0 - err := wt.addOrUpdateMenuItem(atomic.AddInt32(&id, 1), "Simple enabled", false, false) - if err != nil { - t.Errorf("mergeMenuItem failed: %s", err) - } - err = wt.addOrUpdateMenuItem(atomic.AddInt32(&id, 1), "Simple disabled", true, false) - if err != nil { - t.Errorf("mergeMenuItem failed: %s", err) - } - err = wt.addSeparatorMenuItem(atomic.AddInt32(&id, 1)) - if err != nil { - t.Errorf("addSeparatorMenuItem failed: %s", err) - } - err = wt.addOrUpdateMenuItem(atomic.AddInt32(&id, 1), "Simple checked enabled", false, true) - if err != nil { - t.Errorf("mergeMenuItem failed: %s", err) - } - err = wt.addOrUpdateMenuItem(atomic.AddInt32(&id, 1), "Simple checked disabled", true, true) - if err != nil { - t.Errorf("mergeMenuItem failed: %s", err) - } - - err = wt.hideMenuItem(1) - if err != nil { - t.Errorf("hideMenuItem failed: %s", err) - } - - err = wt.hideMenuItem(100) - if err == nil { - t.Error("hideMenuItem failed: must return error on invalid item id") - } - - err = wt.addOrUpdateMenuItem(2, "Simple disabled update", true, false) - if err != nil { - t.Errorf("mergeMenuItem failed: %s", err) - } - - time.AfterFunc(1*time.Second, quit) - - m := struct { - WindowHandle windows.Handle - Message uint32 - Wparam uintptr - Lparam uintptr - Time uint32 - Pt point - }{} - for { - ret, _, err := pGetMessage.Call(uintptr(unsafe.Pointer(&m)), 0, 0, 0) - res := int32(ret) - if res == -1 { - t.Errorf("win32 GetMessage failed: %v", err) - return - } else if res == 0 { - break - } - pTranslateMessage.Call(uintptr(unsafe.Pointer(&m))) - pDispatchMessage.Call(uintptr(unsafe.Pointer(&m))) - } -} - -func TestWindowsRun(t *testing.T) { - onReady := func() { - b, err := ioutil.ReadFile(iconFilePath) - if err != nil { - t.Fatalf("Can't load icon file: %v", err) - } - SetIcon(b) - SetTitle("Test title с кириллицей") - - bSomeBtn := AddMenuItem("Йа кнопко", "") - bSomeBtn.Check() - AddSeparator() - bQuit := AddMenuItem("Quit", "Quit the whole app") - go func() { - <-bQuit.ClickedCh - t.Log("Quit reqested") - Quit() - }() - time.AfterFunc(1*time.Second, Quit) - } - - onExit := func() { - t.Log("Exit success") - } - - Run(onReady, onExit) -} -- cgit v1.2.3