func init() { dirShareData = globals.DirShareData() iconCore = globals.FileCairoDockIcon() AppletInfo = func(log cdtype.Logger, name string) (dir, icon string) { mod := gldi.ModuleGet(name) if mod == nil { return "", "" } vc := mod.VisitCard() return vc.GetShareDataDir(), vc.GetIconFilePath() } AppletRestart = func(name string) { mod := gldi.ModuleGet(name) if mod == nil { return } for _, mi := range mod.InstancesList() { gldi.ObjectDelete(mi) } mod.Activate() } CloseGui = backendgui.CloseGui }
// Entry adds a defined entry to the menu. Returns if a separator is needed. // func (m *DockMenu) Entry(entry MenuEntry) bool { switch entry { case MenuAbout: m.AddEntry( tran.Slate("About"), globals.IconNameAbout, about.New, ) case MenuAddApplet: m.AddEntry( tran.Slate("Applet"), globals.IconNameAdd, backendgui.ShowAddons) case MenuAddLauncher: m.AddEntry( tran.Slate("Custom launcher"), globals.IconNameAdd, func() { newIcon := gldi.LauncherAddNew("", m.Dock, nextOrder(m.Icon, m.Dock)) if newIcon == nil { // TODO: use log println("Couldn't create create the icon.\nCheck that you have writing permissions on ~/.config/cairo-dock and its sub-folders") } else { backendgui.ShowItems(newIcon, nil, nil, -1) } }, ).SetTooltipText(tran.Slate("Usually you would drag a launcher from the menu and drop it on the dock.")) case MenuAddMainDock: m.AddEntry( tran.Slate("Main dock"), globals.IconNameAdd, func() { key := gldi.DockAddConfFile() gldi.DockNew(key) backendgui.ReloadItems() // g_timeout_add_seconds (1, (GSourceFunc)_show_new_dock_msg, cDockName); // delai, car sa fenetre n'est pas encore bien placee (0,0). }) case MenuAddSeparator: m.AddEntry( tran.Slate("Separator"), globals.IconNameAdd, func() { newIcon := gldi.SeparatorIconAddNew(m.Dock, nextOrder(m.Icon, m.Dock)) if newIcon == nil { // TODO: use log println("Couldn't create create the icon.\nCheck that you have writing permissions on ~/.config/cairo-dock and its sub-folders") } }) case MenuAddSubDock: m.AddEntry( tran.Slate("Sub-dock"), globals.IconNameAdd, func() { newIcon := gldi.StackIconAddNew(m.Dock, nextOrder(m.Icon, m.Dock)) if newIcon == nil { // TODO: use log println("Couldn't create create the icon.\nCheck that you have writing permissions on ~/.config/cairo-dock and its sub-folders") } }) case MenuClassItems: //\_________________________ class actions. items := m.Icon.GetClass().MenuItems() for _, it := range items { cmd := strings.Fields(it[1]) m.AddEntry( it[0], // name it[2], // icon func() { log.ExecAsync(cmd[0], cmd[1:]...) }) // was gldi.LaunchCommand(cmd) } return len(items) > 0 case MenuConfigure: m.AddEntry( tran.Slate("Configure"), globals.IconNamePreferences, backendgui.ShowMainGui, ).SetTooltipText(tran.Slate("Configure behaviour, appearance, and applets.")) case MenuCustomIconRemove: classIcon := m.Icon.GetClass().Icon() if classIcon == "" { classIcon = m.Icon.GetClass().String() } path := filepath.Join(globals.DirCurrentIcons(), classIcon+".png") if _, e := os.Stat(path); e != nil { path = filepath.Join(globals.DirCurrentIcons(), classIcon+".svg") if _, e := os.Stat(path); e != nil { path = "" } } // println("custom icon", path) if path != "" { m.AddEntry( tran.Slate("Remove custom icon"), globals.IconNameRemove, func() { C._cairo_dock_remove_custom_appli_icon((*C.Icon)(unsafe.Pointer(m.Icon.ToNative())), (*C.CairoDock)(unsafe.Pointer(m.Dock.Ptr))) }) } case MenuCustomIconSet: m.AddEntry( tran.Slate("Set a custom icon"), globals.IconNameSelectColor, func() { C._cairo_dock_set_custom_appli_icon((*C.Icon)(unsafe.Pointer(m.Icon.ToNative())), (*C.CairoDock)(unsafe.Pointer(m.Dock.Ptr))) }) case MenuDeleteDock: m.AddEntry( tran.Slate("Delete this dock"), globals.IconNameDelete, func() { if m.Dock.GetRefCount() != 0 { dialog.ShowWithQuestion("Delete this dock?", m.Dock.GetPointedIcon(), m.Container, globals.FileCairoDockIcon(), cbDialogIsOK(func() { gldi.ObjectDelete(m.Dock) })) } }) case MenuDeskletLock: desklet := m.Container.ToDesklet() m.AddCheckEntry( tran.Slate("Lock position"), desklet.PositionLocked(), func(c *gtk.CheckMenuItem) { desklet.LockPosition(c.GetActive()) backendgui.UpdateDeskletVisibility(desklet) }) case MenuDeskletSticky: desklet := m.Container.ToDesklet() m.AddCheckEntry( tran.Slate("On all desktops"), m.Container.ToDesklet().IsSticky(), func(c *gtk.CheckMenuItem) { desklet.SetSticky(c.GetActive()) // TODO: check why SetSticky isn't working... println("get stick", desklet.IsSticky()) backendgui.UpdateDeskletVisibility(desklet) }) case MenuDeskletVisibility: submenu := m.AddSubMenu(tran.Slate("Visibility"), globals.IconNameFind) desklet := m.Container.ToDesklet() callback := func(radio *gtk.RadioMenuItem, val cdtype.DeskletVisibility) { if radio.GetActive() { desklet.SetVisibility(val, true) // with true, also save to conf. backendgui.UpdateDeskletVisibility(desklet) } } group := 42 visibility := desklet.Visibility() addRadio := func(vis cdtype.DeskletVisibility, label string) { radio := submenu.AddRadioEntry(label, visibility == vis, group, nil) radio.Connect("toggled", callback, vis) } addRadio(cdtype.DeskletVisibilityNormal, tran.Slate("Normal")) addRadio(cdtype.DeskletVisibilityKeepAbove, tran.Slate("Always on top")) addRadio(cdtype.DeskletVisibilityKeepBelow, tran.Slate("Always below")) if gldi.CanSetOnWidgetLayer() { addRadio(cdtype.DeskletVisibilityWidgetLayer, tran.Slate("Widget Layer")) } addRadio(cdtype.DeskletVisibilityReserveSpace, tran.Slate("Reserve space")) case MenuDetachApplet: m.AddEntry( ternary.String(m.Dock != nil, tran.Slate("Detach"), tran.Slate("Return to the dock")), ternary.String(m.Dock != nil, globals.IconNameGotoTop, globals.IconNameGotoBottom), func() { // if (CAIRO_DOCK_IS_DESKLET (pContainer)) // icon = (CAIRO_DESKLET (pContainer))->pIcon; // l'icone cliquee du desklet n'est pas forcement celle qui contient le module ! // g_return_if_fail (CAIRO_DOCK_IS_APPLET (icon)); m.Icon.ModuleInstance().Detach() }) case MenuDuplicateApplet: m.AddEntry( tran.Slate("Duplicate"), globals.IconNameAdd, func() { // if (CAIRO_DOCK_IS_DESKLET (pContainer)) // icon = (CAIRO_DESKLET (pContainer))->pIcon; // l'icone cliquee du desklet n'est pas forcement celle qui contient le module ! // g_return_if_fail (CAIRO_DOCK_IS_APPLET (icon)); m.Icon.ModuleInstance().Module().AddInstance() // gldi_module_add_instance (icon->pModuleInstance->pModule); }) case MenuEditApplet: m.AddEntry( tran.Slate("Edit"), globals.IconNameEdit, func() { // if (CAIRO_DOCK_IS_DESKLET (pContainer)) // icon = (CAIRO_DESKLET (pContainer))->pIcon; // l'icone cliquee du desklet n'est pas forcement celle qui contient le module. // g_return_if_fail (CAIRO_DOCK_IS_APPLET (icon)); backendgui.ShowItems(m.Icon, nil, nil, -1) }) case MenuEditDock: m.AddEntry( tran.Slate("Configure this dock"), globals.IconNameExecute, func() { backendgui.ShowItems(nil, m.Container, nil, 0) }, ).SetTooltipText(tran.Slate("Customize the position, visibility and appearance of this main dock.")) case MenuEditIcon: m.AddEntry(tran.Slate( tran.Slate("Edit")), globals.IconNameEdit, func() { switch m.Icon.GetDesktopFileName() { case "", "none": dialog.ShowTemporaryWithIcon("Sorry, this icon doesn't have a configuration file.", m.Icon, m.Container, 4000, "same icon") default: backendgui.ShowItems(m.Icon, nil, nil, -1) } }) case MenuEditTarget: _, img := m.Icon.DefaultNameIcon() m.AddEntry( tran.Slate("Edit icon"), img, func() { // if (CAIRO_DOCK_IS_DESKLET (pContainer)) // icon = (CAIRO_DESKLET (pContainer))->pIcon; // l'icone cliquee du desklet n'est pas forcement celle qui contient le module. // g_return_if_fail (CAIRO_DOCK_IS_APPLET (icon)); backendgui.ShowItems(m.Icon, nil, nil, -1) }) case MenuHandbook: m.AddEntry( tran.Slate("Applet's handbook"), globals.IconNameAbout, m.Icon.ModuleInstance().PopupAboutApplet) // handbook + 5x to facto // picon := icon // if container.IsDesklet() { // picon = container.Icon() // icon = (CAIRO_DESKLET (pContainer))->pIcon; // l'icone cliquee du desklet n'est pas forcement celle qui contient le module ! // } case MenuHelp: m.AddEntry( tran.Slate("Help"), globals.IconNameHelp, func() { backendgui.ShowModuleGui("Help") }, ).SetTooltipText(tran.Slate("There are no problems, only solutions (and a lot of useful hints!)")) case MenuLaunchNew: m.AddEntry( tran.Slate("Launch a new (Shift+clic)"), globals.IconNameAdd, func() { m.Icon.LaunchCommand(log) }) case MenuLockIcons: m.AddCheckEntry( tran.Slate("Lock icons position"), current.Docks.LockIcons(), func() { current.Docks.LockIcons(!current.Docks.LockIcons()) config.UpdateFile(log, globals.ConfigFile(), "Accessibility", "lock icons", current.Docks.LockIcons()) }, ).SetTooltipText(tran.Slate("This will (un)lock the position of the icons.")) case MenuMakeLauncher: m.AddEntry( tran.Slate("Make it a launcher"), globals.IconNameNew, func() { C._cairo_dock_make_launcher_from_appli((*C.Icon)(unsafe.Pointer(m.Icon.ToNative())), (*C.CairoDock)(unsafe.Pointer(m.Dock.Ptr))) }) case MenuMoveToDesktopClass: m.moveToDesktop(true) case MenuMoveToDesktopWindow: m.moveToDesktop(false) case MenuMoveToDock: sub := m.AddSubMenu(tran.Slate("Move to another dock"), globals.IconNameJumpTo) docks := gldi.GetAllAvailableDocks(m.Icon.GetContainer().ToCairoDock(), m.Icon.GetSubDock()) docks = append(docks, nil) for _, dock := range docks { name := "" key := "" icon := "" if dock == nil { name = tran.Slate("New main dock") icon = globals.IconNameAdd // globals.IconNameNew } else { name = ternary.String(dock.GetReadableName() != "", dock.GetReadableName(), dock.GetDockName()) key = dock.GetDockName() if dock.GetRefCount() == 0 { // Maindocks icon switch dock.Container().ScreenBorder() { case cdtype.ContainerPositionBottom: icon = "go-down" case cdtype.ContainerPositionTop: icon = "go-up" case cdtype.ContainerPositionLeft: icon = "go-previous" case cdtype.ContainerPositionRight: icon = "go-next" } } else { // Subdocks icon. dockicon := dock.SearchIconPointingOnDock(nil) if dockicon != nil { icon = dockicon.GetFileName() } } } sub.AddEntry( name, icon, func() { if key == "" { key = gldi.DockAddConfFile() } m.Icon.WriteContainerNameInConfFile(key) // Update icon conf file. if m.Icon.IsLauncher() || m.Icon.IsStackIcon() || m.Icon.IsSeparator() { // Reload icon (creating the dock). gldi.ObjectReload(m.Icon) } else if m.Icon.IsApplet() { gldi.ObjectReload(m.Icon.ModuleInstance()) } newdock := gldi.DockGet(key) if newdock != nil && newdock.GetRefCount() == 0 && len(newdock.Icons()) == 1 { str := tran.Slate("The new dock has been created.\nYou can customize it by right-clicking on it -> cairo-dock -> configure this dock.") dialog.ShowGeneralMessage(str, 8000) // we don't show it on the new dock as its window isn't positioned yet (0,0). } }) } case MenuQuickHide: m.AddEntry( tran.Slate("Quick-Hide"), globals.IconNameGotoBottom, gldi.QuickHideAllDocks, ).SetTooltipText(tran.Slate("This will hide the dock until you hover over it with the mouse.")) case MenuQuit: item := m.AddEntry( tran.Slate("Quit"), globals.IconNameQuit, func() { backendgui.CloseGui() // gtk.MainQuit() // TODO: remove SQP HACK, easy quit no confirm for tests. dialog.ShowWithQuestion("Quit Cairo-Dock?", GetIconForDesklet(m.Icon, m.Container), m.Container, globals.FileCairoDockIcon(), cbDialogIsOK(gtk.MainQuit)) }) // const gchar *cDesktopSession = g_getenv ("DESKTOP_SESSION"); // gboolean bIsCairoDockSession = cDesktopSession && g_str_has_prefix (cDesktopSession, "cairo-dock"); // // if we're using a Cairo-Dock session and we quit the dock we have... nothing to relaunch it! // if bIsCairoDockSession { // item.SetSensitive(false) // item.SetTooltipText("You're using a Cairo-Dock Session!\nIt's not advised to quit the dock but you can press Shift to unlock this menu entry.") // static void _cairo_dock_set_sensitive_quit_menu (G_GNUC_UNUSED GtkWidget *pMenuItem, GdkEventKey *pKey, GtkWidget *pQuitEntry) // { // pMenuItem not used because we want to only modify one entry // if (pKey->type == GDK_KEY_PRESS && // (pKey->keyval == GDK_KEY_Shift_L || // pKey->keyval == GDK_KEY_Shift_R)) // pressed // gtk_widget_set_sensitive (pQuitEntry, TRUE); // unlocked // else if (pKey->state & GDK_SHIFT_MASK) // released // gtk_widget_set_sensitive (pQuitEntry, FALSE); // locked) // } cbSensitive := func(_ *gtk.CheckMenuItem, event *gdk.Event) { key := &gdk.EventKey{Event: event} println("key", key.KeyVal()) if key.KeyVal() == uint(C.GDK_KEY_Shift_R) { // pressed. item.SetSensitive(true) } else if gdk.ModifierType(key.State())&gdk.GDK_SHIFT_MASK > 0 { // released. item.SetSensitive(false) } } _, e := item.Connect("key-press-event", cbSensitive) if e != nil { println((e.Error())) } item.Connect("key-release-event", cbSensitive) // gtk_widget_set_sensitive (pMenuItem, FALSE); // locked // gtk_widget_set_tooltip_text (pMenuItem, _("You're using a Cairo-Dock Session!\nIt's not advised to quit the dock but you can press Shift to unlock this menu entry.")); // // signal to unlock the entry (signal monitored only in the submenu) // g_signal_connect (pSubMenu, "key-press-event", G_CALLBACK (_cairo_dock_set_sensitive_quit_menu), pMenuItem); // g_signal_connect (pSubMenu, "key-release-event", G_CALLBACK (_cairo_dock_set_sensitive_quit_menu), pMenuItem); // } // case MenuAutostart: // gchar *cCairoAutoStartDirPath = g_strdup_printf ("%s/.config/autostart", g_getenv ("HOME")); // gchar *cCairoAutoStartEntryPath = g_strdup_printf ("%s/cairo-dock.desktop", cCairoAutoStartDirPath); // gchar *cCairoAutoStartEntryPath2 = g_strdup_printf ("%s/cairo-dock-cairo.desktop", cCairoAutoStartDirPath); // if (! bIsCairoDockSession && ! g_file_test (cCairoAutoStartEntryPath, G_FILE_TEST_EXISTS) && ! g_file_test (cCairoAutoStartEntryPath2, G_FILE_TEST_EXISTS)) // { // cairo_dock_add_in_menu_with_stock_and_data (_("Launch Cairo-Dock on startup"), // GLDI_ICON_NAME_ADD, // G_CALLBACK (_cairo_dock_add_autostart), // pSubMenu, // NULL); // } // g_free (cCairoAutoStartEntryPath); // g_free (cCairoAutoStartEntryPath2); // g_free (cCairoAutoStartDirPath); // case MenuThirdParty: // pMenuItem = cairo_dock_add_in_menu_with_stock_and_data (_("Get more applets!"), // GLDI_ICON_NAME_ADD, // G_CALLBACK (_cairo_dock_show_third_party_applets), // pSubMenu, // NULL); // gtk_widget_set_tooltip_text (pMenuItem, _("Third-party applets provide integration with many programs, like Pidgin")); case MenuRemoveApplet: m.AddEntry( tran.Slate("Remove"), globals.IconNameRemove, func() { // if (CAIRO_DOCK_IS_DESKLET (pContainer)) // icon = (CAIRO_DESKLET (pContainer))->pIcon; // l'icone cliquee du desklet n'est pas forcement celle qui contient le module ! // g_return_if_fail (CAIRO_DOCK_IS_APPLET (icon)); dialog.ShowWithQuestion( fmt.Sprintf("You're about to remove this applet (%s) from the dock. Are you sure?", m.Icon.ModuleInstance().Module().VisitCard().GetTitle()), m.Icon, m.Container, "same icon", cbDialogIsOK(func() { gldi.ObjectDelete(m.Icon.ModuleInstance()) })) }) case MenuRemoveIcon: m.AddEntry( tran.Slate("Remove"), globals.IconNameRemove, func() { name := ternary.String(m.Icon.GetInitialName() != "", m.Icon.GetInitialName(), m.Icon.GetName()) if name == "" { name = ternary.String(m.Icon.IsSeparator(), tran.Slate("separator"), "no name") } dialog.ShowWithQuestion( fmt.Sprintf(tran.Slate("You're about to remove this icon (%s) from the dock. Are you sure?"), name), m.Icon, m.Container, "same icon", cbDialogIsOK(func() { if m.Icon.IsStackIcon() && m.Icon.GetSubDock() != nil && len(m.Icon.GetSubDock().Icons()) > 0 { dialog.ShowWithQuestion( tran.Slate("Do you want to re-dispatch the icons contained inside this container into the dock?\n(otherwise they will be destroyed)"), m.Icon, m.Container, globals.FileCairoDockIcon(), cbDialogIsOK(func() { m.Icon.RemoveIconsFromSubdock(m.Dock) })) } m.Icon.RemoveFromDock() })) }).SetTooltipText(tran.Slate("You can remove a launcher by dragging it out of the dock with the mouse .")) case MenuThemes: // pMenuItem = cairo_dock_add_in_menu_with_stock_and_data (_("Manage themes"), // CAIRO_DOCK_SHARE_DATA_DIR"/icons/icon-appearance.svg", // G_CALLBACK (_cairo_dock_initiate_theme_management), // pSubMenu, // NULL); // gtk_widget_set_tooltip_text (pMenuItem, _("Choose from amongst many themes on the server or save your current theme.")); case MenuWindowAbove: flag := m.Icon.Window().IsAbove() m.AddEntry( ternary.String(flag, tran.Slate("Don't keep above"), tran.Slate("Keep above")), ternary.String(flag, globals.IconNameGotoBottom, globals.IconNameGotoTop), m.Icon.CallbackActionWindowToggle((cdglobal.Window).SetAbove, (cdglobal.Window).IsAbove)) case MenuWindowBelow: if !m.Icon.Window().IsHidden() { // this could be a button in the menu, if we find an icon that doesn't look too much like the "minimise" one m.AddEntry( tran.Slate("Below other windows")+actionMiddleClick(m.Icon, 4), globals.DirShareData("icons", "icon-lower.svg"), m.Icon.CallbackActionWindow((cdglobal.Window).Lower)) } case MenuWindowFullScreen: flag := m.Icon.Window().IsFullScreen() m.AddEntry( ternary.String(flag, tran.Slate("Not Fullscreen"), tran.Slate("Fullscreen")), ternary.String(flag, globals.IconNameLeaveFullScreen, globals.IconNameFullScreen), m.Icon.CallbackActionWindowToggle((cdglobal.Window).SetFullScreen, (cdglobal.Window).IsFullScreen)) case MenuWindowKill: m.AddEntry( tran.Slate("Kill"), globals.IconNameClose, m.Icon.CallbackActionWindow((cdglobal.Window).Kill)) case MenuWindowMoveAllHere: m.AddEntry( tran.Slate("Move all to this desktop"), globals.IconNameJumpTo, m.Icon.CallbackActionSubWindows((cdglobal.Window).MoveToCurrentDesktop)) case MenuWindowMoveHere: var callback func() if !m.Icon.Window().IsOnCurrentDesktop() { callback = m.Icon.CallbackActionWindow(func(win cdglobal.Window) { win.MoveToCurrentDesktop() if !win.IsHidden() { win.Show() } }) } m.AddEntry(tran.Slate("Move to this desktop"), globals.IconNameJumpTo, callback) case MenuWindowSticky: m.AddEntry( ternary.String(m.Icon.Window().IsSticky(), tran.Slate("Visible only on this desktop"), tran.Slate("Visible on all desktops")), globals.IconNameJumpTo, m.Icon.CallbackActionWindowToggle((cdglobal.Window).SetSticky, (cdglobal.Window).IsSticky)) } return notif.AnswerLetPass }