mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-15 22:02:49 -06:00
247 lines
4.7 KiB
C++
247 lines
4.7 KiB
C++
#include "CtrlLib.h"
|
|
|
|
#define LLOG(x) // LOG(x)
|
|
|
|
#ifdef GUI_X11
|
|
|
|
#if !defined(flagNOGTK)
|
|
#include <glib.h>
|
|
#include <libnotify/notify.h>
|
|
#ifdef NOTIFY_CHECK_VERSION
|
|
#if NOTIFY_CHECK_VERSION(0,7,0)
|
|
#define NOTIFY_VERSION_GT_0_7_0
|
|
#endif
|
|
#endif
|
|
#endif
|
|
|
|
namespace Upp {
|
|
|
|
Atom TraySelection()
|
|
{
|
|
return XAtom(Format("_NET_SYSTEM_TRAY_S%d", Xscreenno));
|
|
}
|
|
|
|
void TrayIcon::Call(int code, unsigned long d1, unsigned long d2, unsigned long d3)
|
|
{
|
|
if(!traywin)
|
|
return;
|
|
bool x11trap = TrapX11Errors();
|
|
XEvent e;
|
|
Zero(e);
|
|
e.xclient.data.l[0] = CurrentTime;
|
|
e.xclient.data.l[1] = code;
|
|
e.xclient.data.l[2] = d1;
|
|
e.xclient.data.l[3] = d2;
|
|
e.xclient.data.l[4] = d3;
|
|
e.xclient.window = traywin;
|
|
e.xclient.type = ClientMessage;
|
|
e.xclient.message_type = XAtom("_NET_SYSTEM_TRAY_OPCODE");
|
|
e.xclient.format = 32;
|
|
XSendEvent(Xdisplay, traywin, XFalse, 0, &e);
|
|
XSync(Xdisplay, XFalse);
|
|
UntrapX11Errors(x11trap);
|
|
}
|
|
|
|
void TrayIcon::AddToTray()
|
|
{
|
|
Hide();
|
|
traywin = XGetSelectionOwner(Xdisplay, TraySelection());
|
|
if(!traywin) return;
|
|
|
|
XSelectInput(Xdisplay, traywin, StructureNotifyMask);
|
|
XWindowAttributes attr;
|
|
XGetWindowAttributes(Xdisplay, Xroot, &attr);
|
|
XSelectInput(Xdisplay, Xroot, attr.your_event_mask | StructureNotifyMask);
|
|
|
|
Window win = GetWindow();
|
|
XSizeHints *size_hints = XAllocSizeHints();
|
|
size_hints->min_width = 22;
|
|
size_hints->min_height = 22;
|
|
size_hints->max_width = 22;
|
|
size_hints->max_height = 22;
|
|
size_hints->width = 22;
|
|
size_hints->height = 22;
|
|
size_hints->x = 0;
|
|
size_hints->y = 0;
|
|
size_hints->win_gravity = StaticGravity;
|
|
size_hints->flags = PMinSize|PMaxSize|PPosition|PSize|PWinGravity;
|
|
XSetWMNormalHints(Xdisplay, win, size_hints);
|
|
|
|
Call(0, win, 0, 0);
|
|
|
|
XSetWMNormalHints(Xdisplay, win, size_hints);
|
|
|
|
Show();
|
|
XSetWMNormalHints(Xdisplay, win, size_hints);
|
|
XFree(size_hints);
|
|
}
|
|
|
|
void TrayIcon::Message(int type, const char *title, const char *text, int timeout)
|
|
{
|
|
if(!traywin)
|
|
return;
|
|
#if defined(flagNOGTK)
|
|
int len = strlen(text);
|
|
static int stamp;
|
|
Call(1, 1000 * timeout, len, ++stamp);
|
|
bool x11trap = TrapX11Errors();
|
|
while(len > 0) {
|
|
XClientMessageEvent ev;
|
|
Zero(ev);
|
|
ev.type = ClientMessage;
|
|
ev.window = GetWindow();
|
|
ev.format = 8;
|
|
ev.message_type = XAtom("_NET_SYSTEM_TRAY_MESSAGE_DATA");
|
|
int n = min(len, 20);
|
|
memcpy(&ev.data, text, n);
|
|
text += n;
|
|
len -= n;
|
|
XSendEvent(Xdisplay, traywin, XFalse, StructureNotifyMask, (XEvent *) &ev);
|
|
XSync(Xdisplay, XFalse);
|
|
}
|
|
UntrapX11Errors(x11trap);
|
|
#else
|
|
if (!notify_is_initted()) {
|
|
if (!notify_init(title)) {
|
|
return;
|
|
}
|
|
}
|
|
GError *error = NULL;
|
|
|
|
NotifyNotification *notification = notify_notification_new (title, text
|
|
, type == 1 ? "gtk-dialog-info"
|
|
: type == 2 ? "gtk-dialog-warning"
|
|
: "gtk-dialog-error"
|
|
#ifndef NOTIFY_VERSION_GT_0_7_0
|
|
, NULL
|
|
#endif
|
|
);
|
|
notify_notification_set_timeout(notification, timeout * 1000);
|
|
notify_notification_show (notification, &error);
|
|
#endif
|
|
}
|
|
|
|
#if !defined(flagNOGTK)
|
|
EXITBLOCK {
|
|
if (notify_is_initted())
|
|
notify_uninit ();
|
|
}
|
|
#endif
|
|
|
|
bool TrayIcon::HookProc(XEvent *event)
|
|
{
|
|
XAnyEvent *e = (XAnyEvent *)event;
|
|
if(e->type == DestroyNotify && e->window == traywin) {
|
|
AddToTray();
|
|
return true;
|
|
}
|
|
if(e->type == ClientMessage && !traywin) {
|
|
XClientMessageEvent *cm = (XClientMessageEvent *)event;
|
|
if(cm->message_type == XAtom("MANAGER") && (Atom)cm->data.l[1] == TraySelection()) {
|
|
AddToTray();
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void TrayIcon::Paint(Draw& w)
|
|
{
|
|
Size sz = GetSize();
|
|
Size isz = icon.GetSize();
|
|
Image m = icon;
|
|
if(isz.cx > sz.cx || isz.cy > sz.cy) {
|
|
m = Rescale(icon, sz);
|
|
isz = sz;
|
|
}
|
|
Point p = Rect(sz).CenterPos(isz);
|
|
w.DrawRect(sz, SColorFace());
|
|
w.DrawImage(p.x, p.y, m);
|
|
}
|
|
|
|
void TrayIcon::LeftDown()
|
|
{
|
|
WhenLeftDown();
|
|
}
|
|
|
|
void TrayIcon::LeftDown(Point p, dword keyflags)
|
|
{
|
|
LeftDown();
|
|
}
|
|
|
|
void TrayIcon::LeftUp()
|
|
{
|
|
WhenLeftUp();
|
|
}
|
|
|
|
void TrayIcon::LeftUp(Point p, dword keyflags)
|
|
{
|
|
LeftUp();
|
|
}
|
|
|
|
void TrayIcon::LeftDouble()
|
|
{
|
|
WhenLeftDouble();
|
|
}
|
|
|
|
void TrayIcon::LeftDouble(Point p, dword keyflags)
|
|
{
|
|
LeftDouble();
|
|
}
|
|
|
|
void TrayIcon::Menu(Bar& bar)
|
|
{
|
|
WhenBar(bar);
|
|
}
|
|
|
|
void TrayIcon::DoMenu(Bar& bar)
|
|
{
|
|
Menu(bar);
|
|
}
|
|
|
|
void TrayIcon::RightDown(Point p, dword keyflags)
|
|
{
|
|
MenuBar::Execute(this, THISBACK(DoMenu), GetMousePos());
|
|
}
|
|
|
|
void TrayIcon::Show(bool b)
|
|
{
|
|
/* if(!!b == !!IsOpen()) return; // Needs fixing....
|
|
if(b) {
|
|
}
|
|
else
|
|
Close();*/
|
|
}
|
|
|
|
TrayIcon::TrayIcon()
|
|
{
|
|
SetRect(0, 0, 24, 24);
|
|
ignoretakefocus = true;
|
|
Create(NULL, true, false);
|
|
if(top) {
|
|
popup = true;
|
|
Transparent();
|
|
AddToTray();
|
|
}
|
|
}
|
|
|
|
// Not implemented in X11 yet...
|
|
void TrayIcon::BalloonLeftDown()
|
|
{
|
|
}
|
|
|
|
void TrayIcon::BalloonShow()
|
|
{
|
|
}
|
|
|
|
void TrayIcon::BalloonHide()
|
|
{
|
|
}
|
|
|
|
void TrayIcon::BalloonTimeout()
|
|
{
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|