Coder Social home page Coder Social logo

zserge / tray Goto Github PK

View Code? Open in Web Editor NEW
494.0 20.0 85.0 57 KB

Cross-platform, super tiny C99 implementation of a system tray icon with a popup menu.

License: MIT License

Makefile 4.05% C 95.95%
tray-icon tray-menu cross-platform gtk appindicator

tray's Introduction

Tray

Cross-platform, single header, super tiny C99 implementation of a system tray icon with a popup menu.

Works well on:

  • Linux/Gtk (libappindicator)
  • Windows XP or newer (shellapi.h)
  • MacOS (Cocoa/AppKit)

There is also a stub implementation that returns errors on attempt to create a tray menu.

Setup

Before you can compile tray, you'll need to add an environment definition before the line where you include tray.h.

For Windows:

#include <stdio.h>
#include <string.h>

#define TRAY_WINAPI 1

#include "tray.h"
...

For Linux:

#include <stdio.h>
#include <string.h>

#define TRAY_APPINDICATOR 1

#include "tray.h"
...

For Mac:

#include <stdio.h>
#include <string.h>

#define TRAY_APPKIT 1

#include "tray.h"
...

Demo

The included example .c files can be compiled based on your environment.

For example, to compile and run the program on Windows:

$> gcc example_windows.c [Enter]

This will compile and build a.out. To run it:

$> a [Enter]

Example

struct tray tray = {
    .icon = "icon.png",
    .menu = (struct tray_menu[]){{"Toggle me", 0, 0, toggle_cb, NULL},
                                 {"-", 0, 0, NULL, NULL},
                                 {"Quit", 0, 0, quit_cb, NULL},
                                 {NULL, 0, 0, NULL, NULL}},
};

void toggle_cb(struct tray_menu *item) {
	item->checked = !item->checked;
	tray_update(&tray);
}

void quit_cb(struct tray_menu *item) {
  tray_exit();
}

...

tray_init(&tray);
while (tray_loop(1) == 0);
tray_exit();

API

Tray structure defines an icon and a menu. Menu is a NULL-terminated array of items. Menu item defines menu text, menu checked and disabled (grayed) flags and a callback with some optional context pointer.

struct tray {
  char *icon;
  struct tray_menu *menu;
};

struct tray_menu {
  char *text;
  int disabled;
  int checked;

  void (*cb)(struct tray_menu *);
  void *context;

  struct tray_menu *submenu;
};
  • int tray_init(struct tray *) - creates tray icon. Returns -1 if tray icon/menu can't be created.
  • void tray_update(struct tray *) - updates tray icon and menu.
  • int tray_loop(int blocking) - runs one iteration of the UI loop. Returns -1 if tray_exit() has been called.
  • void tray_exit() - terminates UI loop.

All functions are meant to be called from the UI thread only.

Menu arrays must be terminated with a NULL item, e.g. the last item in the array must have text field set to NULL.

Roadmap

  • Cross-platform tray icon
  • Cross-platform tray popup menu
  • Separators in the menu
  • Disabled/enabled menu items
  • Checked/unchecked menu items
  • Nested menus
  • Icons for menu items
  • Rewrite ObjC code in C using ObjC Runtime (now ObjC code breaks many linters and static analyzers)
  • Call GTK code using dlopen/dlsym (to make binaries run safely if Gtk libraries are not available)

License

This software is distributed under MIT license, so feel free to integrate it in your commercial products.

tray's People

Contributors

angelskieglazki avatar jesselawson avatar jslegendre avatar zserge avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tray's Issues

compatible with new Obj-C runtime

If you can't use -DOBJC_OLD_DISPATCH_PROTOTYPES=1 for whatever reason, I have a patch with objc_MsgSend calls updated to use the syntax compatible with newer versions of Xcode.

This makes the code really ugly so I won't submit it as a pull request, but it works in a pinch. There may be a better way to handle this but this was a sledgehammer approach, I'm no obj-c developer.

There are also a few more fixes for newer versions of macOS upstream in my branch, but this is the one I sense might be the most helpful to other people.

https://github.com/wormyrocks/tray/blob/83fd0df977fc5365713b1eedfcd499c92695bfb6/tray.h

New fork of tray project incorporating many useful fixes

Hello, as @zserge is probably not actively maintaining this repo anymore, I would like to offer a fork, which brings together the great original code by @zserge and the most interesting forks and PRs of their respectable contributors:

Compatibility with GLFW?

Hi,

I'm having trouble getting tray.h to work with a GLFW project - as I understand it, both GLFW and tray.h attach their own AppDelegate to the NSApp instance - so if I call glfwInit() after tray_init(), all the tray callbacks stop working, and if I call tray_init() after glfwInit(), all the GLFW callbacks stop working.

Ideally I want my code to stay as crossplatform (mostly because I have no experience with Objective-C) as possible. So if there's a simple way to fix this without doing too much heavy modification (I don't know if it's possible to attach an additional function to an existing delegate at runtime without clobbering it?) it'd be great to know.

Thanks so much!

doesn't compile

I tried the instructions (on mac):

Undefined symbols for architecture x86_64:
  "_class_addMethod", referenced from:
      _tray_init in main-280cb6.o
  "_class_addProtocol", referenced from:
      _tray_init in main-280cb6.o
  "_objc_allocateClassPair", referenced from:
      _tray_init in main-280cb6.o
  "_objc_getClass", referenced from:
      _tray_update in main-280cb6.o
      _tray_init in main-280cb6.o
      _tray_loop in main-280cb6.o
      __tray_menu in main-280cb6.o
  "_objc_getProtocol", referenced from:
      _tray_init in main-280cb6.o
  "_objc_msgSend", referenced from:
      _tray_update in main-280cb6.o
      _tray_init in main-280cb6.o
      _tray_loop in main-280cb6.o
      __tray_menu in main-280cb6.o
      _tray_exit in main-280cb6.o
      _menu_callback in main-280cb6.o
  "_objc_registerClassPair", referenced from:
      _tray_init in main-280cb6.o
  "_sel_registerName", referenced from:
      _tray_update in main-280cb6.o
      _tray_init in main-280cb6.o
      _tray_loop in main-280cb6.o
      __tray_menu in main-280cb6.o
      _tray_exit in main-280cb6.o
      _menu_callback in main-280cb6.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Ubuntu 18.04 has different pkg-config name for appindicator

On Ubuntu, this won't compile unless I change the Makefile a little.

maple% lsb_release -irc
Distributor ID:	Ubuntu
Release:	18.04
Codename:	bionic

Apparently appindicator3-0.1 is not a valid pkg config.

diff --git a/Makefile b/Makefile
index 483c0aa..d9a1da4 100644
--- a/Makefile
+++ b/Makefile
@@ -2,8 +2,8 @@ ifeq ($(OS),Windows_NT)
        TRAY_CFLAGS := -DTRAY_WINAPI=1
        TRAY_LDFLAGS :=
 else ifeq ($(shell uname -s),Linux)
-       TRAY_CFLAGS := -DTRAY_APPINDICATOR=1 $(shell pkg-config --cflags appindicator3-0.1)
-       TRAY_LDFLAGS := $(shell pkg-config --libs appindicator3-0.1)
+       TRAY_CFLAGS := -DTRAY_APPINDICATOR=1 $(shell pkg-config --cflags appindicator-0.1)
+       TRAY_LDFLAGS := $(shell pkg-config --libs appindicator-0.1)
 else ifeq ($(shell uname -s),Darwin)
        TRAY_CFLAGS := -DTRAY_APPKIT=1
        TRAY_LDFLAGS := -framework Cocoa

I don't think I know enough to make a pull request -- just tossing this info your way.

Cheers on a very cool project!

UTF-8 support for Windows?

While working with this, I realized that e.g. umlauts don't work. (In my case Windows 7)
Based on my research, it would seem that *nix platforms support UTF-8 encoded strings via char* by default?

Anyway, I've already fixed it in my project by converting to UTF-16 directly before making the Windows API calls, so I could submit a PR if you're interested.

C++ problems

I keep having loads of errors in C++. Is there anyway to get around this? Has anyone been successful using this in their projects?

The error I keep receiving is "use of designated initializers requires at least '/std:c++20'".

Is there anyway to fix this? I'm guessing its a syntax error due to it being a c file? When I use the compiled project it works but as soon as I change it to a cpp it doesn't work, which I need as all my code is in C++.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.