简体   繁体   中英

Customise Freedesktop file with sbt-native-packager and JDKPackager plugin

I would like to customize the .desktop file created by the javapackager as part of the JDKPackager plugin of sbt-native-packager. It obviously uses a template:

[info]   Using default package resource [Menu shortcut descriptor]
         (add package/linux/Foo.desktop to the class path to customize)

In particular, I want to add the StartupWMClass entry that will be used by Gnome to unify all the windows opened by my application.

The javapackager refers to the target directory of the plugin, ie target/jdkpackager . This is created for example when the javafx-ant build-file is written. So we can piggyback here:

// 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
}

As long as there is a corresponding setting in the Ant task XML , there is an alternative solution: just rewriting the XML generated by the plugin, via antBuildDefn , will suffice.

Here's an example of specifying a menu category for the .desktop file, via adding the category attribute :

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)
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM