Skip to content

Commit

Permalink
#228: simplify the osx menu mess and move all the xpra menus into the…
Browse files Browse the repository at this point in the history
… main menu so we have more space for the application forwarded menus, can be toggled back using env var XPRA_OSX_SINGLE_MENU=0

git-svn-id: https://xpra.org/svn/Xpra/trunk@10715 3bb7dfac-3a0b-4e04-842a-767bc560f471
  • Loading branch information
totaam committed Oct 2, 2015
1 parent 51e9e74 commit 625d674
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 54 deletions.
25 changes: 5 additions & 20 deletions src/xpra/platform/darwin/gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,22 +138,10 @@ def window_focused(window, event):
window_menu = menus.get("window-menu")
from xpra.platform.darwin.osx_menu import getOSXMenuHelper
mh = getOSXMenuHelper()
mh.rebuild()
mh.add_full_menu()
if not menu_data or (not application_actions and not window_actions) or not window_menu:
mh.rebuild() #just the standard xpra controls
mh.add_full_menu()
return
mh.remove_all_menus()
#add all the xpra menus as sub-menus under one menu:
opt = mh.menuitem("Xpra Options")
options = mh.make_menu()
opt.set_submenu(options)
for label, submenu in mh.get_extra_menus():
item = mh.menuitem(label)
item.set_submenu(submenu)
options.add(item)
opt.show_all()
mh.add_to_menu_bar(opt)
mh.menu_bar.show_all()
#add the application menus after that:
#ie: menu = {
# 'enabled': True,
Expand Down Expand Up @@ -200,9 +188,7 @@ def cb(menu_item):
for group_id in sorted(window_menu.keys()):
group = window_menu[group_id]
title = window.get_title() or "Application"
application = mh.menuitem(title)
submenu = mh.make_menu()
application.set_submenu(submenu)
app_menu = mh.make_menu()
for menuid in sorted(group.keys()):
menu_entries = group[menuid]
for d in menu_entries:
Expand All @@ -213,10 +199,9 @@ def cb(menu_item):
item = mh.menuitem(label, cb=cb)
item._action = action
item._target = d.get("target")
submenu.add(item)
app_menu.add(item)
log("added %s to %s menu for %s", label, title, window)
application.show_all()
mh.add_to_menu_bar(application)
mh.add_to_menu_bar(title, app_menu)


def add_window_hooks(window):
Expand Down
107 changes: 73 additions & 34 deletions src/xpra/platform/darwin/osx_menu.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@
# Xpra is released under the terms of the GNU GPL v2, or, at your option, any
# later version. See the file COPYING for details.

import os

from xpra.gtk_common.gobject_compat import import_gtk
gtk = import_gtk()
from xpra.gtk_common.gtk_util import scaled_image
from xpra.client.gtk_base.about import about
from xpra.client.gtk_base.gtk_tray_menu_base import GTKTrayMenuBase, populate_encodingsmenu
from xpra.platform.paths import get_icon
from xpra.platform.darwin.gui import get_OSXApplication

from xpra.log import Logger
log = Logger("osx", "tray", "menu")
Expand All @@ -19,8 +22,15 @@
SHOW_SOUND_MENU = True
SHOW_ENCODINGS_MENU = True
SHOW_ACTIONS_MENU = True
SHOW_INFO_MENU = True

SHOW_ABOUT_XPRA = True

SINGLE_MENU = os.environ.get("XPRA_OSX_SINGLE_MENU", "1")=="1"


SEPARATOR = "SEPARATOR"


_OSXMenuHelper = None
def getOSXMenuHelper(client=None):
Expand All @@ -46,28 +56,32 @@ def __init__(self, client=None):
self.menu_bar = None
self.hidden_window = None
self.keyboard = None
self.menus = {}
self.menus = {} #all the "top-level" menu items we manage
self.app_menus = {} #the ones added to the app_menu via insert_app_menu_item (which cannot be removed!)
self.full = False
self.set_client(client)

def set_client(self, client):
self.client = client
if client and client.keyboard_helper:
self.keyboard = client.keyboard_helper.keyboard
#if we call add_about before the main loop is ready,
#things don't work...
if client and SHOW_ABOUT_XPRA:
self.client.after_handshake(self.add_about)

def build(self):
log("OSXMenuHelper.build()")
if self.menu_bar is None:
self.menu_bar = gtk.MenuBar()
self.build_menu_bar()
self.menu_bar.show_all()
return self.menu_bar

def rebuild(self):
log("OSXMenuHelper.rebuild()")
if not self.menu_bar:
return self.build()
self.remove_all_menus()
self.build_menu_bar()
return self.menu_bar

def remove_all_menus(self):
Expand All @@ -76,28 +90,64 @@ def remove_all_menus(self):
for x in self.menus.values():
if x in self.menu_bar.get_children():
self.menu_bar.remove(x)
x.hide()
x.hide()
self.menus = {}
self.full = False


def add_to_menu_bar(self, item):
submenu = item.get_submenu()
assert submenu
if item not in self.menu_bar.get_children():
def add_top_level_menu(self, label, submenu):
""" Adds the item to the app-menu or to the top bar,
but only if it has not been added yet.
(depending on the SINGLE_MENU flag)
"""
if SINGLE_MENU:
#add or re-use menu item in the app-menu:
self.add_to_app_menu(label, submenu)
else:
self.add_to_menu_bar(label, submenu)

def add_to_app_menu(self, label, submenu):
item = self.app_menus.get(label)
if item:
log("application menu already has a '%s' entry", label)
if submenu is not None:
item.set_submenu(submenu)
item.show_all()
else:
if label.startswith(SEPARATOR):
item = gtk.SeparatorMenuItem()
else:
item = self.menuitem(label)
item.set_submenu(submenu)
item.show_all()
macapp = get_OSXApplication()
macapp.insert_app_menu_item(item, 1)
self.app_menus[label] = item

def add_to_menu_bar(self, label, submenu):
if label.startswith(SEPARATOR):
return #not relevant
item = self.menus.get(label)
if item is None:
item = self.menuitem(label)
item.set_submenu(submenu)
item.show_all()
self.menu_bar.add(item)
self.menus[item.get_label()] = item
self.menus[label] = item
else:
item.set_submenu(submenu)
item.show_all()


def add_about(self):
if "About" in self.app_menus:
return
item = self.menuitem("About", cb=about)
item.show_all()
macapp = get_OSXApplication()
macapp.insert_app_menu_item(item, 0)
self.app_menus["About"] = item

def build_menu_bar(self):
log("OSXMenuHelper.build_menu_bar()")
if SHOW_ABOUT_XPRA:
info = self.menuitem("Info")
info_menu = self.make_menu()
info.set_submenu(info_menu)
info_menu.add(self.menuitem("About Xpra", "information.png", None, about))
info.show_all()
self.add_to_menu_bar(info)
self.menu_bar.show_all()

def add_full_menu(self):
log("OSXMenuHelper.add_full_menu()")
Expand All @@ -106,26 +156,14 @@ def add_full_menu(self):
self.full = True
assert self.client
menus = self.get_extra_menus()
for label, submenu in menus:
item = None
#try to find an existing menu item matching this label:
for x in self.menu_bar.get_children():
if hasattr(x, "get_label") and x.get_label()==label:
log("found existing menu item for %s: %s", label, x)
item = x
break
if item is None:
item = self.menuitem(label)
item.set_submenu(submenu)
item.show_all()
self.add_to_menu_bar(item)
for label, submenu in reversed(menus):
self.add_top_level_menu(label, submenu)
self.menu_bar.show_all()

def get_extra_menus(self):
menus = []
if SHOW_ABOUT_XPRA:
if SHOW_INFO_MENU:
info_menu = self.make_menu()
info_menu.append(self.menuitem("About Xpra", "information.png", None, about))
info_menu.append(self.make_sessioninfomenuitem())
info_menu.append(self.make_bugreportmenuitem())
menus.append(("Info", info_menu))
Expand Down Expand Up @@ -164,6 +202,7 @@ def addsnc(*args):
actions_menu.add(self.make_startnewcommandmenuitem(True))
self.client.after_handshake(addsnc)
menus.append(("Actions", actions_menu))
menus.append((SEPARATOR+"-EXTRAS", None))
return menus

#these methods are called by the superclass
Expand Down

0 comments on commit 625d674

Please sign in to comment.