Chandra

 view release on metacpan or  search on metacpan

include/webview-tray-win32.c  view on Meta::CPAN

/*
 * webview-tray-win32.c - Windows system tray (Shell_NotifyIcon) backend
 *
 * Uses the Win32 Shell notification API with popup menus.
 */

#define WM_TRAYICON (WM_USER + 1)

struct webview_tray_win32 {
  NOTIFYICONDATAA nid;
  HMENU menu;
  HWND msg_hwnd;
};

/* Forward */
static LRESULT CALLBACK tray_wndproc(HWND hwnd, UINT msg, WPARAM wParam,
                                     LPARAM lParam);

static HMENU tray_win32_build_menu(struct webview_tray *t,
                                    struct webview_tray_item *items,
                                    int count) {
  HMENU menu = CreatePopupMenu();
  for (int i = 0; i < count; i++) {
    struct webview_tray_item *it = &items[i];
    if (it->is_separator) {
      AppendMenuA(menu, MF_SEPARATOR, 0, NULL);
      continue;
    }

    UINT flags = MF_STRING;
    if (it->is_disabled) flags |= MF_GRAYED;
    if (it->is_checked) flags |= MF_CHECKED;

    if (it->submenu_count > 0 && it->submenu) {
      HMENU sub = tray_win32_build_menu(t, it->submenu, it->submenu_count);
      AppendMenuA(menu, flags | MF_POPUP, (UINT_PTR)sub,
                  it->label ? it->label : "");
    } else {
      AppendMenuA(menu, flags, (UINT_PTR)it->id,
                  it->label ? it->label : "");
    }
  }
  return menu;
}

static LRESULT CALLBACK tray_wndproc(HWND hwnd, UINT msg, WPARAM wParam,
                                     LPARAM lParam) {
  struct webview_tray *t = (struct webview_tray *)
      GetWindowLongPtr(hwnd, GWLP_USERDATA);

  if (msg == WM_TRAYICON) {
    if (LOWORD(lParam) == WM_RBUTTONUP || LOWORD(lParam) == WM_LBUTTONUP) {
      struct webview_tray_win32 *priv = (struct webview_tray_win32 *)t->_priv;
      POINT pt;
      GetCursorPos(&pt);
      SetForegroundWindow(hwnd);
      int cmd = TrackPopupMenu(priv->menu,
                               TPM_RETURNCMD | TPM_NONOTIFY,
                               pt.x, pt.y, 0, hwnd, NULL);
      SendMessage(hwnd, WM_NULL, 0, 0);
      if (cmd > 0 && t->menu_cb) {
        t->menu_cb(t->w, cmd);
      }
    }



( run in 0.649 second using v1.01-cache-2.11-cpan-364913b4093 )