This repository has been archived by the owner on Dec 30, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 66
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add basic tray icon implementation for Mac OS
- Loading branch information
1 parent
3a013db
commit 4d7e0c6
Showing
5 changed files
with
123 additions
and
24 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,28 +1,110 @@ | ||
//! Contains the implementation of the Mac OS X tray icon in the top bar. | ||
|
||
use std; | ||
use {SystrayError}; | ||
|
||
use cocoa::appkit::{NSApp, NSApplication, NSButton, NSImage, NSStatusBar, NSStatusItem, | ||
NSSquareStatusItemLength}; | ||
use cocoa::base::{id, nil}; | ||
use cocoa::foundation::{NSData, NSSize, NSAutoreleasePool}; | ||
use libc::c_void; | ||
|
||
use {SystrayEvent, SystrayError}; | ||
|
||
/// The generation representation of the Mac OS X application. | ||
pub struct Window { | ||
/// A mutable reference to the `NSApplication` instance of the currently running application. | ||
application: id, | ||
/// It seems that we have to use `NSAutoreleasePool` to prevent memory leaks. | ||
autorelease_pool: id, | ||
} | ||
|
||
impl Window { | ||
pub fn new() -> Result<Window, SystrayError> { | ||
Err(SystrayError::NotImplementedError) | ||
/// Creates a new instance of the `Window`. | ||
pub fn new(_: std::sync::mpsc::Sender<SystrayEvent>) -> Result<Window, SystrayError> { | ||
Ok(Window { | ||
application: unsafe { NSApp() }, | ||
autorelease_pool: unsafe { NSAutoreleasePool::new(nil) }, | ||
}) | ||
} | ||
|
||
/// Closes the current application. | ||
pub fn quit(&self) { | ||
unsafe { msg_send![self.application, terminate] }; | ||
} | ||
|
||
pub fn shutdown(&self) -> Result<(), SystrayError> { | ||
unimplemented!() | ||
} | ||
|
||
/// Sets the tooltip (not available for this platfor). | ||
pub fn set_tooltip(&self, _: &String) -> Result<(), SystrayError> { | ||
Err(SystrayError::OsError("This operating system does not support tooltips for the tray \ | ||
items".to_owned())) | ||
} | ||
|
||
/// Adds an additional item to the tray icon menu. | ||
pub fn add_menu_entry(&self, _: u32, _: &String) -> Result<u32, SystrayError> { | ||
unimplemented!() | ||
} | ||
pub fn add_menu_item<F>(&self, _: &String, _: F) -> Result<u32, SystrayError> | ||
where F: std::ops::Fn(&Window) -> () + 'static | ||
{ | ||
|
||
pub fn add_menu_separator(&self, _: u32) -> Result<(), SystrayError> { | ||
unimplemented!() | ||
} | ||
pub fn wait_for_message(&mut self) { | ||
|
||
/// Sets the application icon displayed in the tray bar. Accepts a `buffer` to the underlying | ||
/// image, you can pass even encoded PNG images here. Supports the same list of formats as | ||
/// `NSImage`. | ||
pub fn set_icon_from_buffer(&mut self, buffer: &[u8], _: u32, _: u32) | ||
-> Result<(), SystrayError> | ||
{ | ||
const ICON_WIDTH: f64 = 18.0; | ||
const ICON_HEIGHT: f64 = 18.0; | ||
|
||
let tray_entry = unsafe { | ||
NSStatusBar::systemStatusBar(nil).statusItemWithLength_(NSSquareStatusItemLength) | ||
}; | ||
|
||
let nsdata = unsafe { | ||
NSData::dataWithBytes_length_(nil, | ||
buffer.as_ptr() as *const c_void, | ||
buffer.len() as u64).autorelease() | ||
}; | ||
if nsdata == nil { | ||
return Err(SystrayError::OsError("Could not create `NSData` out of the passed buffer" | ||
.to_owned())); | ||
} | ||
|
||
let nsimage = unsafe { NSImage::initWithData_(NSImage::alloc(nil), nsdata).autorelease() }; | ||
if nsimage == nil { | ||
return Err(SystrayError::OsError("Could not create `NSImage` out of the created \ | ||
`NSData` buffer".to_owned())); | ||
} | ||
|
||
unsafe { | ||
let new_size = NSSize::new(ICON_WIDTH, ICON_HEIGHT); | ||
msg_send![nsimage, setSize:new_size]; | ||
tray_entry.button().setImage_(nsimage); | ||
} | ||
|
||
Ok(()) | ||
} | ||
|
||
pub fn set_icon_from_file(&self, _: &String) -> Result<(), SystrayError> { | ||
unimplemented!() | ||
} | ||
pub fn set_icon_from_buffer(&self, _: &[u8], _: u32, _: u32) -> Result<(), SystrayError> { | ||
|
||
pub fn set_icon_from_resource(&self, _: &String) -> Result<(), SystrayError> { | ||
unimplemented!() | ||
} | ||
|
||
/// Starts the application event loop. Calling this function will block the current thread. | ||
pub fn wait_for_message(&mut self) { | ||
unsafe { self.application.run() }; | ||
} | ||
} | ||
|
||
impl Drop for Window { | ||
fn drop(&mut self) { | ||
unsafe { self.autorelease_pool.drain() }; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters