Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/powerbi/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java macOS“;“大苏尔”;检测黑暗菜单栏/系统托盘_Java_C++_Objective C_Statusbar - Fatal编程技术网

Java macOS“;“大苏尔”;检测黑暗菜单栏/系统托盘

Java macOS“;“大苏尔”;检测黑暗菜单栏/系统托盘,java,c++,objective-c,statusbar,Java,C++,Objective C,Statusbar,从macOS(10.16“Beta”/11.0)“Big Sur”开始,菜单栏和系统托盘不再支持桌面暗模式首选项,因此很难为该桌面正确设置系统托盘图标的主题 以前,使用shell命令默认读取,可以检测到暗模式: defaults read -g AppleInterfaceStyle # "Dark" 这对于检测窗口主题仍然很有效,但对于菜单栏和系统托盘主题不起作用 由于该区域似乎受壁纸亮度/白度/亮度的影响,我们如何检测黑暗的系统托盘 如何在(例如)Objective-

从macOS(10.16“Beta”/11.0)“Big Sur”开始,菜单栏和系统托盘不再支持桌面暗模式首选项,因此很难为该桌面正确设置系统托盘图标的主题

以前,使用shell命令
默认读取
,可以检测到暗模式:

defaults read -g AppleInterfaceStyle
# "Dark"
这对于检测窗口主题仍然很有效,但对于菜单栏和系统托盘主题不起作用

由于该区域似乎受壁纸亮度/白度/亮度的影响,我们如何检测黑暗的系统托盘

如何在(例如)Objective-C/C++中检测此问题?任何解决方案都是受欢迎的,因为大多数方案都可以调整

问题也发布到苹果开发者论坛:

Qt5.6有一个名为的功能,允许操作系统自动处理此问题。这实际上是的别名

更多关于macOS“暗模式”的参考:

采用OpenJDK上游错误报告:


关键词:
NSStatusBar
菜单栏附加功能

我刚刚提交了一份TSI,我得到了一个答案:

但我不会在NSStatusItem按钮的顶部添加NSView 直接的。文档提到使用按钮属性进行自定义 状态项的外观和行为,但它应该工作 在按钮本身的范围内,也就是说,它是多种多样的 属性,如图像和文本及其位置。几年前,, NSStatusItem允许自定义视图,但后来在中被弃用 以支持基于按钮的UI,因此允许其绘制 行为,以便轻松适应菜单栏外观的更改

不幸的是,没有办法通过编程获得这些信息。 然而,获取信息对于我的三个应用程序来说非常重要,所以我开始探索

对我个人来说,获取这些信息不会触发任何安全提示是非常重要的

我想到了以下想法:

  • 创建并隐藏
    NSStatusItem
  • 设置模板化的
    NSImage
  • CALayer
    的内容呈现为
    NSImage
您可以使用此代码获取颜色信息(注意:
NSStatusItem
永远不可见,不会导致现有项目移动或类似情况)。请随意调整格式和类:

我使用公共属性创建了一个名为
MenuBar
的类:

public class MenuBar {
    private static var statusItem: NSStatusItem?

    public static var theme: MenuBarTheme {
        if self.statusItem == nil {
            self.statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
            self.statusItem?.button?.image = NSImage(systemSymbolName: "circle.fill", accessibilityDescription: nil)
            self.statusItem?.isVisible = false
        }
        
        if let color = self.getPixelColor() {
            return color.redComponent < 0.20 && color.blueComponent < 0.20 && color.greenComponent < 0.20 ? .light : .dark
        }
        else
        {
            return NSApplication.isDarkMode ? .dark : .light
        }
    }

    public static var tintColor: NSColor {
        return self.theme == .light ? NSColor.black : NSColor.white
  }
    
  // MARK: - Helper
  fileprivate static func getPixelColor() -> NSColor?
  {
     if let image = self.statusItem?.button?.layer?.getBitmapImage() {
        let imageRep = NSBitmapImageRep(data: image.tiffRepresentation!)
            
         if let color = imageRep?.colorAt(x: Int(image.size.width / 2.0), y: Int(image.size.height / 2.0)) {
            return color
         }
     }
        
     return nil
  }
}

public enum MenuBarTheme : String
{
    case light = "light"
    case dark = "dark"
}

public extension NSApplication
{
    class var isDarkMode: Bool
    {
        return NSApplication.shared.appearance?.description.lowercased().contains("dark") ?? false
    }
}

public extension CALayer
{
    func getBitmapImage() -> NSImage
    {
        let btmpImgRep = NSBitmapImageRep(bitmapDataPlanes: nil, pixelsWide: Int(self.frame.width), pixelsHigh: Int(self.frame.height), bitsPerSample: 8, samplesPerPixel: 4, hasAlpha: true, isPlanar: false, colorSpaceName: .deviceRGB, bytesPerRow: 0, bitsPerPixel: 32)

        let ctx = NSGraphicsContext(bitmapImageRep: btmpImgRep!)
        let cgContext = ctx!.cgContext
        
        self.render(in: cgContext)
        
        let cgImage = cgContext.makeImage()

        return NSImage(cgImage: cgImage!, size: CGSize(width: self.frame.width, height: self.frame.height))
    }
}
公共类菜单栏{
私有静态变量statusItem:NSStatusItem?
公共静态变量主题:菜单基础{
如果self.statusItem==nil{
self.statusItem=NSStatusBar.system.statusItem(带长度:NSStatusItem.variableLength)
self.statusItem?.button?.image=NSImage(系统符号名称:“circle.fill”,可访问性说明:nil)
self.statusItem?.isVisible=false
}
如果let color=self.getPixelColor(){
返回color.redComponent<0.20&&color.blueComponent<0.20&&color.greenComponent<0.20?。亮:。暗
}
其他的
{
返回NSApplication.isDarkMode?.dark:.亮
}
}
公共静态颜色:NSColor{
return self.theme==.light?NSColor.black:NSColor.white
}
//马克:-助手
fileprivate静态函数getPixelColor()->NSColor?
{
如果让image=self.statusItem?.button?.layer?.getBitmapImage(){
让imageRep=NSBitmapImageRep(数据:image.tiffRepresentation!)
如果let color=imageRep?.colorAt(x:Int(image.size.width/2.0),y:Int(image.size.height/2.0)){
返回颜色
}
}
归零
}
}
公共枚举菜单项:字符串
{
case light=“light”
case dark=“dark”
}
公共扩展非应用程序
{
类别var isDarkMode:布尔
{
返回NSApplication.shared.appearance?.description.lowercased().contains(“深色”)?false
}
}
公共分机
{
func getBitmapImage()->NSImage
{
设btmpImgRep=NSBitmapImageRep(bitmapDataPlanes:nil,pixelsWide:Int(self.frame.width),pixelsHigh:Int(self.frame.height),bitsPerSample:8,samplesPerPixel:4,hasAlpha:true,isPlanar:false,colorSpaceName:.deviceRGB,bytesPerRow:0,bitsPerPixel:32)
设ctx=NSGraphicsContext(bitmapImageRep:BTMPIMIGREP!)
让cgContext=ctx!.cgContext
self.render(在:cgContext中)
让cgImage=cgContext.makeImage()
返回NSImage(cgImage:cgImage!,大小:CGSize(宽度:self.frame.width,高度:self.frame.height))
}
}

我也有同样的问题,但我想我找到了解决办法。如中所述(请参见
NSStatusItem
的条目),您只需观察
NSStatusItem
按钮的
有效外观即可。如果
有效外观
的名称包含
,则为暗模式。否则就是灯光模式

我创建的示例代码显示
作为
NSStatusItem
的文本标签,可在中找到,请特别参阅。(我很抱歉因为使用Objective-C而成为濒临灭绝的恐龙。)您可以通过在Catalina或Big-Sur上运行,从系统首选项更改暗/光设置或桌面图片的颜色来测试它


编辑:事实证明,Big Sur有时会将
有效外观
从亮变亮或从暗变暗(从某种意义上说,尽管外观实际上没有改变,但调用了KVO)因此,建议在更改前后检查
有效外观的值,以确认实际更改的值。

对于Java 17,已添加此功能。它最终将被后移植到Java11

新物业为:

apple.awt.enableTemplateImages
// Verify theme to choose image version
Image iconImage = MacOSTrayIconFixer.getInitialIcon(blackImage, whiteImage);
// Create your TrayIcon using image
TrayIcon icon = new TrayIcon(iconImage, "Test");
// (Optional) add action and menu
icon.addActionListener((e) -> System.out.println("examples.BasicUsage.main():" + SwingUtilities.isEventDispatchThread()));

// Include in SystemTray BEFORE call fixer
SystemTray.getSystemTray().add(icon);

// Fix
MacOSTrayIconFixer.fix(icon, blackImage, whiteImage, false, 0);