summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Walzer <kw@codebykevin.com>2020-10-20 02:12:21 (GMT)
committerKevin Walzer <kw@codebykevin.com>2020-10-20 02:12:21 (GMT)
commit1752aa31f611b6517d2f99596bc97cf9cdab0671 (patch)
treeb80242b6b2d0392f6545beff9dbebe86e2899440
parente602f49377f47a8ea74ea71dd0de9fd79158aa79 (diff)
downloadtk-1752aa31f611b6517d2f99596bc97cf9cdab0671.zip
tk-1752aa31f611b6517d2f99596bc97cf9cdab0671.tar.gz
tk-1752aa31f611b6517d2f99596bc97cf9cdab0671.tar.bz2
Tentative implementation of button-1 and button-2 bindings; still need to test on Win and X11
-rw-r--r--library/systray.tcl77
-rw-r--r--macosx/tkMacOSXSysTray.c153
2 files changed, 148 insertions, 82 deletions
diff --git a/library/systray.tcl b/library/systray.tcl
index b7a5ac0..4e9aab8 100644
--- a/library/systray.tcl
+++ b/library/systray.tcl
@@ -37,9 +37,15 @@ proc _balloon_show {w arg} {
# Additional infrastructure for Windows callbacks.
proc _win_callback {msg icn script} {
+ global _cb_1
+ global _cb_2
+
switch -exact -- $msg {
WM_LBUTTONDOWN {
- eval $script
+ eval $_cb2
+ }
+ WM_RBUTTONDOWN {
+ eval $cb_1
}
}
}
@@ -110,6 +116,10 @@ global _ico
set _ico ""
global _iconlist
set _iconlist {}
+global _cb_1
+set _cb_1 ""
+global _cb_2
+set _cb_2 ""
# systray --
# This procedure creates an icon display in the platform-specific system tray.
@@ -120,12 +130,15 @@ set _iconlist {}
# Arguments:
# image - Tk image to display.
# text - string to display in tooltip over image.
-# callback - Tcl proc to invoke on <Button-1> event.
+# b1_callback - Tcl proc to invoke on <Button-1> event.
+# b2_callback - Tcl proc to invoke on <Button-2> event.
+
# modify - change one of the systray properties.
# Arguments (only one required):
# image - Tk image to update.
# text - string to update.
-# callback - Tcl proc to change.
+# b1_callback - Tcl proc to change.
+# b2_callback - Tcl proc to change.
# destroy - destroy systray icon.
# Arguments:
# none.
@@ -142,11 +155,14 @@ proc ::tk::systray {args} {
#Set variables for icon properties.
global _ico
- global _iconlist
+ global _iconlist
+ global _cb_1
+ global _cb_2
set _img ""
set _txt ""
- set _cb ""
+ set _cb_1 ""
+ set _cb_2 ""
#Remove the systray icon.
if {[lindex $args 0] eq "destroy" && [llength $args] == 1} {
@@ -170,12 +186,13 @@ proc ::tk::systray {args} {
#Create the system tray icon.
if {[lindex $args 0] eq "create"} {
- if {[llength $args] != 4} {
- error "wrong # args: should be \"tk systray create image ?text? ?callback?\""
+ if {[llength $args] != 5} {
+ error "wrong # args: should be \"tk systray create image ?text? ?b1_callback? b2_callback?\""
}
set _img [lindex $args 1]
set _txt [lindex $args 2]
- set _cb [lindex $args 3]
+ set _cb_1 [lindex $args 3]
+ set _cb_2 [lindex $args 4]
switch -- [tk windowingsystem] {
"win32" {
if {[llength $_iconlist] > 0} {
@@ -183,7 +200,7 @@ proc ::tk::systray {args} {
icon supported per interpeter"
}
set _ico [_systray createfrom $_img]
- _systray taskbar add $_ico -text $_txt -callback [list _win_callback %m %i $_cb]
+ _systray taskbar add $_ico -text $_txt -callback [list _win_callback %m %i]
lappend _iconlist "ico#[llength _iconlist]"
}
"x11" {
@@ -194,17 +211,18 @@ proc ::tk::systray {args} {
set _ico $_img
_systray ._tray -image $_img -visible true
_balloon ._tray $_txt
- bind ._tray <Button-1> $_cb
+ bind ._tray <Button-1> $_cb_1
+ bind ._tray <Button-2> $_cb_2
}
"aqua" {
- _systray create $_img $_txt $_cb
+ _systray create $_img $_txt $_cb_1 $_cb_2
}
}
}
#Modify the system tray icon properties.
if {[lindex $args 0] eq "modify"} {
if {[llength $args] != 3} {
- error "wrong # args: \"tk systray modify image | text | callback option?\""
+ error "wrong # args: \"tk systray modify image | text | b1_callback | b2_callback option?\""
}
switch -- [tk windowingsystem] {
"win32" {
@@ -212,16 +230,21 @@ proc ::tk::systray {args} {
set _img [lindex $args 2]
_systray taskbar delete $_ico
set _ico [_systray createfrom $_img]
- _systray taskbar add $_ico -text $_txt -callback [list _win_callback %m %i $_cb]
+ _systray taskbar add $_ico -text $_txt -callback [list _win_callback %m %i]
}
if {[lindex $args 1] eq "text"} {
set _txt [lindex $args 2]
_systray taskbar modify $_ico -text $_txt
}
- if {[lindex $args 1 ] eq "callback"} {
- set _cb [lindex $args 2]
- _systray taskbar modify $_ico -callback [list _win_callback %m %i $_cb]
+ if {[lindex $args 1 ] eq "b1_callback"} {
+ set _cb_1 [lindex $args 2]
+ _systray taskbar modify $_ico -callback [list _win_callback %m %i]
}
+ if {[lindex $args 1 ] eq "b2_callback"} {
+ set _cb_2 [lindex $args 2]
+ _systray taskbar modify $_ico -callback [list _win_callback %m %i]
+ }
+
}
"x11" {
if {[lindex $args 1] eq "image"} {
@@ -235,11 +258,17 @@ proc ::tk::systray {args} {
set _txt [lindex $args 2]
_balloon ._tray $_txt
}
- if {[lindex $args 1 ] eq "callback"} {
- set _cb ""
+ if {[lindex $args 1 ] eq "b1_callback"} {
+ set _cb_1 ""
bind ._tray <Button-1> ""
- set _cb [lindex $args 2]
- bind ._tray <Button-1> $_cb
+ set _cb_1 [lindex $args 2]
+ bind ._tray <Button-1> $_cb_1
+ }
+ if {[lindex $args 1 ] eq "b2_callback"} {
+ set _cb_2 ""
+ bind ._tray <Button-1> ""
+ set _cb_2 [lindex $args 2]
+ bind ._tray <Button-1> $_cb_2
}
}
"aqua" {
@@ -251,9 +280,13 @@ proc ::tk::systray {args} {
set _txt [lindex $args 2]
_systray modify text $_txt
}
- if {[lindex $args 1 ] eq "callback"} {
+ if {[lindex $args 1 ] eq "b1_callback"} {
+ set _cb [lindex $args 2]
+ _systray modify callback $_cb_1
+ }
+ if {[lindex $args 1 ] eq "b2_callback"} {
set _cb [lindex $args 2]
- _systray modify callback $_cb
+ _systray modify callback $_cb_2
}
}
}
diff --git a/macosx/tkMacOSXSysTray.c b/macosx/tkMacOSXSysTray.c
index 63e9b6c..7b9a897 100644
--- a/macosx/tkMacOSXSysTray.c
+++ b/macosx/tkMacOSXSysTray.c
@@ -27,13 +27,15 @@ static const char ASSOC_KEY[] = "tk::tktray";
NSImage * icon;
NSString * tooltip;
Tcl_Interp * interp;
- Tcl_Obj * callback;
+ Tcl_Obj * b1_callback;
+ Tcl_Obj * b2_callback;
}
- (id) init : (Tcl_Interp *) interp;
- (void) setImagewithImage : (NSImage *) image;
- (void) setTextwithString : (NSString *) string;
-- (void) setCallback : (Tcl_Obj *) callback;
+- (void) setB1Callback : (Tcl_Obj *) callback;
+- (void) setB2Callback : (Tcl_Obj *) callback;
- (void) clickOnStatusItem: (id) sender;
- (void) dealloc;
@@ -48,9 +50,11 @@ static const char ASSOC_KEY[] = "tk::tktray";
statusItem = [[statusBar statusItemWithLength:NSVariableStatusItemLength] retain];
statusItem.button.target = self;
statusItem.button.action = @selector(clickOnStatusItem: );
+ [statusItem.button sendActionOn : NSEventMaskLeftMouseUp | NSEventMaskRightMouseUp];
statusItem.visible = YES;
interp = interpreter;
- callback = NULL;
+ b1_callback = NULL;
+ b2_callback = NULL;
return self;
}
@@ -68,30 +72,48 @@ static const char ASSOC_KEY[] = "tk::tktray";
statusItem.button.toolTip = tooltip;
}
-- (void) setCallback : (Tcl_Obj *) obj
+- (void) setB1Callback : (Tcl_Obj *) obj
{
if (obj != NULL) {
Tcl_IncrRefCount(obj);
}
- if (callback != NULL) {
- Tcl_DecrRefCount(callback);
+ if (b1_callback != NULL) {
+ Tcl_DecrRefCount(b1_callback);
}
- callback = obj;
+ b1_callback = obj;
+}
+
+- (void) setB2Callback : (Tcl_Obj *) obj
+{
+ if (obj != NULL) {
+ Tcl_IncrRefCount(obj);
+ }
+ if (b2_callback != NULL) {
+ Tcl_DecrRefCount(b1_callback);
+ }
+ b2_callback = obj;
}
- (void) clickOnStatusItem: (id) sender
{
- if ((NSApp.currentEvent.clickCount == 1) && (callback != NULL)) {
- int result = Tcl_EvalObjEx(interp, callback, TCL_EVAL_GLOBAL);
+ NSEvent *event = [NSApp currentEvent];
+ if (([event type] == NSEventTypeLeftMouseUp) && (b1_callback != NULL)) {
+ int result = Tcl_EvalObjEx(interp, b1_callback, TCL_EVAL_GLOBAL);
if (result != TCL_OK) {
Tcl_BackgroundException(interp, result);
}
- }
+ } else {
+ if (([event type] == NSEventTypeRightMouseUp) && (b2_callback != NULL)) {
+ int result = Tcl_EvalObjEx(interp, b2_callback, TCL_EVAL_GLOBAL);
+ if (result != TCL_OK) {
+ Tcl_BackgroundException(interp, result);
+ }
+ }
+}
}
-
- (void) dealloc
{
- /*
+ /*
* We are only doing the minimal amount of deallocation that
* the superclass cannot handle when it is deallocated, per
* https://developer.apple.com/documentation/objectivec/nsobject/
@@ -100,8 +122,11 @@ static const char ASSOC_KEY[] = "tk::tktray";
* in the Tk test suite.
*/
[statusBar removeStatusItem: statusItem];
- if (callback != NULL) {
- Tcl_DecrRefCount(callback);
+ if (b1_callback != NULL) {
+ Tcl_DecrRefCount(b1_callback);
+ }
+ if (b2_callback != NULL) {
+ Tcl_DecrRefCount(b2_callback);
}
}
@@ -121,7 +146,7 @@ static const char ASSOC_KEY[] = "tk::tktray";
- (id) init;
- (void) postNotificationWithTitle : (NSString *) title message: (NSString *) detail;
- (BOOL) userNotificationCenter:(NSUserNotificationCenter *)center
- shouldPresentNotification:(NSUserNotification *)notification;
+ shouldPresentNotification:(NSUserNotification *)notification;
- (void) dealloc;
@@ -206,28 +231,21 @@ typedef struct {
static int
MacSystrayObjCmd(
- void *clientData,
- Tcl_Interp * interp,
- int objc,
- Tcl_Obj *const *objv)
+ void *clientData,
+ Tcl_Interp * interp,
+ int objc,
+ Tcl_Obj *const *objv)
{
Tk_Image tk_image;
TrayInfo *info = (TrayInfo *)clientData;
int result, idx;
static const char *options[] =
- {"create", "modify", "destroy", NULL};
+ {"create", "modify", "destroy", NULL};
typedef enum {TRAY_CREATE, TRAY_MODIFY, TRAY_DESTROY} optionsEnum;
static const char *modifyOptions[] =
- {"image", "text", "callback", NULL};
- typedef enum {TRAY_IMAGE, TRAY_TEXT, TRAY_CALLBACK} modifyOptionsEnum;
-
- if (info->tk_item == NULL) {
- info->tk_item = [[TkStatusItem alloc] init: interp];
- } else {
- Tcl_AppendResult(interp, "Only one system tray icon supported per interpeter", NULL);
- return TCL_ERROR;
- }
+ {"image", "text", "b1_callback", "b2_callback", NULL};
+ typedef enum {TRAY_IMAGE, TRAY_TEXT, TRAY_B1_CALLBACK, TRAY_B2_CALLBACK} modifyOptionsEnum;
if (objc < 2) {
Tcl_WrongNumArgs(interp, 1, objv, "create | modify | destroy");
@@ -243,8 +261,15 @@ MacSystrayObjCmd(
switch((optionsEnum)idx) {
case TRAY_CREATE: {
- if (objc < 5) {
- Tcl_WrongNumArgs(interp, 1, objv, "create image ?text? ?callback?");
+ if (objc < 6) {
+ Tcl_WrongNumArgs(interp, 1, objv, "create image ?text? ?b1_callback? b2_callback?");
+ return TCL_ERROR;
+ }
+
+ if (info->tk_item == NULL) {
+ info->tk_item = [[TkStatusItem alloc] init: interp];
+ } else {
+ Tcl_AppendResult(interp, "Only one system tray icon supported per interpeter", NULL);
return TCL_ERROR;
}
@@ -287,12 +312,13 @@ MacSystrayObjCmd(
* Set the proc for the callback.
*/
- [info->tk_item setCallback : objv[4]];
+ [info->tk_item setB1Callback : objv[4]];
+ [info->tk_item setB2Callback : objv[5]];
break;
}
case TRAY_MODIFY: {
- if (objc < 4) {
+ if (objc < 5) {
Tcl_WrongNumArgs(interp, 1, objv, "modify object item");
return TCL_ERROR;
}
@@ -350,24 +376,30 @@ MacSystrayObjCmd(
* Modify the proc for the callback.
*/
- case TRAY_CALLBACK: {
- [info->tk_item setCallback : objv[3]];
+ case TRAY_B1_CALLBACK: {
+ [info->tk_item setB1Callback : objv[3]];
+ break;
+ }
+ case TRAY_B2_CALLBACK: {
+ [info->tk_item setB2Callback : objv[4]];
+ break;
}
break;
}
- break;
- }
- case TRAY_DESTROY: {
- /* we don't really distroy, just reset the image, text and callback */
- [info->tk_item setImagewithImage: nil];
- [info->tk_item setTextwithString: nil];
- [info->tk_item setCallback : NULL];
- /* do nothing */
- break;
+
+ case TRAY_DESTROY: {
+ /* we don't really distroy, just reset the image, text and callback */
+ [info->tk_item setImagewithImage: nil];
+ [info->tk_item setTextwithString: nil];
+ [info->tk_item setB1Callback : NULL];
+ [info->tk_item setB2Callback : NULL];
+ // /* do nothing */
+ break;
+ }
+ break;
}
+ return TCL_OK;
}
-
- return TCL_OK;
}
@@ -389,18 +421,18 @@ MacSystrayObjCmd(
static void
MacSystrayDestroy(
- void *clientData,
- TCL_UNUSED(Tcl_Interp *))
+ void *clientData,
+ TCL_UNUSED(Tcl_Interp *))
{
TrayInfo *info = (TrayInfo *)clientData;
if (info->tk_item != NULL) {
- [info->tk_item dealloc];
- info->tk_item = NULL;
+ [info->tk_item dealloc];
+ info->tk_item = NULL;
}
if (info->notify_item != NULL) {
- [info->notify_item dealloc];
- info->notify_item = NULL;
+ [info->notify_item dealloc];
+ info->notify_item = NULL;
}
ckfree(info);
}
@@ -424,12 +456,12 @@ MacSystrayDestroy(
static int SysNotifyObjCmd(
- void *clientData,
- Tcl_Interp * interp,
- int objc,
- Tcl_Obj *const *objv)
+ void *clientData,
+ Tcl_Interp * interp,
+ int objc,
+ Tcl_Obj *const *objv)
{
- TrayInfo *info = (TrayInfo *) clientData;
+ TrayInfo *info = (TrayInfo *) clientData;
if (objc < 3) {
Tcl_WrongNumArgs(interp, 1, objv, "title message");
@@ -465,16 +497,17 @@ static int SysNotifyObjCmd(
*/
int
-MacSystrayInit(Tcl_Interp *interp) {
+MacSystrayInit(Tcl_Interp *interp)
+{
/*
* Initialize TkStatusItem and TkNotifyItem.
*/
- TrayInfo *info = (TrayInfo *)ckalloc(sizeof(TrayInfo));
+ TrayInfo *info = (TrayInfo *)ckalloc(sizeof(TrayInfo));
memset(info, 0, sizeof(TrayInfo));
- Tcl_SetAssocData(interp, ASSOC_KEY, MacSystrayDestroy, info);
+ Tcl_SetAssocData(interp, ASSOC_KEY, MacSystrayDestroy, info);
if ([NSApp macOSVersion] < 101000) {
Tcl_AppendResult(interp, "Statusitem icons not supported on versions of macOS lower than 10.10", NULL);