1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2025-12-05 21:15:38 -05:00

sway: add support for sway

This commit is contained in:
bbedward
2025-10-29 15:08:11 -04:00
parent 7b26692c8e
commit c87fa0de5e
12 changed files with 212 additions and 26 deletions

View File

@@ -25,6 +25,7 @@ assignees: ""
- [ ] niri
- [ ] Hyprland
- [ ] dwl (MangoWC)
- [ ] sway
- [ ] Other (specify)
## Distribution

View File

@@ -22,6 +22,7 @@ Is this feature specific to one compositor?
- [ ] niri
- [ ] Hyprland
- [ ] dwl (MangoWC)
- [ ] sway
## Proposed Solution

View File

@@ -11,6 +11,7 @@ assignees: ""
- [ ] niri
- [ ] Hyprland
- [ ] dwl (MangoWC)
- [ ] sway
- [ ] other
## Distribution

View File

@@ -54,7 +54,7 @@ Item {
Loader {
id: blurredWallpaperBackgroundLoader
active: SettingsData.blurredWallpaperLayer
active: SettingsData.blurredWallpaperLayer && CompositorService.isNiri
asynchronous: false
sourceComponent: BlurredWallpaperBackground {}

View File

@@ -4,6 +4,7 @@ import QtQuick.Effects
import QtQuick.Shapes
import Quickshell
import Quickshell.Hyprland
import Quickshell.I3
import Quickshell.Io
import Quickshell.Services.Mpris
import Quickshell.Services.Notifications
@@ -31,6 +32,9 @@ Item {
focusedScreenName = Hyprland.focusedWorkspace.monitor.name
} else if (CompositorService.isNiri && NiriService.currentOutput) {
focusedScreenName = NiriService.currentOutput
} else if (CompositorService.isSway) {
const focusedWs = I3.workspaces?.values?.find(ws => ws.focused === true)
focusedScreenName = focusedWs?.monitor?.name || ""
}
if (!focusedScreenName && barVariants.instances.length > 0) {
@@ -55,6 +59,9 @@ Item {
focusedScreenName = Hyprland.focusedWorkspace.monitor.name
} else if (CompositorService.isNiri && NiriService.currentOutput) {
focusedScreenName = NiriService.currentOutput
} else if (CompositorService.isSway) {
const focusedWs = I3.workspaces?.values?.find(ws => ws.focused === true)
focusedScreenName = focusedWs?.monitor?.name || ""
}
if (!focusedScreenName && barVariants.instances.length > 0) {
@@ -573,6 +580,16 @@ Item {
return Array.from({length: 9}, (_, i) => i)
}
return Array.from({length: DwlService.tagCount}, (_, i) => i)
} else if (CompositorService.isSway) {
const workspaces = I3.workspaces?.values || []
if (workspaces.length === 0) return [{"num": 1}]
if (!barWindow.screenName || !SettingsData.workspacesPerMonitor) {
return workspaces.slice().sort((a, b) => a.num - b.num)
}
const monitorWorkspaces = workspaces.filter(ws => ws.monitor?.name === barWindow.screenName)
return monitorWorkspaces.length > 0 ? monitorWorkspaces.sort((a, b) => a.num - b.num) : [{"num": 1}]
}
return [1]
}
@@ -594,6 +611,14 @@ Item {
if (!outputState || !outputState.tags) return 0
const activeTags = DwlService.getActiveTags(barWindow.screenName)
return activeTags.length > 0 ? activeTags[0] : 0
} else if (CompositorService.isSway) {
if (!barWindow.screenName || !SettingsData.workspacesPerMonitor) {
const focusedWs = I3.workspaces?.values?.find(ws => ws.focused === true)
return focusedWs ? focusedWs.num : 1
}
const focusedWs = I3.workspaces?.values?.find(ws => ws.monitor?.name === barWindow.screenName && ws.focused === true)
return focusedWs ? focusedWs.num : 1
}
return 1
}
@@ -631,6 +656,15 @@ Item {
if (nextIndex !== validIndex) {
DwlService.switchToTag(barWindow.screenName, realWorkspaces[nextIndex])
}
} else if (CompositorService.isSway) {
const currentWs = getCurrentWorkspace()
const currentIndex = realWorkspaces.findIndex(ws => ws.num === currentWs)
const validIndex = currentIndex === -1 ? 0 : currentIndex
const nextIndex = direction > 0 ? Math.min(validIndex + 1, realWorkspaces.length - 1) : Math.max(validIndex - 1, 0)
if (nextIndex !== validIndex) {
try { I3.dispatch(`workspace number ${realWorkspaces[nextIndex].num}`) } catch(_){}
}
}
}

View File

@@ -37,7 +37,7 @@ BasePill {
}
IconImage {
visible: SettingsData.launcherLogoMode === "compositor" && (CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isDwl)
visible: SettingsData.launcherLogoMode === "compositor" && (CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isDwl || CompositorService.isSway)
anchors.centerIn: parent
width: Theme.barIconSize(root.barThickness, SettingsData.launcherLogoSizeOffset)
height: Theme.barIconSize(root.barThickness, SettingsData.launcherLogoSizeOffset)
@@ -50,6 +50,8 @@ BasePill {
return "file://" + Theme.shellDir + "/assets/hyprland.svg"
} else if (CompositorService.isDwl) {
return "file://" + Theme.shellDir + "/assets/mango.png"
} else if (CompositorService.isSway) {
return "file://" + Theme.shellDir + "/assets/sway.svg"
}
return ""
}

View File

@@ -3,6 +3,7 @@ import QtQuick.Controls
import Quickshell
import Quickshell.Widgets
import Quickshell.Hyprland
import Quickshell.I3
import qs.Common
import qs.Services
import qs.Widgets
@@ -36,6 +37,8 @@ Item {
return getHyprlandActiveWorkspace()
} else if (CompositorService.isDwl) {
return getDwlActiveTag()
} else if (CompositorService.isSway) {
return getSwayActiveWorkspace()
}
return 1
}
@@ -46,7 +49,6 @@ Item {
}
if (CompositorService.isHyprland) {
const baseList = getHyprlandWorkspaces()
// Filter out special workspaces
const filteredList = baseList.filter(ws => ws.id > -1)
return SettingsData.showWorkspacePadding ? padWorkspaces(filteredList) : filteredList
}
@@ -54,9 +56,35 @@ Item {
const baseList = getDwlTags()
return SettingsData.showWorkspacePadding ? padWorkspaces(baseList) : baseList
}
if (CompositorService.isSway) {
const baseList = getSwayWorkspaces()
return SettingsData.showWorkspacePadding ? padWorkspaces(baseList) : baseList
}
return [1]
}
function getSwayWorkspaces() {
const workspaces = I3.workspaces?.values || []
if (workspaces.length === 0) return [{"num": 1}]
if (!root.screenName || !SettingsData.workspacesPerMonitor) {
return workspaces.slice().sort((a, b) => a.num - b.num)
}
const monitorWorkspaces = workspaces.filter(ws => ws.monitor?.name === root.screenName)
return monitorWorkspaces.length > 0 ? monitorWorkspaces.sort((a, b) => a.num - b.num) : [{"num": 1}]
}
function getSwayActiveWorkspace() {
if (!root.screenName || !SettingsData.workspacesPerMonitor) {
const focusedWs = I3.workspaces?.values?.find(ws => ws.focused === true)
return focusedWs ? focusedWs.num : 1
}
const focusedWs = I3.workspaces?.values?.find(ws => ws.monitor?.name === root.screenName && ws.focused === true)
return focusedWs ? focusedWs.num : 1
}
function getWorkspaceIcons(ws) {
_desktopEntriesUpdateTrigger
if (!SettingsData.showWorkspaceApps || !ws) {
@@ -81,6 +109,8 @@ Item {
return []
}
targetWorkspaceId = ws.tag
} else if (CompositorService.isSway) {
targetWorkspaceId = ws.num !== undefined ? ws.num : ws
} else {
return []
}
@@ -91,6 +121,9 @@ Item {
let isActiveWs = false
if (CompositorService.isNiri) {
isActiveWs = NiriService.allWorkspaces.some(ws => ws.id === targetWorkspaceId && ws.is_active)
} else if (CompositorService.isSway) {
const focusedWs = I3.workspaces?.values?.find(ws => ws.focused === true)
isActiveWs = focusedWs ? (focusedWs.num === targetWorkspaceId) : false
} else if (CompositorService.isDwl) {
const output = DwlService.getOutputState(root.screenName)
if (output && output.tags) {
@@ -109,8 +142,9 @@ Item {
let winWs = null
if (CompositorService.isNiri) {
winWs = w.workspace_id
} else if (CompositorService.isSway) {
winWs = w.workspace?.num
} else {
// For Hyprland, we need to find the corresponding Hyprland toplevel to get workspace
const hyprlandToplevels = Array.from(Hyprland.toplevels?.values || [])
const hyprToplevel = hyprlandToplevels.find(ht => ht.wayland === w)
winWs = hyprToplevel?.workspace?.id
@@ -132,14 +166,14 @@ Item {
"type": "icon",
"icon": icon,
"isSteamApp": isSteamApp,
"active": !!(w.activated || (CompositorService.isNiri && w.is_focused)),
"active": !!((w.activated || w.is_focused) || (CompositorService.isNiri && w.is_focused)),
"count": 1,
"windowId": w.address || w.id,
"fallbackText": w.appId || w.class || w.title || ""
}
} else {
byApp[key].count++
if (w.activated || (CompositorService.isNiri && w.is_focused)) {
if ((w.activated || w.is_focused) || (CompositorService.isNiri && w.is_focused)) {
byApp[key].active = true
}
}
@@ -155,6 +189,8 @@ Item {
placeholder = {"id": -1, "name": ""}
} else if (CompositorService.isDwl) {
placeholder = {"tag": -1}
} else if (CompositorService.isSway) {
placeholder = {"num": -1}
} else {
placeholder = -1
}
@@ -277,6 +313,8 @@ Item {
return ws && ws.id !== -1
} else if (CompositorService.isDwl) {
return ws && ws.tag !== -1
} else if (CompositorService.isSway) {
return ws && ws.num !== -1
}
return ws !== -1
})
@@ -328,12 +366,27 @@ Item {
}
DwlService.switchToTag(root.screenName, realWorkspaces[nextIndex].tag)
} else if (CompositorService.isSway) {
const realWorkspaces = getRealWorkspaces()
if (realWorkspaces.length < 2) {
return
}
const currentIndex = realWorkspaces.findIndex(ws => ws.num === root.currentWorkspace)
const validIndex = currentIndex === -1 ? 0 : currentIndex
const nextIndex = direction > 0 ? Math.min(validIndex + 1, realWorkspaces.length - 1) : Math.max(validIndex - 1, 0)
if (nextIndex === validIndex) {
return
}
try { I3.dispatch(`workspace number ${realWorkspaces[nextIndex].num}`) } catch(_){}
}
}
width: isVertical ? barThickness : visualWidth
height: isVertical ? visualHeight : barThickness
visible: CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isDwl
visible: CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isDwl || CompositorService.isSway
Rectangle {
id: visualBackground
@@ -378,6 +431,8 @@ Item {
return modelData && modelData.id === root.currentWorkspace
} else if (CompositorService.isDwl) {
return modelData && modelData.tag === root.currentWorkspace
} else if (CompositorService.isSway) {
return modelData && modelData.num === root.currentWorkspace
}
return modelData === root.currentWorkspace
}
@@ -386,6 +441,8 @@ Item {
return modelData && modelData.id === -1
} else if (CompositorService.isDwl) {
return modelData && modelData.tag === -1
} else if (CompositorService.isSway) {
return modelData && modelData.num === -1
}
return modelData === -1
}
@@ -400,6 +457,8 @@ Item {
return loadedIsUrgent
} else if (CompositorService.isDwl) {
return modelData?.state === 2
} else if (CompositorService.isSway) {
return loadedIsUrgent
}
return false
}
@@ -452,6 +511,8 @@ Item {
Hyprland.dispatch(`workspace ${modelData.id}`)
} else if (CompositorService.isDwl && modelData?.tag !== undefined) {
DwlService.switchToTag(root.screenName, modelData.tag)
} else if (CompositorService.isSway && modelData?.num) {
try { I3.dispatch(`workspace number ${modelData.num}`) } catch(_){}
}
}
}
@@ -476,9 +537,11 @@ Item {
wsData = modelData;
} else if (CompositorService.isDwl) {
wsData = modelData;
} else if (CompositorService.isSway) {
wsData = modelData;
}
delegateRoot.loadedWorkspaceData = wsData;
delegateRoot.loadedIsUrgent = wsData?.is_urgent ?? false;
delegateRoot.loadedIsUrgent = wsData?.urgent ?? false;
var icData = null;
if (wsData?.name) {
@@ -488,7 +551,7 @@ Item {
delegateRoot.loadedHasIcon = icData !== null;
if (SettingsData.showWorkspaceApps) {
if (CompositorService.isDwl) {
if (CompositorService.isDwl || CompositorService.isSway) {
delegateRoot.loadedIcons = root.getWorkspaceIcons(modelData);
} else {
delegateRoot.loadedIcons = root.getWorkspaceIcons(CompositorService.isHyprland ? modelData : (modelData === -1 ? null : modelData));
@@ -742,6 +805,8 @@ Item {
isPlaceholder = modelData?.id === -1
} else if (CompositorService.isDwl) {
isPlaceholder = modelData?.tag === -1
} else if (CompositorService.isSway) {
isPlaceholder = modelData?.num === -1
} else {
isPlaceholder = modelData === -1
}
@@ -754,6 +819,8 @@ Item {
return modelData?.id || ""
} else if (CompositorService.isDwl) {
return (modelData?.tag !== undefined) ? (modelData.tag + 1) : ""
} else if (CompositorService.isSway) {
return modelData?.num || ""
}
return modelData - 1
}
@@ -788,6 +855,11 @@ Item {
enabled: CompositorService.isDwl
function onStateChanged() { delegateRoot.updateAllData() }
}
Connections {
target: I3.workspaces
enabled: CompositorService.isSway
function onValuesChanged() { delegateRoot.updateAllData() }
}
}
}
}

View File

@@ -93,6 +93,8 @@ Item {
modes.push("Hyprland")
} else if (CompositorService.isDwl) {
modes.push("mango")
} else if (CompositorService.isSway) {
modes.push("Sway")
} else {
modes.push(I18n.tr("Compositor"))
}

View File

@@ -12,7 +12,7 @@
</div>
A modern Wayland desktop shell built with [Quickshell](https://quickshell.org/) and [Go](https://go.dev/). Optimized for the [niri](https://github.com/YaLTeR/niri), [Hyprland](https://hyprland.org/), and [dwl/mangowc](https://github.com/DreamMaoMao/mangowc) compositors.
A modern Wayland desktop shell built with [Quickshell](https://quickshell.org/) and [Go](https://go.dev/). Optimized for the [niri](https://github.com/YaLTeR/niri), [Hyprland](https://hyprland.org/), [sway](https://swaywm.org/), and [dwl/mangowc](https://github.com/DreamMaoMao/mangowc) compositors.
Features notifications, app launcher, wallpaper customization, and fully customizable with [plugins](https://github.com/AvengeMedia/dms-plugin-registry).
@@ -134,7 +134,7 @@ curl -fsSL https://install.danklinux.com | sh
### Compositor Setup
DankMaterialShell particularly aims at supporting the **niri** and **Hyprland** compositors, but it does support more wayland compositors with a diminished feature set (no monitor off, workspace switcher, overview integration, etc.):
DankMaterialShell particularly aims at supporting the **niri**, **Hyprland**, **sway**, and **dwl/MangoWC** compositors, but it does support more wayland compositors with a diminished feature set (no monitor off, workspace switcher, overview integration, etc.):
**Niri**:
```bash
@@ -164,6 +164,10 @@ sudo dnf copr enable solopasha/hyprland && sudo dnf install hyprland
For detailed Hyprland installation instructions, see the [Hyprland wiki](https://wiki.hypr.land/Getting-Started/Installation/).
**sway/dwl (MangoWC)**:
TODO - not documented.
### Dank Shell Installation
*feel free to contribute steps for other distributions*

View File

@@ -13,10 +13,12 @@ Singleton {
property bool isHyprland: false
property bool isNiri: false
property bool isDwl: false
property bool isSway: false
property string compositor: "unknown"
readonly property string hyprlandSignature: Quickshell.env("HYPRLAND_INSTANCE_SIGNATURE")
readonly property string niriSocket: Quickshell.env("NIRI_SOCKET")
readonly property string swaySocket: Quickshell.env("SWAYSOCK")
property bool useNiriSorting: isNiri && NiriService
property var sortedToplevels: sortedToplevelsCache
@@ -363,6 +365,7 @@ Singleton {
isHyprland = true
isNiri = false
isDwl = false
isSway = false
compositor = "hyprland"
console.info("CompositorService: Detected Hyprland")
try {
@@ -377,28 +380,39 @@ Singleton {
isNiri = true
isHyprland = false
isDwl = false
isSway = false
compositor = "niri"
console.info("CompositorService: Detected Niri with socket:", niriSocket)
NiriService.generateNiriBinds()
NiriService.generateNiriBlurrule()
} else {
isHyprland = false
isNiri = true
isDwl = false
compositor = "niri"
console.warn("CompositorService: Niri socket check failed, defaulting to Niri anyway")
}
}, 0)
return
}
if (swaySocket && swaySocket.length > 0) {
Proc.runCommand("swaySocketCheck", ["test", "-S", swaySocket], (output, exitCode) => {
if (exitCode === 0) {
isNiri = false
isHyprland = false
isDwl = false
isSway = true
compositor = "sway"
console.info("CompositorService: Detected Sway with socket:", swaySocket)
}
}, 0)
return
}
if (DMSService.dmsAvailable) {
Qt.callLater(checkForDwl)
} else {
if (DMSService.dmsAvailable) {
Qt.callLater(checkForDwl)
} else {
isHyprland = false
isNiri = false
isDwl = false
compositor = "unknown"
console.warn("CompositorService: No compositor detected")
}
isHyprland = false
isNiri = false
isDwl = false
isSway = false
compositor = "unknown"
console.warn("CompositorService: No compositor detected")
}
}
@@ -425,6 +439,7 @@ Singleton {
if (isNiri) return NiriService.powerOffMonitors()
if (isHyprland) return Hyprland.dispatch("dpms off")
if (isDwl) return _dwlPowerOffMonitors()
if (isSway) { try { I3.dispatch("output * dpms off") } catch(_){} return }
console.warn("CompositorService: Cannot power off monitors, unknown compositor")
}
@@ -432,6 +447,7 @@ Singleton {
if (isNiri) return NiriService.powerOnMonitors()
if (isHyprland) return Hyprland.dispatch("dpms on")
if (isDwl) return _dwlPowerOnMonitors()
if (isSway) { try { I3.dispatch("output * dpms on") } catch(_){} return }
console.warn("CompositorService: Cannot power on monitors, unknown compositor")
}

View File

@@ -6,6 +6,7 @@ import QtQuick
import Quickshell
import Quickshell.Io
import Quickshell.Hyprland
import Quickshell.I3
import Quickshell.Wayland
import qs.Common
@@ -189,6 +190,11 @@ Singleton {
return
}
if (CompositorService.isSway) {
try { I3.dispatch("exit") } catch(_){}
return
}
Hyprland.dispatch("exit")
} else {
Quickshell.execDetached(["sh", "-c", SettingsData.customPowerActionLogout])

47
assets/sway.svg Normal file
View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="1589.1 -0.1 410.9 383.1" enable-background="new 1589.1 -0.1 410.9 383.1" xml:space="preserve">
<polygon fill="#FF4040" points="1794.4,383 1589.1,304.6 1589.1,273.2 1794.4,291.5 1999.9,273.2 1999.9,304.6 "/>
<path fill="#AFA137" d="M1794.4,351.4l-205.3-78.2c0,0,13.6-5.3,16.2-6.2c12.2-4.5,25-8.3,36.8-13.4c24.5-10.9,51.4-17.8,78.2-18.2
c15.4-0.2,29.8,4.5,44.8,2.2c17.4-2.9,34.1-9.4,51.6-12.9c31.6-6,62.3,2.2,91.5,13.8c30,11.8,59.2,22.3,89.3,33.8
c0.9,0.4,1.6,0.5,2.5,0.9L1794.4,351.4z"/>
<g>
<g>
<path fill="#C6ADAC" d="M1656.3,277.2c-2.5-57,55.2-87.7,97.8-111.1c37.2-20.3,83.7-46.8,74.1-96.4c-2-10.3-17.8-6-15.8,4.4
c4.4,22.7-8.5,39.9-25.8,53c-20.3,15.4-43.7,26.3-65.9,38.8c-40.8,23.2-83.1,59.9-81,111.3
C1640.5,287.7,1656.8,287.7,1656.3,277.2L1656.3,277.2z"/>
</g>
</g>
<g>
<g>
<path fill="#C6ADAC" d="M1728,183.7c56.6,11.8,116.4-5.1,158.3-45c7.6-7.3-4-18.9-11.6-11.6c-37.4,35.8-91.7,51.4-142.3,40.8
C1722,165.9,1717.6,181.5,1728,183.7L1728,183.7z"/>
</g>
</g>
<g>
<path fill="#68751C" d="M1727.8,64.8c14.9,3.6,40.1-13.6,51.4-19.1c14.5-7.1,29.6-12.5,44.3-19.1c5.6-2.5,24-8.3,24.1-16.5
c0.4-10.2-19.1-10.7-25.4-10c-12.9,1.3-25.4,5.3-37.8,8.9c-12.7,3.8-25,8.9-36.8,15.2c-8.9,4.7-21.1,13.1-26.3,21.8
c-3.3,5.3-3.1,13.1,2,16.7C1724.5,63.7,1726.2,64.4,1727.8,64.8z"/>
<path fill="#68751C" d="M1819.1,37.2c2.5-1.5,5.1-2.7,7.6-4c21.1-10,45.4-18.2,69.3-20c20.9-1.6,43.9-5.4,64.6,0.2
c10.7,2.9,22.5,13.3,16.9,23.2c-4.2,7.4-21.2,17.4-28.7,22.9c-27.4,19.4-65.7,28-100.7,29.8c-25.4,1.3-67.3-13.3-44.1-40.7
C1808,44.1,1813.3,40.5,1819.1,37.2z"/>
<path fill="#68751C" d="M1958.9,60.1c5.8,0.2,12.5,1.6,15.2,6.9c2.2,4.4,0.5,9.6-2.5,13.3c-3.3,3.6-7.6,5.6-12.2,7.4
c-22.5,9.4-46.6,15.1-71,16.7c-6.7,0.4-13.8,0.5-20.3-1.6s-12.3-7.1-14.2-13.6c-4-15.1,29-20,37.9-21.6s17.8-2.7,26.7-3.1
C1932,63.5,1945.1,59.5,1958.9,60.1z"/>
<path fill="#68751C" d="M1955.6,158.8c-8.9-22-62.4,2.2-74.6,10c-4.5,2.9-9.3,7.3-8.3,12.5c0.9,5.6,7.6,8.2,13.4,8.9
C1900.2,192,1966.1,184.8,1955.6,158.8z"/>
<path fill="#68751C" d="M1787.5,87.7c-2.2,14.5-21.8,30.5-34.9,35c-12.7,4.5-33.9-4.9-26.1-20.3c6.9-13.4,41-37.4,55.9-27.6
C1786.6,77.5,1788.2,83,1787.5,87.7z"/>
<path fill="#68751C" d="M1825.1,159.9c20.9,2.5,42.3-0.2,61.9-7.6c4.4-1.6,8.9-3.8,10.7-8.2c1.3-3.3,0.4-7.3-2.2-9.6
c-2.5-2.4-6.5-3.1-9.6-1.6c-5.8-6.4-16-5.8-24.5-4.2c-13.4,2.7-26.7,7.6-38.8,14c-4.4,2.4-9.3,6.4-8,11.1
C1815.8,157.9,1820.9,159.4,1825.1,159.9z"/>
<path fill="#68751C" d="M1849.4,143c27.6,6.2,57.9-1.8,81.5-17.1c3.1-2,6.5-5.1,6-8.9c-0.7-4.5-6.5-6-11.3-5.8
c-26.9,0.4-54.1,7.1-77.5,20.7c-2.7,1.5-5.6,4-4.9,6.9C1844,141.4,1846.9,142.5,1849.4,143z"/>
<g>
<path fill="#68751C" d="M1711.1,106.4c2.5-3.1,4.7-6.9,3.6-10.5c-5.1-20.1-32.5,6-39,12c-8.3,7.6-8,14.3,5.6,14.3
C1692.6,122,1704.4,114.5,1711.1,106.4z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.2 KiB