139 lines
No EOL
3.6 KiB
HolyC
139 lines
No EOL
3.6 KiB
HolyC
#define SYSTRAY_MSG_NULL 0x0
|
|
#define SYSTRAY_MSG_REGISTER 0x1
|
|
#define SYSTRAY_MSG_UNREGISTER 0x2
|
|
|
|
class @systemtray
|
|
{
|
|
CTask* task;
|
|
@window_widgets_list* item;
|
|
U0 (*Init)();
|
|
U0 (*Task)();
|
|
Context2DWidget* (*RegisterItem)();
|
|
U0 (*UnregisterItem)(Widget* widget);
|
|
U0 (*SetIcon)(Context2DWidget* widget, U8* path);
|
|
};
|
|
|
|
@systemtray SystemTray;
|
|
|
|
U0 @systemtray_register_item(I64 addr)
|
|
{
|
|
Context2DWidget* item = Gui.CreateWidget(
|
|
Compositor.menubar.win, WIDGET_TYPE_CONTEXT2D, -24, 0, 24, 24);
|
|
item->ctx = NewContext2D(item->width, item->height);
|
|
item->ctx->fill(0);
|
|
MemSetI64(addr, item, 1);
|
|
}
|
|
|
|
U0 @systemtray_unregister_item(Widget* item)
|
|
{
|
|
IpcMessage* msg = CAlloc2(sizeof(IpcMessage));
|
|
msg->client = NULL;
|
|
msg->type = CPZ_MSG_WIN_WIDGET_DESTROY;
|
|
msg->payload = item;
|
|
System.Log(Fs, "Sent message → WidgetDestroy");
|
|
Ipc.MsgSend(Compositor.menubar.task, msg);
|
|
}
|
|
|
|
U0 @systemtray_reindex_items()
|
|
{
|
|
I64 x = Display.Width() - 100;
|
|
@window_widgets_list* item = Compositor.menubar.win->widget;
|
|
while (item->next)
|
|
item = item->next;
|
|
while (item->widget->type == WIDGET_TYPE_CONTEXT2D) {
|
|
x -= item->widget->width + 4;
|
|
item->widget->x = x;
|
|
item = item->prev;
|
|
}
|
|
Gui.Window.Refresh(Compositor.menubar.win);
|
|
}
|
|
|
|
U0 @systemtray_ipc_queue_process()
|
|
{
|
|
IpcMessage* msg;
|
|
msg = Ipc.MsgRecv();
|
|
if (msg) {
|
|
switch (msg->type) {
|
|
case SYSTRAY_MSG_REGISTER:
|
|
@systemtray_register_item(msg->payload);
|
|
@systemtray_reindex_items;
|
|
break;
|
|
case SYSTRAY_MSG_UNREGISTER:
|
|
@systemtray_unregister_item(msg->payload);
|
|
@systemtray_reindex_items;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
Free(msg);
|
|
}
|
|
}
|
|
|
|
U0 @systemtray_init() { }
|
|
|
|
U0 @systemtray_task()
|
|
{
|
|
Ipc.InitQueue(Fs);
|
|
SystemTray.task = Fs;
|
|
System.Log(Fs, "Task running at 0x%08x", Fs);
|
|
while (!Compositor.menubar.win) // Wait for instance
|
|
Sleep(1);
|
|
while (1) {
|
|
@systemtray_ipc_queue_process();
|
|
Sleep(1);
|
|
}
|
|
}
|
|
|
|
Context2DWidget* @systemtray_client_register_item()
|
|
{
|
|
Context2DWidget* item = NULL;
|
|
IpcMessage* msg = CAlloc2(sizeof(IpcMessage));
|
|
msg->client = NULL;
|
|
msg->type = SYSTRAY_MSG_REGISTER;
|
|
msg->payload = &item;
|
|
System.Log(Fs, "Sent message → SystrayRegisterItem");
|
|
Ipc.MsgSend(SystemTray.task, msg);
|
|
while (!item)
|
|
Sleep(1);
|
|
return item;
|
|
}
|
|
|
|
U0 @systemtray_client_unregister_item(Widget* item)
|
|
{
|
|
IpcMessage* msg = CAlloc2(sizeof(IpcMessage));
|
|
msg->client = NULL;
|
|
msg->type = SYSTRAY_MSG_UNREGISTER;
|
|
msg->payload = item;
|
|
System.Log(Fs, "Sent message → SystrayUnRegisterItem");
|
|
Ipc.MsgSend(SystemTray.task, msg);
|
|
while (item->type)
|
|
Sleep(1);
|
|
@systemtray_reindex_items;
|
|
}
|
|
|
|
U0 @systemtray_set_icon(Context2DWidget* widget, U8* path)
|
|
{
|
|
if (!widget || !path)
|
|
return;
|
|
U8 full_path[512];
|
|
if (2 == 3) // FIXME
|
|
StrCpy(&full_path, path);
|
|
else {
|
|
StrCpy(&full_path, "M:/Media/Themes/Umami/Icon/");
|
|
String.Append(&full_path, path);
|
|
}
|
|
if (!FileFind(&full_path))
|
|
return;
|
|
Context2D* icon = Image.FileToContext2D(&full_path);
|
|
CopyRect2D(widget->ctx, 0, 0, icon);
|
|
DelContext2D(icon);
|
|
Gui.Window.Refresh(Compositor.menubar.win);
|
|
}
|
|
|
|
SystemTray.Init = &@systemtray_init;
|
|
SystemTray.RegisterItem = &@systemtray_client_register_item;
|
|
SystemTray.SetIcon = &@systemtray_set_icon;
|
|
SystemTray.Task = &@systemtray_task;
|
|
SystemTray.UnregisterItem = &@systemtray_client_unregister_item;
|
|
|
|
"systemtray "; |