使用 sbt-native-packager 和 JDKPackager 插件自定义 Freedesktop 文件
Customise Freedesktop file with sbt-native-packager and JDKPackager plugin
我想自定义由 javapackager 创建的 .desktop
文件作为 sbt-native-packager 的 JDKPackager 插件的一部分。它显然使用了一个模板:
[info] Using default package resource [Menu shortcut descriptor]
(add package/linux/Foo.desktop to the class path to customize)
特别是,我想添加 Gnome 将使用的 StartupWMClass
条目来统一我的应用程序打开的所有 windows。
javapackager指的是插件的目标目录,即target/jdkpackager
。例如,这是在编写 javafx-ant 构建文件时创建的。所以我们可以在这里搭载:
// rewrite the task so that after the ant build is created,
// we add package/linux/MyApp.desktop
writeAntBuild in JDKPackager := {
val res = (writeAntBuild in JDKPackager).value
val main = (mainClass in JDKPackager).value
.getOrElse(sys.error("No main class specified"))
val tgt = (target in JDKPackager).value
val n = (name in JDKPackager).value
val wm = main.replace('.', '-')
val desktop =
s"""[Desktop Entry]
|Name=APPLICATION_NAME
|Comment=APPLICATION_SUMMARY
|Exec=/opt/APPLICATION_FS_NAME/APPLICATION_LAUNCHER_FILENAME
|Icon=/opt/APPLICATION_FS_NAME/APPLICATION_LAUNCHER_FILENAME.png
|Terminal=false
|Type=Application
|Categories=DEPLOY_BUNDLE_CATEGORY
|DESKTOP_MIMES
|StartupWMClass=$wm
|""".stripMargin
IO.write(tgt / "package" / "linux" / s"$n.desktop", desktop)
res
}
只要在Ant task XML里有相应的设置,还有一个替代方案:只需重写插件生成的XML,通过antBuildDefn
,就够了。
下面是通过添加 category
attribute 为 .desktop
文件指定菜单类别的示例:
antBuildDefn in JDKPackager := {
val origTask = (antBuildDefn in JDKPackager).value
val InfoLabel = "info"
val KeyRegex = s"$InfoLabel\.(.+)".r
import scala.xml._
import scala.xml.transform._
val infoRewrite = new RewriteRule {
override def transform(n: Node) = n match {
case e: Elem if e.prefix == "fx" && e.label == InfoLabel =>
e % Attribute("", "category", "Office", Null)
case other => other
}
}
new RuleTransformer(infoRewrite)(origTask)
}
我想自定义由 javapackager 创建的 .desktop
文件作为 sbt-native-packager 的 JDKPackager 插件的一部分。它显然使用了一个模板:
[info] Using default package resource [Menu shortcut descriptor]
(add package/linux/Foo.desktop to the class path to customize)
特别是,我想添加 Gnome 将使用的 StartupWMClass
条目来统一我的应用程序打开的所有 windows。
javapackager指的是插件的目标目录,即target/jdkpackager
。例如,这是在编写 javafx-ant 构建文件时创建的。所以我们可以在这里搭载:
// rewrite the task so that after the ant build is created,
// we add package/linux/MyApp.desktop
writeAntBuild in JDKPackager := {
val res = (writeAntBuild in JDKPackager).value
val main = (mainClass in JDKPackager).value
.getOrElse(sys.error("No main class specified"))
val tgt = (target in JDKPackager).value
val n = (name in JDKPackager).value
val wm = main.replace('.', '-')
val desktop =
s"""[Desktop Entry]
|Name=APPLICATION_NAME
|Comment=APPLICATION_SUMMARY
|Exec=/opt/APPLICATION_FS_NAME/APPLICATION_LAUNCHER_FILENAME
|Icon=/opt/APPLICATION_FS_NAME/APPLICATION_LAUNCHER_FILENAME.png
|Terminal=false
|Type=Application
|Categories=DEPLOY_BUNDLE_CATEGORY
|DESKTOP_MIMES
|StartupWMClass=$wm
|""".stripMargin
IO.write(tgt / "package" / "linux" / s"$n.desktop", desktop)
res
}
只要在Ant task XML里有相应的设置,还有一个替代方案:只需重写插件生成的XML,通过antBuildDefn
,就够了。
下面是通过添加 category
attribute 为 .desktop
文件指定菜单类别的示例:
antBuildDefn in JDKPackager := {
val origTask = (antBuildDefn in JDKPackager).value
val InfoLabel = "info"
val KeyRegex = s"$InfoLabel\.(.+)".r
import scala.xml._
import scala.xml.transform._
val infoRewrite = new RewriteRule {
override def transform(n: Node) = n match {
case e: Elem if e.prefix == "fx" && e.label == InfoLabel =>
e % Attribute("", "category", "Office", Null)
case other => other
}
}
new RuleTransformer(infoRewrite)(origTask)
}