Merge branch 'policy-banner'

This commit is contained in:
Greg Neagle
2016-03-25 14:15:41 -07:00
3 changed files with 77 additions and 16 deletions

View File

@@ -57,6 +57,7 @@
C046261C1A00016200AF1E48 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/InfoPlist.strings; sourceTree = "<group>"; };
C046261D1A00019800AF1E48 /* it */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = it; path = it.lproj/MainMenu.xib; sourceTree = "<group>"; };
C05C3CEE188391F200095E65 /* munki.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; name = munki.py; path = MunkiStatus/munki.py; sourceTree = SOURCE_ROOT; };
C06137A51C9CB3BD00EC298E /* BorderlessWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BorderlessWindow.h; sourceTree = "<group>"; };
C07E956C1913ECEF00B40B9A /* fr */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = fr; path = fr.lproj/MainMenu.xib; sourceTree = "<group>"; };
C07E956D1913ECEF00B40B9A /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = "<group>"; };
C07E956E1913ECF400B40B9A /* de */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = de; path = de.lproj/MainMenu.xib; sourceTree = "<group>"; };
@@ -157,6 +158,7 @@
C09004F916CDD84E00BE34CE /* MunkiStatus */ = {
isa = PBXGroup;
children = (
C06137A51C9CB3BD00EC298E /* BorderlessWindow.h */,
C094B6D31891826700E06897 /* BorderlessWindow.m */,
C094B6D41891826700E06897 /* ScaledImageView.h */,
C094B6D51891826700E06897 /* ScaledImageView.m */,

View File

@@ -22,6 +22,7 @@ from objc import YES, NO, IBAction, IBOutlet, nil
from PyObjCTools import AppHelper
import os
import munki
import FoundationPlist
@@ -86,6 +87,7 @@ class MSUStatusWindowController(NSObject):
timeout_counter = 0
saw_process = False
managedsoftwareupdate_pid = None
window_level = NSScreenSaverWindowLevel - 1
@IBAction
def stopBtnClicked_(self, sender):
@@ -131,6 +133,9 @@ class MSUStatusWindowController(NSObject):
# set self.receiving_notifications to False so our process monitoring
# thread will exit
self.receiving_notifications = False
def windowDidResignMain_(self, notification):
self.window.orderFrontRegardless()
def managedsoftwareupdateStarted_(self, notification):
'''Called when we get a
@@ -145,9 +150,27 @@ class MSUStatusWindowController(NSObject):
com.googlecode.munki.managedsoftwareupdate.ended notification'''
NSLog('managedsoftwareupdate pid %s ended'
% notification.userInfo().get('pid'))
def setWindowLevel(self):
'''Sets our NSWindowLevel. Works around issues with the loginwindow
PolicyBanner in 10.11+ Some code based on earlier work by Pepijn
Bruienne'''
# Get our Darwin major version
darwin_vers = int(os.uname()[2].split('.')[0])
have_policy_banner = False
for test_file in ['/Library/Security/PolicyBanner.txt',
'/Library/Security/PolicyBanner.rtf',
'/Library/Security/PolicyBanner.rtfd']:
if os.path.exists(test_file):
have_policy_banner = True
break
# bump our NSWindowLevel if we have a PolicyBanner in ElCap+
if have_policy_banner and darwin_vers > 14:
self.window_level = NSScreenSaverWindowLevel
def initStatusSession(self):
'''Initialize our status session'''
self.setWindowLevel()
consoleuser = munki.getconsoleuser()
if consoleuser == None or consoleuser == u"loginwindow":
self.displayBackdropWindow()
@@ -156,7 +179,7 @@ class MSUStatusWindowController(NSObject):
if consoleuser == None or consoleuser == u"loginwindow":
# needed so the window can show over the loginwindow
self.window.setCanBecomeVisibleWithoutLogin_(True)
self.window.setLevel_(NSScreenSaverWindowLevel - 1)
self.window.setLevel_(self.window_level)
self.window.center()
self.messageFld.setStringValue_(
NSLocalizedString(u"Starting…", None))
@@ -231,11 +254,23 @@ class MSUStatusWindowController(NSObject):
self.timer.invalidate()
self.timer = None
def configureAndDisplayBackdropWindow_(self, window):
'''Sets all our configuration options for our masking windows'''
window.setCanBecomeVisibleWithoutLogin_(True)
window.setLevel_(self.window_level)
translucentColor = NSColor.blackColor().colorWithAlphaComponent_(0.35)
window.setBackgroundColor_(translucentColor)
window.setOpaque_(False)
window.setIgnoresMouseEvents_(False)
window.setAlphaValue_(0.0)
window.orderFrontRegardless()
window.animator().setAlphaValue_(1.0)
def displayBackdropWindow(self):
'''Draw a window that covers the login UI'''
if self.backdropWindow:
self.backdropWindow.setCanBecomeVisibleWithoutLogin_(True)
self.backdropWindow.setLevel_(NSStatusWindowLevel)
self.backdropWindow.setLevel_(self.window_level)
screenRect = NSScreen.mainScreen().frame()
self.backdropWindow.setFrame_display_(screenRect, True)
@@ -247,23 +282,39 @@ class MSUStatusWindowController(NSObject):
self.backdropWindow.orderFrontRegardless()
else:
# Lion+
# draw a transparent/translucent window to prevent interaction
# draw transparent/translucent windows to prevent interaction
# with the login UI
self.backdropImageFld.setHidden_(True)
translucentColor = NSColor.blackColor(
).colorWithAlphaComponent_(0.35)
self.backdropWindow.setBackgroundColor_(translucentColor)
self.backdropWindow.setOpaque_(False)
self.backdropWindow.setIgnoresMouseEvents_(False)
self.backdropWindow.setAlphaValue_(0.0)
self.backdropWindow.orderFrontRegardless()
self.backdropWindow.animator().setAlphaValue_(1.0)
self.configureAndDisplayBackdropWindow_(self.backdropWindow)
# are there any other screens?
for screen in NSScreen.screens():
if screen != NSScreen.mainScreen():
# create another masking window for this secondary screen
window_rect = screen.frame()
window_rect.origin = NSPoint(0.0, 0.0)
child_window = NSWindow.alloc(
).initWithContentRect_styleMask_backing_defer_screen_(
window_rect,
NSBorderlessWindowMask, NSBackingStoreBuffered, NO, screen)
self.configureAndDisplayBackdropWindow_(child_window)
self.backdropWindow.addChildWindow_ordered_(child_window, NSWindowAbove)
# preserve the relative ordering of the backdrop window and the status window
# IOW, clicking the backdrop window will not bring it in front of the status window
self.backdropWindow.addChildWindow_ordered_(self.window, NSWindowAbove)
def updateStatus_(self, notification):
'''Called when we get a
com.googlecode.munki.managedsoftwareupdate.statusUpdate notification;
update our status display with information from the notification'''
if self.window_level == NSScreenSaverWindowLevel:
# we're at the loginwindow, there is a PolicyBanner, and we're running
# under 10.11+. Make sure we're in the front.
NSApp.activateIgnoringOtherApps_(YES)
self.window.orderFrontRegardless()
self.got_status_update = True
info = notification.userInfo()
# explictly get keys from info object; PyObjC in Mountain Lion
@@ -288,6 +339,7 @@ class MSUStatusWindowController(NSObject):
command = info.get('command')
if command == 'activate':
NSApp.activateIgnoringOtherApps_(YES)
self.window.orderFrontRegardless()
elif command == 'showRestartAlert':
# clean up timer

View File

@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="5056" systemVersion="13F34" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="7706" systemVersion="15E65" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
<dependencies>
<deployment version="1060" defaultVersion="1060" identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="5056"/>
<deployment version="1060" identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="7706"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication"/>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application">
<customObject id="-3" userLabel="Application" customClass="NSObject">
<connections>
<outlet property="delegate" destination="373" id="374"/>
</connections>
@@ -171,6 +171,7 @@
<button verticalHuggingPriority="750" id="rxM-GK-Unu">
<rect key="frame" x="389" y="13" width="131" height="32"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<animations/>
<buttonCell key="cell" type="push" title="Stop" bezelStyle="rounded" alignment="center" refusesFirstResponder="YES" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="M20-JG-Pmr">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
@@ -184,10 +185,12 @@
<progressIndicator verticalHuggingPriority="750" minValue="20" maxValue="100" doubleValue="20" bezeled="NO" indeterminate="YES" style="bar" id="yFK-Ya-d24">
<rect key="frame" x="99" y="61" width="415" height="20"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<animations/>
</progressIndicator>
<textField verticalHuggingPriority="750" id="aUN-kO-8dF">
<rect key="frame" x="98" y="86" width="412" height="17"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<animations/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" id="eWh-Ya-joW">
<font key="font" metaFont="systemBold"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
@@ -197,6 +200,7 @@
<textField verticalHuggingPriority="750" id="Xa0-XA-1hm">
<rect key="frame" x="98" y="43" width="417" height="14"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<animations/>
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" id="b6Q-ET-o8V">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
@@ -206,16 +210,17 @@
<imageView id="aZW-jZ-KiY">
<rect key="frame" x="20" y="39" width="64" height="64"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<animations/>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyUpOrDown" image="MunkiStatus" id="FGG-pb-xd8"/>
</imageView>
</subviews>
<animations/>
</view>
<connections>
<outlet property="delegate" destination="I9V-I1-u8s" id="1bd-RW-Bhf"/>
</connections>
</window>
<window title="BackdropWindow" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" hasShadow="NO" oneShot="NO" showsToolbarButton="NO" visibleAtLaunch="NO" animationBehavior="default" id="VCy-58-vwp" userLabel="BackdropWindow" customClass="BorderlessWindow">
<windowStyleMask key="styleMask" titled="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="196" y="240" width="480" height="230"/>
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="878"/>
@@ -226,9 +231,11 @@
<imageView id="csw-Cd-idG" customClass="ScaledImageView">
<rect key="frame" x="0.0" y="0.0" width="480" height="230"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<animations/>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" id="wah-iR-ZTT"/>
</imageView>
</subviews>
<animations/>
</view>
</window>
</objects>