summaryrefslogtreecommitdiffstats
path: root/panels/multitasking
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--panels/multitasking/assets/active-screen-edges-rtl.svg1
-rw-r--r--panels/multitasking/assets/active-screen-edges.svg1
-rw-r--r--panels/multitasking/assets/hot-corner-rtl.svg1
-rw-r--r--panels/multitasking/assets/hot-corner.svg1
-rw-r--r--panels/multitasking/assets/workspaces-primary-display.svg1
-rw-r--r--panels/multitasking/assets/workspaces-span-displays.svg1
-rw-r--r--panels/multitasking/cc-multitasking-panel.c161
-rw-r--r--panels/multitasking/cc-multitasking-panel.h30
-rw-r--r--panels/multitasking/cc-multitasking-panel.ui229
-rw-r--r--panels/multitasking/cc-multitasking-row.c572
-rw-r--r--panels/multitasking/cc-multitasking-row.h66
-rw-r--r--panels/multitasking/cc-multitasking-row.ui100
-rw-r--r--panels/multitasking/gnome-multitasking-panel.desktop.in.in14
-rw-r--r--panels/multitasking/icons/meson.build4
-rw-r--r--panels/multitasking/icons/scalable/org.gnome.Settings-multitasking-symbolic.svg4
-rw-r--r--panels/multitasking/meson.build48
-rw-r--r--panels/multitasking/multitasking.gresource.xml15
17 files changed, 1249 insertions, 0 deletions
diff --git a/panels/multitasking/assets/active-screen-edges-rtl.svg b/panels/multitasking/assets/active-screen-edges-rtl.svg
new file mode 100644
index 0000000..4c2bd1a
--- /dev/null
+++ b/panels/multitasking/assets/active-screen-edges-rtl.svg
@@ -0,0 +1 @@
+<svg width="160" height="94" viewBox="0 0 42.333 24.871" xmlns="http://www.w3.org/2000/svg"><path style="display:inline;vector-effect:none;fill:none;fill-opacity:1;stroke:#3584e4;stroke-width:.529167;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none" d="M.265.265h41.804v24.342H.265Z"/><path style="display:inline;opacity:.287;vector-effect:none;fill:#3584e4;fill-opacity:1;stroke:none;stroke-width:2.99998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal" d="M1.943 5.178v87.681h77.428V77.053h-68.39c-1.662 0-3-1.338-3-3V22.055c0-1.662 1.338-3 3-3h68.39V5.178Z" transform="matrix(.26459 0 0 .26459 0 0)"/><g transform="matrix(-.26458 0 0 .26458 424.372 1156.76)" style="display:inline"><rect ry="3" rx="3" y="-4353.007" x="1520.006" height="58" width="76" style="opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#3584e4;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none"/><path overflow="visible" font-weight="400" style="color:#bebebe;font-weight:400;line-height:normal;font-family:'Andale Mono';-inkscape-font-specification:'Andale Mono';text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-transform:none;overflow:visible;fill:#3584e4;fill-opacity:1;marker:none" d="M1583-4348.006h1.031c.255.011.51.13.688.313l2.281 2.28 2.312-2.28c.266-.232.447-.307.688-.314h1v1c0 .286-.034.55-.25.75l-2.281 2.282 2.25 2.25c.188.188.281.454.281.72v1h-1c-.265 0-.53-.094-.719-.282l-2.281-2.28-2.281 2.28a1.015 1.015 0 0 1-.719.281h-1v-1c0-.265.093-.53.281-.719l2.281-2.25-2.28-2.28a.909.909 0 0 1-.282-.75z"/><g style="display:inline;fill:#fff;fill-opacity:1;stroke:#3584e4;stroke-opacity:1"><path style="color:#000;display:block;overflow:visible;visibility:visible;fill:#3584e4;fill-opacity:1;fill-rule:nonzero;stroke:#3584e4;stroke-width:.999998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" d="M1545.908-4344.757v26.838l-6.053-5.916-3.46 7.07c-.848 1.914-5.25.376-3.999-2.182l3.423-7.34h-7.64z"/></g></g><path style="fill:#3584e4;fill-opacity:1;stroke-width:.52917;stroke-linejoin:round;stop-color:#000" d="M0 0h42.334v1.852H0z"/></svg> \ No newline at end of file
diff --git a/panels/multitasking/assets/active-screen-edges.svg b/panels/multitasking/assets/active-screen-edges.svg
new file mode 100644
index 0000000..bc249ab
--- /dev/null
+++ b/panels/multitasking/assets/active-screen-edges.svg
@@ -0,0 +1 @@
+<svg width="160" height="94" viewBox="0 0 42.333 24.871" xmlns="http://www.w3.org/2000/svg"><path style="display:inline;vector-effect:none;fill:none;fill-opacity:1;stroke:#3584e4;stroke-width:.529167;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none" d="M.265.265h41.804v24.342H.265Z"/><path style="display:inline;opacity:.287;vector-effect:none;fill:#3584e4;fill-opacity:1;stroke:none;stroke-width:2.99998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal" d="M1.943 5.178v87.681h77.428V77.053h-68.39c-1.662 0-3-1.338-3-3V22.055c0-1.662 1.338-3 3-3h68.39V5.178Z" transform="matrix(.26459 0 0 .26459 0 0)"/><g transform="translate(-400.062 1156.76) scale(.26458)" style="display:inline"><rect ry="3" rx="3" y="-4353.007" x="1520.006" height="58" width="76" style="opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#3584e4;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none"/><path overflow="visible" font-weight="400" style="color:#bebebe;font-weight:400;line-height:normal;font-family:'Andale Mono';-inkscape-font-specification:'Andale Mono';text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-transform:none;overflow:visible;fill:#3584e4;fill-opacity:1;marker:none" d="M1583-4348.006h1.031c.255.011.51.13.688.313l2.281 2.28 2.312-2.28c.266-.232.447-.307.688-.314h1v1c0 .286-.034.55-.25.75l-2.281 2.282 2.25 2.25c.188.188.281.454.281.72v1h-1c-.265 0-.53-.094-.719-.282l-2.281-2.28-2.281 2.28a1.015 1.015 0 0 1-.719.281h-1v-1c0-.265.093-.53.281-.719l2.281-2.25-2.28-2.28a.909.909 0 0 1-.282-.75z"/><g style="display:inline;fill:#fff;fill-opacity:1;stroke:#3584e4;stroke-opacity:1"><path d="M26.605 2.318v16.44l3.712-3.624 2.122 4.331c.52 1.172 3.22.23 2.452-1.337l-2.099-4.496h4.685z" style="color:#000;display:block;overflow:visible;visibility:visible;fill:#fff;fill-opacity:1;fill-rule:nonzero;stroke:#3584e4;stroke-width:.612915;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" transform="matrix(1.6306 0 0 1.63249 1484.124 -4348.541)"/><path style="color:#000;display:block;overflow:visible;visibility:visible;fill:#3584e4;fill-opacity:1;fill-rule:nonzero;stroke:#3584e4;stroke-width:.612915;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" d="M26.605 2.318v16.44l3.712-3.624 2.122 4.331c.52 1.172 3.22.23 2.452-1.337l-2.099-4.496h4.685z" transform="matrix(1.6306 0 0 1.63249 1484.124 -4348.541)"/></g></g><path style="fill:#3584e4;fill-opacity:1;stroke-width:.52917;stroke-linejoin:round;stop-color:#000" d="M0 0h42.334v1.852H0z"/></svg> \ No newline at end of file
diff --git a/panels/multitasking/assets/hot-corner-rtl.svg b/panels/multitasking/assets/hot-corner-rtl.svg
new file mode 100644
index 0000000..4eb3aba
--- /dev/null
+++ b/panels/multitasking/assets/hot-corner-rtl.svg
@@ -0,0 +1 @@
+<svg width="160" height="94" viewBox="0 0 42.333 24.871" xmlns="http://www.w3.org/2000/svg"><defs><clipPath id="a" clipPathUnits="userSpaceOnUse"><path style="opacity:1;vector-effect:none;fill:#3584e4;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal" d="M316-4731.007h162v95H316z"/></clipPath></defs><g style="display:inline"><path style="opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#3584e4;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none" d="M1501.006-3631.007h158v92h-158z" transform="matrix(-.26458 0 0 .26458 439.199 960.969)"/></g><g clip-path="url(#a)" transform="matrix(-.26458 0 0 .26458 125.93 1251.746)" style="display:inline"><path style="color:#000;opacity:.249;fill:#3584e4;stroke-width:.999981;-inkscape-stroke:none" d="M159.96-79.697C115.93-79.697 80.2-43.972 80.2.06a79.352 79.352 0 0 0 13.98 45.082v-5.497C87.212 28.09 83.2 14.546 83.2.061c0-42.411 34.35-76.758 76.76-76.758 42.412 0 76.76 34.347 76.76 76.758 0 42.41-34.348 76.76-76.76 76.76-19.455 0-37.203-7.245-50.728-19.165h-4.402c14.327 13.718 33.742 22.164 55.13 22.164 44.033 0 79.76-35.727 79.76-79.76 0-44.032-35.727-79.757-79.76-79.757z" transform="matrix(-1.00002 0 0 1.00002 475.963 -4731.068)"/><path style="color:#000;opacity:.474;fill:#3584e4;stroke-width:.999981;-inkscape-stroke:none" d="M159.96-49.43c-27.314 0-49.491 22.175-49.491 49.49 0 7.333 1.61 14.287 4.476 20.55l3.178-.245A46.34 46.34 0 0 1 113.47.061c0-25.695 20.798-46.49 46.492-46.49S206.45-25.635 206.45.06c0 25.694-20.796 46.49-46.49 46.49a46.337 46.337 0 0 1-20.357-4.68l-.247 3.18a49.246 49.246 0 0 0 20.604 4.5c27.315 0 49.49-22.175 49.49-49.49 0-27.316-22.175-49.49-49.49-49.49z" transform="matrix(-1.00002 0 0 1.00002 475.963 -4731.068)"/><path style="color:#000;opacity:.705;fill:#3584e4;stroke-width:.999981;-inkscape-stroke:none" d="M159.96-28.297c-15.643 0-28.358 12.713-28.358 28.358 0 7.171 2.676 13.723 7.078 18.72l2.713-.209-.21 2.721c5.005 4.43 11.58 7.127 18.778 7.127 15.644 0 28.357-12.715 28.357-28.36 0-15.644-12.713-28.357-28.357-28.357zm0 3c14.024 0 25.358 11.335 25.358 25.358 0 14.022-11.334 25.359-25.357 25.359S134.6 14.083 134.6.06c0-14.022 11.337-25.357 25.36-25.357z" transform="matrix(-1.00002 0 0 1.00002 475.963 -4731.068)"/><circle r="16.568" cy="-4731.007" cx="316" style="opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#3584e4;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"/></g><path style="color:#000;display:inline;overflow:visible;visibility:visible;fill:none;fill-opacity:1;stroke:#3584e4;stroke-width:.262885;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:.95;stroke-opacity:1;marker:none;enable-background:accumulate" d="m30.31 9.024 1.341-1.38-2.121-2.123 7.88-.607-.606 7.89-2.122-2.124-3.288 3.292"/><g style="display:inline"><path style="color:#000;display:block;overflow:visible;visibility:visible;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#3584e4;stroke-width:.612915;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:1.22583,.612915;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" d="M29.691 6.634v16.44l3.712-3.624 2.122 4.331c.52 1.171 3.22.23 2.452-1.337l-2.099-4.497h4.685z" transform="matrix(.42866 0 0 .42916 12.191 7.553)"/></g><path style="fill:#3584e4;fill-opacity:1;stroke-width:.52917;stroke-linejoin:round;stop-color:#000" d="M0 0h42.334v1.852H0z"/></svg> \ No newline at end of file
diff --git a/panels/multitasking/assets/hot-corner.svg b/panels/multitasking/assets/hot-corner.svg
new file mode 100644
index 0000000..66cee2a
--- /dev/null
+++ b/panels/multitasking/assets/hot-corner.svg
@@ -0,0 +1 @@
+<svg width="160" height="94" viewBox="0 0 42.333 24.871" xmlns="http://www.w3.org/2000/svg"><defs><clipPath id="a" clipPathUnits="userSpaceOnUse"><path style="opacity:1;vector-effect:none;fill:#3584e4;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal" d="M316-4731.007h162v95H316z"/></clipPath></defs><g style="display:inline"><path style="opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#3584e4;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none" d="M1501.006-3631.007h158v92h-158z" transform="translate(-396.877 960.969) scale(.26458)"/></g><g clip-path="url(#a)" transform="translate(-83.608 1251.746) scale(.26458)" style="display:inline"><path style="color:#000;opacity:.249;fill:#3584e4;stroke-width:.999981;-inkscape-stroke:none" d="M-.002-79.697c-44.032 0-79.76 35.725-79.76 79.758 0 44.032 35.728 79.76 79.76 79.76 21.164 0 40.396-8.27 54.678-21.733v-4.156C40.756 68.058 21.408 76.82-.002 76.82c-42.41 0-76.76-34.349-76.76-76.76 0-42.41 34.35-76.757 76.76-76.757 42.41 0 76.76 34.347 76.76 76.758 0 17.32-5.734 33.29-15.4 46.13l2.085 2.174C73.672 34.955 79.758 18.22 79.758.061c0-44.033-35.728-79.758-79.76-79.758z" transform="matrix(1.00002 0 0 1.00002 316.002 -4731.068)"/><path style="color:#000;opacity:.474;fill:#3584e4;-inkscape-stroke:none" d="M316-4780.498c-27.316 0-49.492 22.176-49.492 49.492s22.176 49.49 49.492 49.49c7.56 0 14.733-1.697 21.146-4.732l-1.283-2.711a46.295 46.295 0 0 1-19.863 4.443c-25.695 0-46.492-20.795-46.492-46.49 0-25.694 20.797-46.492 46.492-46.492 25.695 0 46.492 20.798 46.492 46.492 0 7.094-1.58 13.792-4.416 19.803l2.92.835a49.266 49.266 0 0 0 4.496-20.638c0-27.316-22.176-49.492-49.492-49.492z"/><path style="color:#000;opacity:.705;fill:#3584e4;-inkscape-stroke:none" d="M316-4759.365c-15.644 0-28.36 12.715-28.36 28.36 0 15.644 12.716 28.357 28.36 28.357a28.277 28.277 0 0 0 18.967-7.275l.035-2.145 2.033.082a28.273 28.273 0 0 0 7.324-19.02c0-15.644-12.715-28.36-28.359-28.36zm0 3c14.023 0 25.36 11.336 25.36 25.36a25.247 25.247 0 0 1-7.864 18.355 25.253 25.253 0 0 1-17.496 7.002c-14.023 0-25.36-11.335-25.36-25.358s11.337-25.36 25.36-25.36z"/><circle r="16.568" cy="-4731.007" cx="316" style="opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#3584e4;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"/></g><g style="display:inline"><path style="color:#000;display:inline;overflow:visible;visibility:visible;fill:none;stroke:#3584e4;stroke-width:.612915;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:.95;stroke-opacity:1;marker:none;enable-background:accumulate;fill-opacity:1" d="m275.62 271.75-3.13-3.214 4.95-4.95-18.385-1.414 1.414 18.385 4.95-4.95 7.671 7.672" transform="matrix(.42866 0 0 .42916 -106.135 -107.6)"/><g style="display:inline"><path style="color:#000;display:block;overflow:visible;visibility:visible;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#3584e4;stroke-width:.612915;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:1.22583,.612915;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" d="M29.691 6.634v16.44l3.712-3.624 2.122 4.331c.52 1.171 3.22.23 2.452-1.337l-2.099-4.497h4.685z" transform="matrix(.42866 0 0 .42916 1.739 7.533)"/></g></g><path style="fill:#3584e4;fill-opacity:1;stroke-width:.52917;stroke-linejoin:round;stop-color:#000" d="M0 0h42.334v1.852H0z"/></svg> \ No newline at end of file
diff --git a/panels/multitasking/assets/workspaces-primary-display.svg b/panels/multitasking/assets/workspaces-primary-display.svg
new file mode 100644
index 0000000..3a3bed7
--- /dev/null
+++ b/panels/multitasking/assets/workspaces-primary-display.svg
@@ -0,0 +1 @@
+<svg width="326" height="94" viewBox="0 0 86.255 24.871" xmlns="http://www.w3.org/2000/svg"><path style="display:inline;opacity:.287;vector-effect:none;fill:#3584e4;fill-opacity:1;stroke:#3584e4;stroke-width:.79375;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal" d="M.397.397h41.54v24.078H.397Z"/><path style="display:inline;vector-effect:none;fill:none;fill-opacity:1;stroke:#3584e4;stroke-width:.529167;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none" d="M.265.265h41.804v24.342H.265Z"/><path style="vector-effect:none;fill:none;fill-opacity:1;stroke:#3584e4;stroke-width:.529162;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none" d="M44.186.265H85.99v24.342H44.186z"/><path style="display:inline;opacity:.287;vector-effect:none;fill:#3584e4;fill-opacity:1;stroke:#3584e4;stroke-width:.79375;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal" d="M44.318.397h41.54v24.078h-41.54Z"/><rect style="opacity:1;fill:#3584e4;fill-opacity:1;stroke:#ed333b;stroke-width:0;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none" width="33.338" height="19.579" x="48.419" y="2.646" rx="1.323" ry="1.323"/><rect style="opacity:1;fill:#3584e4;fill-opacity:1;stroke:#ed333b;stroke-width:0;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none" width="26.459" height="15.346" x="7.937" y="4.763" rx="1.323" ry="1.323"/><path style="opacity:1;fill:#3584e4;stroke:#ed333b;stroke-width:0;stroke-linecap:round;fill-opacity:1" d="M38.365 4.763h3.44v15.345h-3.44a1.32 1.32 0 0 1-1.323-1.322v-12.7c0-.733.59-1.323 1.323-1.323zM3.969 4.763H.529v15.345h3.44a1.32 1.32 0 0 0 1.323-1.322v-12.7a1.32 1.32 0 0 0-1.323-1.323Z"/><path style="fill:#3584e4;fill-opacity:1;stroke-width:.52917;stroke-linejoin:round;stop-color:#000" d="M0 0h42.334v1.852H0z"/></svg> \ No newline at end of file
diff --git a/panels/multitasking/assets/workspaces-span-displays.svg b/panels/multitasking/assets/workspaces-span-displays.svg
new file mode 100644
index 0000000..571ee10
--- /dev/null
+++ b/panels/multitasking/assets/workspaces-span-displays.svg
@@ -0,0 +1 @@
+<svg width="326" height="94" viewBox="0 0 86.255 24.871" xmlns="http://www.w3.org/2000/svg"><path style="display:inline;opacity:.287;vector-effect:none;fill:#3584e4;fill-opacity:1;stroke:#3584e4;stroke-width:.79375;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal" d="M.397.397h41.54v24.078H.397Z"/><path style="display:inline;vector-effect:none;fill:none;fill-opacity:1;stroke:#3584e4;stroke-width:.529167;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none" d="M.265.265h41.804v24.342H.265Z"/><path style="vector-effect:none;fill:none;fill-opacity:1;stroke:#3584e4;stroke-width:.529162;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none" d="M44.186.265H85.99v24.342H44.186z"/><path style="display:inline;opacity:.287;vector-effect:none;fill:#3584e4;fill-opacity:1;stroke:#3584e4;stroke-width:.79375;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal" d="M44.318.397h41.54v24.078h-41.54Z"/><rect style="opacity:1;fill:#3584e4;fill-opacity:1;stroke:#ed333b;stroke-width:0;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none" width="26.459" height="15.346" x="7.937" y="4.763" rx="1.323" ry="1.323"/><path style="opacity:1;fill:#3584e4;stroke:#ed333b;stroke-width:0;stroke-linecap:round;fill-opacity:1" d="M38.365 4.763h3.44V20.11h-3.44a1.32 1.32 0 0 1-1.323-1.323v-12.7c0-.733.59-1.323 1.323-1.323zM3.969 4.763H.529V20.11h3.44a1.32 1.32 0 0 0 1.323-1.323v-12.7a1.32 1.32 0 0 0-1.323-1.323z"/><g transform="translate(43.921 -.529)"><rect style="opacity:1;fill:#3584e4;fill-opacity:1;stroke:#ed333b;stroke-width:0;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none" width="26.459" height="15.346" x="7.937" y="5.292" rx="1.323" ry="1.323"/><path style="opacity:1;fill:#3584e4;stroke:#ed333b;stroke-width:0;stroke-linecap:round;fill-opacity:1" d="M38.365 5.292h3.44v15.346h-3.44a1.32 1.32 0 0 1-1.323-1.323v-12.7c0-.733.59-1.323 1.323-1.323zM3.969 5.292H.529v15.346h3.44a1.32 1.32 0 0 0 1.323-1.323v-12.7a1.32 1.32 0 0 0-1.323-1.323z"/></g><g style="stroke-width:.999999"><path style="fill:#3584e4;fill-opacity:1;stroke-width:.52917;stroke-linejoin:round;stop-color:#000" d="M0 0h42.334v1.852H0z"/></g></svg> \ No newline at end of file
diff --git a/panels/multitasking/cc-multitasking-panel.c b/panels/multitasking/cc-multitasking-panel.c
new file mode 100644
index 0000000..db4c47a
--- /dev/null
+++ b/panels/multitasking/cc-multitasking-panel.c
@@ -0,0 +1,161 @@
+/* cc-multitasking-panel.h
+ *
+ * Copyright 2020 Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+
+#include "cc-multitasking-panel.h"
+
+#include "cc-multitasking-resources.h"
+#include "cc-multitasking-row.h"
+
+struct _CcMultitaskingPanel
+{
+ CcPanel parent_instance;
+
+ GSettings *interface_settings;
+ GSettings *mutter_settings;
+ GSettings *shell_settings;
+ GSettings *wm_settings;
+
+ GtkPicture *active_screen_edges_picture;
+ GtkSwitch *active_screen_edges_switch;
+ GtkCheckButton *all_workspaces_radio;
+ GtkCheckButton *current_workspace_radio;
+ GtkCheckButton *dynamic_workspaces_radio;
+ GtkCheckButton *fixed_workspaces_radio;
+ GtkPicture *hot_corner_picture;
+ GtkSwitch *hot_corner_switch;
+ GtkSpinButton *number_of_workspaces_spin;
+ GtkCheckButton *workspaces_primary_display_radio;
+ GtkCheckButton *workspaces_span_displays_radio;
+};
+
+CC_PANEL_REGISTER (CcMultitaskingPanel, cc_multitasking_panel)
+
+/* GObject overrides */
+
+static void
+cc_multitasking_panel_finalize (GObject *object)
+{
+ CcMultitaskingPanel *self = (CcMultitaskingPanel *)object;
+
+ g_clear_object (&self->interface_settings);
+ g_clear_object (&self->mutter_settings);
+ g_clear_object (&self->shell_settings);
+ g_clear_object (&self->wm_settings);
+
+ G_OBJECT_CLASS (cc_multitasking_panel_parent_class)->finalize (object);
+}
+
+static void
+cc_multitasking_panel_class_init (CcMultitaskingPanelClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ g_type_ensure (CC_TYPE_MULTITASKING_ROW);
+
+ object_class->finalize = cc_multitasking_panel_finalize;
+
+ gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/multitasking/cc-multitasking-panel.ui");
+
+ gtk_widget_class_bind_template_child (widget_class, CcMultitaskingPanel, active_screen_edges_picture);
+ gtk_widget_class_bind_template_child (widget_class, CcMultitaskingPanel, active_screen_edges_switch);
+ gtk_widget_class_bind_template_child (widget_class, CcMultitaskingPanel, all_workspaces_radio);
+ gtk_widget_class_bind_template_child (widget_class, CcMultitaskingPanel, current_workspace_radio);
+ gtk_widget_class_bind_template_child (widget_class, CcMultitaskingPanel, dynamic_workspaces_radio);
+ gtk_widget_class_bind_template_child (widget_class, CcMultitaskingPanel, fixed_workspaces_radio);
+ gtk_widget_class_bind_template_child (widget_class, CcMultitaskingPanel, hot_corner_picture);
+ gtk_widget_class_bind_template_child (widget_class, CcMultitaskingPanel, hot_corner_switch);
+ gtk_widget_class_bind_template_child (widget_class, CcMultitaskingPanel, number_of_workspaces_spin);
+ gtk_widget_class_bind_template_child (widget_class, CcMultitaskingPanel, workspaces_primary_display_radio);
+ gtk_widget_class_bind_template_child (widget_class, CcMultitaskingPanel, workspaces_span_displays_radio);
+}
+
+static void
+cc_multitasking_panel_init (CcMultitaskingPanel *self)
+{
+ g_resources_register (cc_multitasking_get_resource ());
+
+ gtk_widget_init_template (GTK_WIDGET (self));
+
+ self->interface_settings = g_settings_new ("org.gnome.desktop.interface");
+ g_settings_bind (self->interface_settings,
+ "enable-hot-corners",
+ self->hot_corner_switch,
+ "active",
+ G_SETTINGS_BIND_DEFAULT);
+
+ self->mutter_settings = g_settings_new ("org.gnome.mutter");
+
+ if (g_settings_get_boolean (self->mutter_settings, "workspaces-only-on-primary"))
+ gtk_check_button_set_active (self->workspaces_primary_display_radio, TRUE);
+ else
+ gtk_check_button_set_active (self->workspaces_span_displays_radio, TRUE);
+
+ g_settings_bind (self->mutter_settings,
+ "workspaces-only-on-primary",
+ self->workspaces_primary_display_radio,
+ "active",
+ G_SETTINGS_BIND_DEFAULT);
+ g_settings_bind (self->mutter_settings,
+ "edge-tiling",
+ self->active_screen_edges_switch,
+ "active",
+ G_SETTINGS_BIND_DEFAULT);
+
+ if (g_settings_get_boolean (self->mutter_settings, "dynamic-workspaces"))
+ gtk_check_button_set_active (self->dynamic_workspaces_radio, TRUE);
+ else
+ gtk_check_button_set_active (self->fixed_workspaces_radio, TRUE);
+
+ g_settings_bind (self->mutter_settings,
+ "dynamic-workspaces",
+ self->dynamic_workspaces_radio,
+ "active",
+ G_SETTINGS_BIND_DEFAULT);
+
+ self->wm_settings = g_settings_new ("org.gnome.desktop.wm.preferences");
+ g_settings_bind (self->wm_settings,
+ "num-workspaces",
+ self->number_of_workspaces_spin,
+ "value",
+ G_SETTINGS_BIND_DEFAULT);
+
+ self->shell_settings = g_settings_new ("org.gnome.shell.app-switcher");
+
+ if (g_settings_get_boolean (self->shell_settings, "current-workspace-only"))
+ gtk_check_button_set_active (self->current_workspace_radio, TRUE);
+ else
+ gtk_check_button_set_active (self->all_workspaces_radio, TRUE);
+
+ g_settings_bind (self->shell_settings,
+ "current-workspace-only",
+ self->current_workspace_radio,
+ "active",
+ G_SETTINGS_BIND_DEFAULT);
+
+ if (gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL)
+ {
+ gtk_picture_set_resource (self->hot_corner_picture,
+ "/org/gnome/control-center/multitasking/assets/hot-corner-rtl.svg");
+ gtk_picture_set_resource (self->active_screen_edges_picture,
+ "/org/gnome/control-center/multitasking/assets/active-screen-edges-rtl.svg");
+ }
+}
diff --git a/panels/multitasking/cc-multitasking-panel.h b/panels/multitasking/cc-multitasking-panel.h
new file mode 100644
index 0000000..81e78f0
--- /dev/null
+++ b/panels/multitasking/cc-multitasking-panel.h
@@ -0,0 +1,30 @@
+/* cc-multitasking-panel.h
+ *
+ * Copyright 2020 Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#pragma once
+
+#include <shell/cc-panel.h>
+
+G_BEGIN_DECLS
+
+#define CC_TYPE_MULTITASKING_PANEL (cc_multitasking_panel_get_type())
+G_DECLARE_FINAL_TYPE (CcMultitaskingPanel, cc_multitasking_panel, CC, MULTITASKING_PANEL, CcPanel)
+
+G_END_DECLS
diff --git a/panels/multitasking/cc-multitasking-panel.ui b/panels/multitasking/cc-multitasking-panel.ui
new file mode 100644
index 0000000..28a5ce0
--- /dev/null
+++ b/panels/multitasking/cc-multitasking-panel.ui
@@ -0,0 +1,229 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <template class="CcMultitaskingPanel" parent="CcPanel">
+ <child type="content">
+ <object class="AdwPreferencesPage">
+
+ <child>
+ <object class="AdwPreferencesGroup">
+ <property name="title" translatable="yes">General</property>
+
+ <!-- Hot Corner -->
+ <child>
+ <object class="CcMultitaskingRow">
+ <property name="activatable-widget">hot_corner_switch</property>
+ <property name="title" translatable="yes">_Hot Corner</property>
+ <property name="subtitle" translatable="yes">Touch the top-left corner to open the Activities Overview.</property>
+ <property name="use_underline">True</property>
+ <child>
+ <object class="GtkSwitch" id="hot_corner_switch">
+ <property name="valign">center</property>
+ </object>
+ </child>
+ <child type="artwork">
+ <object class="GtkPicture" id="hot_corner_picture">
+ <property name="hexpand">True</property>
+ <property name="halign">center</property>
+ <property name="margin-top">18</property>
+ <property name="margin-bottom">18</property>
+ <property name="margin-start">18</property>
+ <property name="margin-end">18</property>
+ <property name="can-shrink">False</property>
+ <property name="file">resource:///org/gnome/control-center/multitasking/assets/hot-corner.svg</property>
+ </object>
+ </child>
+ </object>
+ </child>
+
+ <!-- Active Screen Edges -->
+ <child>
+ <object class="CcMultitaskingRow">
+ <property name="activatable-widget">active_screen_edges_switch</property>
+ <property name="title" translatable="yes">_Active Screen Edges</property>
+ <property name="subtitle" translatable="yes">Drag windows against the top, left, and right screen edges to resize them.</property>
+ <property name="use_underline">True</property>
+ <child>
+ <object class="GtkSwitch" id="active_screen_edges_switch">
+ <property name="valign">center</property>
+ </object>
+ </child>
+ <child type="artwork">
+ <object class="GtkPicture" id="active_screen_edges_picture">
+ <property name="hexpand">True</property>
+ <property name="halign">center</property>
+ <property name="margin-top">18</property>
+ <property name="margin-bottom">18</property>
+ <property name="margin-start">18</property>
+ <property name="margin-end">18</property>
+ <property name="can-shrink">False</property>
+ <property name="file">resource:///org/gnome/control-center/multitasking/assets/active-screen-edges.svg</property>
+ </object>
+ </child>
+ </object>
+ </child>
+
+ </object>
+ </child>
+
+ <child>
+ <object class="AdwPreferencesGroup">
+ <property name="title" translatable="yes">Workspaces</property>
+
+ <!-- Dynamic Workspaces -->
+ <child>
+ <object class="CcMultitaskingRow">
+ <property name="activatable-widget">dynamic_workspaces_radio</property>
+ <property name="title" translatable="yes">_Dynamic workspaces</property>
+ <property name="subtitle" translatable="yes">Automatically removes empty workspaces.</property>
+ <property name="use_underline">True</property>
+ <child type="prefix">
+ <object class="GtkCheckButton" id="dynamic_workspaces_radio">
+ <property name="valign">center</property>
+ </object>
+ </child>
+ </object>
+ </child>
+
+ <!-- Fixed Number of Workspaces -->
+ <child>
+ <object class="CcMultitaskingRow">
+ <property name="activatable-widget">fixed_workspaces_radio</property>
+ <property name="title" translatable="yes">_Fixed number of workspaces</property>
+ <property name="subtitle" translatable="yes">Specify a number of permanent workspaces.</property>
+ <property name="use_underline">True</property>
+ <child type="prefix">
+ <object class="GtkCheckButton" id="fixed_workspaces_radio">
+ <property name="valign">center</property>
+ <property name="group">dynamic_workspaces_radio</property>
+ </object>
+ </child>
+ </object>
+ </child>
+
+ <!-- Number of Workspaces -->
+ <child>
+ <object class="CcMultitaskingRow">
+ <property name="sensitive" bind-source="fixed_workspaces_radio" bind-property="active" bind-flags="default|sync-create" />
+ <property name="activatable-widget">number_of_workspaces_spin</property>
+ <property name="title" translatable="yes">_Number of Workspaces</property>
+ <property name="use_underline">True</property>
+ <child>
+ <object class="GtkSpinButton" id="number_of_workspaces_spin">
+ <property name="valign">center</property>
+ <property name="adjustment">workspaces_adjustment</property>
+ </object>
+ </child>
+ </object>
+ </child>
+
+ </object>
+ </child>
+
+ <child>
+ <object class="AdwPreferencesGroup">
+ <property name="title" translatable="yes">Multi-Monitor</property>
+
+ <!-- Primary Display -->
+ <child>
+ <object class="CcMultitaskingRow">
+ <property name="activatable-widget">workspaces_primary_display_radio</property>
+ <property name="title" translatable="yes">Workspaces on _primary display only</property>
+ <property name="use_underline">True</property>
+ <child type="prefix">
+ <object class="GtkCheckButton" id="workspaces_primary_display_radio">
+ <property name="valign">center</property>
+ </object>
+ </child>
+ <child type="artwork">
+ <object class="GtkPicture">
+ <property name="hexpand">True</property>
+ <property name="halign">center</property>
+ <property name="margin-top">18</property>
+ <property name="margin-bottom">18</property>
+ <property name="margin-start">18</property>
+ <property name="margin-end">18</property>
+ <property name="can-shrink">False</property>
+ <property name="file">resource:///org/gnome/control-center/multitasking/assets/workspaces-primary-display.svg</property>
+ </object>
+ </child>
+ </object>
+ </child>
+
+ <!-- Span Displays -->
+ <child>
+ <object class="CcMultitaskingRow">
+ <property name="activatable-widget">workspaces_span_displays_radio</property>
+ <property name="title" translatable="yes">Workspaces on all d_isplays</property>
+ <property name="use_underline">True</property>
+ <child type="prefix">
+ <object class="GtkCheckButton" id="workspaces_span_displays_radio">
+ <property name="valign">center</property>
+ <property name="group">workspaces_primary_display_radio</property>
+ </object>
+ </child>
+ <child type="artwork">
+ <object class="GtkPicture">
+ <property name="hexpand">True</property>
+ <property name="halign">center</property>
+ <property name="margin-top">18</property>
+ <property name="margin-bottom">18</property>
+ <property name="margin-start">18</property>
+ <property name="margin-end">18</property>
+ <property name="can-shrink">False</property>
+ <property name="file">resource:///org/gnome/control-center/multitasking/assets/workspaces-span-displays.svg</property>
+ </object>
+ </child>
+ </object>
+ </child>
+
+ </object>
+ </child>
+
+ <child>
+ <object class="AdwPreferencesGroup">
+ <property name="title" translatable="yes">Application Switching</property>
+
+ <!-- All Workspaces -->
+ <child>
+ <object class="CcMultitaskingRow">
+ <property name="activatable-widget">all_workspaces_radio</property>
+ <property name="title" translatable="yes">Include applications from all _workspaces</property>
+ <property name="use_underline">True</property>
+ <child type="prefix">
+ <object class="GtkCheckButton" id="all_workspaces_radio">
+ <property name="valign">center</property>
+ </object>
+ </child>
+ </object>
+ </child>
+
+ <!-- Current Workspace -->
+ <child>
+ <object class="CcMultitaskingRow">
+ <property name="activatable-widget">current_workspace_radio</property>
+ <property name="title" translatable="yes">Include applications from the _current workspace only</property>
+ <property name="use_underline">True</property>
+ <child type="prefix">
+ <object class="GtkCheckButton" id="current_workspace_radio">
+ <property name="valign">center</property>
+ <property name="group">all_workspaces_radio</property>
+ </object>
+ </child>
+ </object>
+ </child>
+
+ </object>
+ </child>
+
+ </object>
+ </child>
+ </template>
+
+ <object class="GtkAdjustment" id="workspaces_adjustment">
+ <property name="lower">1.0</property>
+ <property name="step-increment">1.0</property>
+ <property name="value">4.0</property>
+ <!-- 36 is the maximum value allowed by Mutter -->
+ <property name="upper">36.0</property>
+ </object>
+</interface>
diff --git a/panels/multitasking/cc-multitasking-row.c b/panels/multitasking/cc-multitasking-row.c
new file mode 100644
index 0000000..9524fba
--- /dev/null
+++ b/panels/multitasking/cc-multitasking-row.c
@@ -0,0 +1,572 @@
+/* cc-multitasking-row.c
+ *
+ * Copyright 2018 Purism SPC
+ * 2021 Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include "cc-multitasking-row.h"
+
+struct _CcMultitaskingRow
+{
+ AdwPreferencesRow parent;
+
+ GtkBox *artwork_box;
+ GtkBox *header;
+ GtkImage *image;
+ GtkBox *prefixes;
+ GtkLabel *subtitle;
+ GtkBox *suffixes;
+ GtkLabel *title;
+ GtkBox *title_box;
+
+ GtkWidget *previous_parent;
+
+ gboolean use_underline;
+ gint title_lines;
+ gint subtitle_lines;
+ GtkWidget *activatable_widget;
+};
+
+static GtkBuildableIface *parent_buildable_iface;
+
+static void cc_multitasking_row_buildable_init (GtkBuildableIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (CcMultitaskingRow, cc_multitasking_row, ADW_TYPE_PREFERENCES_ROW,
+ G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE, cc_multitasking_row_buildable_init))
+
+enum
+{
+ PROP_0,
+ PROP_ICON_NAME,
+ PROP_ACTIVATABLE_WIDGET,
+ PROP_SUBTITLE,
+ PROP_USE_UNDERLINE,
+ PROP_TITLE_LINES,
+ PROP_SUBTITLE_LINES,
+ N_PROPS,
+};
+
+enum
+{
+ SIGNAL_ACTIVATED,
+ SIGNAL_LAST_SIGNAL,
+};
+
+static GParamSpec *props[N_PROPS] = { NULL, };
+static guint signals[SIGNAL_LAST_SIGNAL] = { 0, };
+
+static void
+row_activated_cb (CcMultitaskingRow *self,
+ GtkListBoxRow *row)
+{
+ /* No need to use GTK_LIST_BOX_ROW() for a pointer comparison. */
+ if ((GtkListBoxRow *) self == row)
+ cc_multitasking_row_activate (self);
+}
+
+static void
+parent_cb (CcMultitaskingRow *self)
+{
+ GtkWidget *parent = gtk_widget_get_parent (GTK_WIDGET (self));
+
+ if (self->previous_parent != NULL)
+ {
+ g_signal_handlers_disconnect_by_func (self->previous_parent,
+ G_CALLBACK (row_activated_cb),
+ self);
+ self->previous_parent = NULL;
+ }
+
+ if (parent == NULL || !GTK_IS_LIST_BOX (parent))
+ return;
+
+ self->previous_parent = parent;
+ g_signal_connect_swapped (parent, "row-activated", G_CALLBACK (row_activated_cb), self);
+}
+
+static void
+update_subtitle_visibility (CcMultitaskingRow *self)
+{
+ gtk_widget_set_visible (GTK_WIDGET (self->subtitle),
+ gtk_label_get_text (self->subtitle) != NULL &&
+ g_strcmp0 (gtk_label_get_text (self->subtitle), "") != 0);
+}
+
+static void
+cc_multitasking_row_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ CcMultitaskingRow *self = CC_MULTITASKING_ROW (object);
+
+ switch (prop_id)
+ {
+ case PROP_ICON_NAME:
+ g_value_set_string (value, cc_multitasking_row_get_icon_name (self));
+ break;
+ case PROP_ACTIVATABLE_WIDGET:
+ g_value_set_object (value, (GObject *) cc_multitasking_row_get_activatable_widget (self));
+ break;
+ case PROP_SUBTITLE:
+ g_value_set_string (value, cc_multitasking_row_get_subtitle (self));
+ break;
+ case PROP_SUBTITLE_LINES:
+ g_value_set_int (value, cc_multitasking_row_get_subtitle_lines (self));
+ break;
+ case PROP_TITLE_LINES:
+ g_value_set_int (value, cc_multitasking_row_get_title_lines (self));
+ break;
+ case PROP_USE_UNDERLINE:
+ g_value_set_boolean (value, cc_multitasking_row_get_use_underline (self));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+cc_multitasking_row_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ CcMultitaskingRow *self = CC_MULTITASKING_ROW (object);
+
+ switch (prop_id)
+ {
+ case PROP_ICON_NAME:
+ cc_multitasking_row_set_icon_name (self, g_value_get_string (value));
+ break;
+ case PROP_ACTIVATABLE_WIDGET:
+ cc_multitasking_row_set_activatable_widget (self, (GtkWidget*) g_value_get_object (value));
+ break;
+ case PROP_SUBTITLE:
+ cc_multitasking_row_set_subtitle (self, g_value_get_string (value));
+ break;
+ case PROP_SUBTITLE_LINES:
+ cc_multitasking_row_set_subtitle_lines (self, g_value_get_int (value));
+ break;
+ case PROP_TITLE_LINES:
+ cc_multitasking_row_set_title_lines (self, g_value_get_int (value));
+ break;
+ case PROP_USE_UNDERLINE:
+ cc_multitasking_row_set_use_underline (self, g_value_get_boolean (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+cc_multitasking_row_dispose (GObject *object)
+{
+ CcMultitaskingRow *self = CC_MULTITASKING_ROW (object);
+
+ if (self->previous_parent != NULL) {
+ g_signal_handlers_disconnect_by_func (self->previous_parent, G_CALLBACK (row_activated_cb), self);
+ self->previous_parent = NULL;
+ }
+
+ cc_multitasking_row_set_activatable_widget (self, NULL);
+ g_clear_pointer ((GtkWidget**)&self->header, gtk_widget_unparent);
+
+ G_OBJECT_CLASS (cc_multitasking_row_parent_class)->dispose (object);
+}
+
+static void
+cc_multitasking_row_class_init (CcMultitaskingRowClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->get_property = cc_multitasking_row_get_property;
+ object_class->set_property = cc_multitasking_row_set_property;
+ object_class->dispose = cc_multitasking_row_dispose;
+
+ props[PROP_ICON_NAME] =
+ g_param_spec_string ("icon-name",
+ "Icon name",
+ "Icon name",
+ "",
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
+
+ props[PROP_ACTIVATABLE_WIDGET] =
+ g_param_spec_object ("activatable-widget",
+ "Activatable widget",
+ "The widget to be activated when the row is activated",
+ GTK_TYPE_WIDGET,
+ G_PARAM_READWRITE);
+
+ props[PROP_SUBTITLE] =
+ g_param_spec_string ("subtitle",
+ "Subtitle",
+ "Subtitle",
+ "",
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
+
+ props[PROP_USE_UNDERLINE] =
+ g_param_spec_boolean ("use-underline",
+ "Use underline",
+ "If set, an underline in the text indicates the next character should be used for the mnemonic accelerator key",
+ FALSE,
+ G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
+
+ props[PROP_TITLE_LINES] =
+ g_param_spec_int ("title-lines",
+ "Number of title lines",
+ "The desired number of title lines",
+ 0, G_MAXINT,
+ 1,
+ G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
+
+ props[PROP_SUBTITLE_LINES] =
+ g_param_spec_int ("subtitle-lines",
+ "Number of subtitle lines",
+ "The desired number of subtitle lines",
+ 0, G_MAXINT,
+ 1,
+ G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
+
+ g_object_class_install_properties (object_class, N_PROPS, props);
+
+ signals[SIGNAL_ACTIVATED] =
+ g_signal_new ("activated",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL, NULL,
+ G_TYPE_NONE,
+ 0);
+
+ gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/multitasking/cc-multitasking-row.ui");
+
+ gtk_widget_class_bind_template_child (widget_class, CcMultitaskingRow, artwork_box);
+ gtk_widget_class_bind_template_child (widget_class, CcMultitaskingRow, header);
+ gtk_widget_class_bind_template_child (widget_class, CcMultitaskingRow, image);
+ gtk_widget_class_bind_template_child (widget_class, CcMultitaskingRow, prefixes);
+ gtk_widget_class_bind_template_child (widget_class, CcMultitaskingRow, subtitle);
+ gtk_widget_class_bind_template_child (widget_class, CcMultitaskingRow, suffixes);
+ gtk_widget_class_bind_template_child (widget_class, CcMultitaskingRow, title);
+ gtk_widget_class_bind_template_child (widget_class, CcMultitaskingRow, title_box);
+}
+
+static gboolean
+string_is_not_empty (GBinding *binding,
+ const GValue *from_value,
+ GValue *to_value,
+ gpointer user_data)
+{
+ const gchar *string = g_value_get_string (from_value);
+
+ g_value_set_boolean (to_value, string != NULL && g_strcmp0 (string, "") != 0);
+
+ return TRUE;
+}
+
+static void
+cc_multitasking_row_init (CcMultitaskingRow *self)
+{
+ self->title_lines = 1;
+ self->subtitle_lines = 1;
+
+ gtk_widget_init_template (GTK_WIDGET (self));
+
+ g_object_bind_property_full (self, "title",
+ self->title, "visible",
+ G_BINDING_SYNC_CREATE,
+ string_is_not_empty,
+ NULL, NULL, NULL);
+
+ update_subtitle_visibility (self);
+
+ g_signal_connect (self, "notify::parent", G_CALLBACK (parent_cb), NULL);
+}
+
+static void
+cc_multitasking_row_buildable_add_child (GtkBuildable *buildable,
+ GtkBuilder *builder,
+ GObject *child,
+ const gchar *type)
+{
+ CcMultitaskingRow *self = CC_MULTITASKING_ROW (buildable);
+
+ if (!self->header)
+ parent_buildable_iface->add_child (buildable, builder, child, type);
+ else if (type && strcmp (type, "prefix") == 0)
+ cc_multitasking_row_add_prefix (self, GTK_WIDGET (child));
+ else if (type && strcmp (type, "artwork") == 0)
+ cc_multitasking_row_add_artwork (self, GTK_WIDGET (child));
+ else if (!type && GTK_IS_WIDGET (child))
+ {
+ gtk_box_append (self->suffixes, GTK_WIDGET (child));
+ gtk_widget_show (GTK_WIDGET (self->suffixes));
+ }
+ else
+ parent_buildable_iface->add_child (buildable, builder, child, type);
+}
+
+static void
+cc_multitasking_row_buildable_init (GtkBuildableIface *iface)
+{
+ parent_buildable_iface = g_type_interface_peek_parent (iface);
+ iface->add_child = cc_multitasking_row_buildable_add_child;
+}
+
+const gchar *
+cc_multitasking_row_get_subtitle (CcMultitaskingRow *self)
+{
+ g_return_val_if_fail (CC_IS_MULTITASKING_ROW (self), NULL);
+
+ return gtk_label_get_text (self->subtitle);
+}
+
+void
+cc_multitasking_row_set_subtitle (CcMultitaskingRow *self,
+ const gchar *subtitle)
+{
+ g_return_if_fail (CC_IS_MULTITASKING_ROW (self));
+
+ if (g_strcmp0 (gtk_label_get_text (self->subtitle), subtitle) == 0)
+ return;
+
+ gtk_label_set_text (self->subtitle, subtitle);
+ gtk_widget_set_visible (GTK_WIDGET (self->subtitle),
+ subtitle != NULL && g_strcmp0 (subtitle, "") != 0);
+
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_SUBTITLE]);
+}
+
+const gchar *
+cc_multitasking_row_get_icon_name (CcMultitaskingRow *self)
+{
+ g_return_val_if_fail (CC_IS_MULTITASKING_ROW (self), NULL);
+
+ return gtk_image_get_icon_name (self->image);
+}
+
+void
+cc_multitasking_row_set_icon_name (CcMultitaskingRow *self,
+ const gchar *icon_name)
+{
+ const gchar *old_icon_name;
+
+ g_return_if_fail (CC_IS_MULTITASKING_ROW (self));
+
+ old_icon_name = gtk_image_get_icon_name (self->image);
+ if (g_strcmp0 (old_icon_name, icon_name) == 0)
+ return;
+
+ gtk_image_set_from_icon_name (self->image, icon_name);
+ gtk_widget_set_visible (GTK_WIDGET (self->image),
+ icon_name != NULL && g_strcmp0 (icon_name, "") != 0);
+
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_ICON_NAME]);
+}
+
+GtkWidget *
+cc_multitasking_row_get_activatable_widget (CcMultitaskingRow *self)
+{
+ g_return_val_if_fail (CC_IS_MULTITASKING_ROW (self), NULL);
+
+ return self->activatable_widget;
+}
+
+static void
+activatable_widget_weak_notify (gpointer data,
+ GObject *where_the_object_was)
+{
+ CcMultitaskingRow *self = CC_MULTITASKING_ROW (data);
+
+ self->activatable_widget = NULL;
+
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_ACTIVATABLE_WIDGET]);
+}
+
+void
+cc_multitasking_row_set_activatable_widget (CcMultitaskingRow *self,
+ GtkWidget *widget)
+{
+ g_return_if_fail (CC_IS_MULTITASKING_ROW (self));
+ g_return_if_fail (widget == NULL || GTK_IS_WIDGET (widget));
+
+ if (self->activatable_widget == widget)
+ return;
+
+ if (self->activatable_widget)
+ g_object_weak_unref (G_OBJECT (self->activatable_widget),
+ activatable_widget_weak_notify,
+ self);
+
+ self->activatable_widget = widget;
+
+ if (self->activatable_widget != NULL) {
+ g_object_weak_ref (G_OBJECT (self->activatable_widget),
+ activatable_widget_weak_notify,
+ self);
+ gtk_list_box_row_set_activatable (GTK_LIST_BOX_ROW (self), TRUE);
+ gtk_accessible_update_relation (GTK_ACCESSIBLE (self->activatable_widget),
+ GTK_ACCESSIBLE_RELATION_LABELLED_BY, self->title, NULL,
+ GTK_ACCESSIBLE_RELATION_DESCRIBED_BY, self->subtitle, NULL,
+ -1);
+
+ }
+
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_ACTIVATABLE_WIDGET]);
+}
+
+gboolean
+cc_multitasking_row_get_use_underline (CcMultitaskingRow *self)
+{
+ g_return_val_if_fail (CC_IS_MULTITASKING_ROW (self), FALSE);
+
+ return self->use_underline;
+}
+
+void
+cc_multitasking_row_set_use_underline (CcMultitaskingRow *self,
+ gboolean use_underline)
+{
+ g_return_if_fail (CC_IS_MULTITASKING_ROW (self));
+
+ use_underline = !!use_underline;
+
+ if (self->use_underline == use_underline)
+ return;
+
+ self->use_underline = use_underline;
+ adw_preferences_row_set_use_underline (ADW_PREFERENCES_ROW (self), self->use_underline);
+ gtk_label_set_use_underline (self->title, self->use_underline);
+ gtk_label_set_use_underline (self->subtitle, self->use_underline);
+ gtk_label_set_mnemonic_widget (self->title, GTK_WIDGET (self));
+ gtk_label_set_mnemonic_widget (self->subtitle, GTK_WIDGET (self));
+
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_USE_UNDERLINE]);
+}
+
+gint
+cc_multitasking_row_get_title_lines (CcMultitaskingRow *self)
+{
+ g_return_val_if_fail (CC_IS_MULTITASKING_ROW (self), 0);
+
+ return self->title_lines;
+}
+
+void
+cc_multitasking_row_set_title_lines (CcMultitaskingRow *self,
+ gint title_lines)
+{
+ g_return_if_fail (CC_IS_MULTITASKING_ROW (self));
+ g_return_if_fail (title_lines >= 0);
+
+ if (self->title_lines == title_lines)
+ return;
+
+ self->title_lines = title_lines;
+
+ gtk_label_set_lines (self->title, title_lines);
+ gtk_label_set_ellipsize (self->title, title_lines == 0 ? PANGO_ELLIPSIZE_NONE : PANGO_ELLIPSIZE_END);
+
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_TITLE_LINES]);
+}
+
+gint
+cc_multitasking_row_get_subtitle_lines (CcMultitaskingRow *self)
+{
+ g_return_val_if_fail (CC_IS_MULTITASKING_ROW (self), 0);
+
+ return self->subtitle_lines;
+}
+
+void
+cc_multitasking_row_set_subtitle_lines (CcMultitaskingRow *self,
+ gint subtitle_lines)
+{
+ g_return_if_fail (CC_IS_MULTITASKING_ROW (self));
+ g_return_if_fail (subtitle_lines >= 0);
+
+ if (self->subtitle_lines == subtitle_lines)
+ return;
+
+ self->subtitle_lines = subtitle_lines;
+
+ gtk_label_set_lines (self->subtitle, subtitle_lines);
+ gtk_label_set_ellipsize (self->subtitle, subtitle_lines == 0 ? PANGO_ELLIPSIZE_NONE : PANGO_ELLIPSIZE_END);
+
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_SUBTITLE_LINES]);
+}
+
+void
+cc_multitasking_row_add_prefix (CcMultitaskingRow *self,
+ GtkWidget *widget)
+{
+ g_return_if_fail (CC_IS_MULTITASKING_ROW (self));
+ g_return_if_fail (GTK_IS_WIDGET (self));
+
+ gtk_box_append (self->prefixes, widget);
+ gtk_widget_show (GTK_WIDGET (self->prefixes));
+}
+
+void
+cc_multitasking_row_add_artwork (CcMultitaskingRow *self,
+ GtkWidget *widget)
+{
+ g_return_if_fail (CC_IS_MULTITASKING_ROW (self));
+ g_return_if_fail (GTK_IS_WIDGET (self));
+
+ /* HACK: the artwork box pushes the title too much to the top, so we
+ * need to compensate this here.
+ */
+ gtk_widget_set_margin_top (GTK_WIDGET (self->header), 12);
+
+ gtk_box_append (self->artwork_box, widget);
+ gtk_widget_show (GTK_WIDGET (self->artwork_box));
+}
+
+void
+cc_multitasking_row_activate (CcMultitaskingRow *self)
+{
+ g_return_if_fail (CC_IS_MULTITASKING_ROW (self));
+
+ if (self->activatable_widget)
+ gtk_widget_mnemonic_activate (self->activatable_widget, FALSE);
+
+ g_signal_emit (self, signals[SIGNAL_ACTIVATED], 0);
+}
+
+void
+cc_multitasking_row_remove (CcMultitaskingRow *self,
+ GtkWidget *child)
+{
+ GtkWidget *parent;
+
+ g_return_if_fail (CC_IS_MULTITASKING_ROW (self));
+ g_return_if_fail (GTK_IS_WIDGET (child));
+
+ parent = gtk_widget_get_parent (child);
+
+ if (parent == GTK_WIDGET (self->prefixes))
+ gtk_box_remove (self->prefixes, child);
+ else if (parent == GTK_WIDGET (self->suffixes))
+ gtk_box_remove (self->suffixes, child);
+ else if (parent == GTK_WIDGET (self->artwork_box))
+ gtk_box_remove (self->artwork_box, child);
+ else
+ g_warning ("%p is not a child of %p", child, self);
+}
+
diff --git a/panels/multitasking/cc-multitasking-row.h b/panels/multitasking/cc-multitasking-row.h
new file mode 100644
index 0000000..c70dd08
--- /dev/null
+++ b/panels/multitasking/cc-multitasking-row.h
@@ -0,0 +1,66 @@
+/* cc-multitasking-row.h
+ *
+ * Copyright 2018 Purism SPC
+ * 2021 Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <adwaita.h>
+
+G_BEGIN_DECLS
+
+#define CC_TYPE_MULTITASKING_ROW (cc_multitasking_row_get_type())
+G_DECLARE_FINAL_TYPE (CcMultitaskingRow, cc_multitasking_row, CC, MULTITASKING_ROW, AdwPreferencesRow)
+
+const gchar *cc_multitasking_row_get_subtitle (CcMultitaskingRow *self);
+void cc_multitasking_row_set_subtitle (CcMultitaskingRow *self,
+ const gchar *subtitle);
+
+const gchar *cc_multitasking_row_get_icon_name (CcMultitaskingRow *self);
+void cc_multitasking_row_set_icon_name (CcMultitaskingRow *self,
+ const gchar *icon_name);
+
+GtkWidget *cc_multitasking_row_get_activatable_widget (CcMultitaskingRow *self);
+void cc_multitasking_row_set_activatable_widget (CcMultitaskingRow *self,
+ GtkWidget *widget);
+
+gboolean cc_multitasking_row_get_use_underline (CcMultitaskingRow *self);
+void cc_multitasking_row_set_use_underline (CcMultitaskingRow *self,
+ gboolean use_underline);
+
+gint cc_multitasking_row_get_title_lines (CcMultitaskingRow *self);
+void cc_multitasking_row_set_title_lines (CcMultitaskingRow *self,
+ gint title_lines);
+
+gint cc_multitasking_row_get_subtitle_lines (CcMultitaskingRow *self);
+void cc_multitasking_row_set_subtitle_lines (CcMultitaskingRow *self,
+ gint subtitle_lines);
+
+void cc_multitasking_row_add_prefix (CcMultitaskingRow *self,
+ GtkWidget *widget);
+
+void cc_multitasking_row_add_artwork (CcMultitaskingRow *self,
+ GtkWidget *widget);
+
+void cc_multitasking_row_activate (CcMultitaskingRow *self);
+
+void cc_multitasking_row_remove (CcMultitaskingRow *self,
+ GtkWidget *child);
+
+G_END_DECLS
diff --git a/panels/multitasking/cc-multitasking-row.ui b/panels/multitasking/cc-multitasking-row.ui
new file mode 100644
index 0000000..2e41951
--- /dev/null
+++ b/panels/multitasking/cc-multitasking-row.ui
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <template class="CcMultitaskingRow" parent="AdwPreferencesRow">
+ <property name="activatable">False</property>
+ <accessibility>
+ <relation name="labelled-by">title</relation>
+ </accessibility>
+ <child>
+ <object class="GtkBox" id="header">
+ <property name="orientation">vertical</property>
+ <property name="valign">center</property>
+ <style>
+ <class name="header"/>
+ </style>
+
+ <child>
+ <object class="GtkBox">
+ <property name="spacing">12</property>
+ <property name="valign">center</property>
+ <property name="vexpand">True</property>
+
+ <child>
+ <object class="GtkBox" id="prefixes">
+ <property name="spacing">12</property>
+ <property name="visible">False</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkImage" id="image">
+ <property name="pixel_size">32</property>
+ <property name="valign">center</property>
+ <property name="visible">False</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkBox" id="title_box">
+ <property name="halign">start</property>
+ <property name="orientation">vertical</property>
+ <property name="valign">center</property>
+ <style>
+ <class name="title"/>
+ </style>
+ <child>
+ <object class="GtkLabel" id="title">
+ <property name="ellipsize">end</property>
+ <property name="halign">start</property>
+ <property name="hexpand">True</property>
+ <property name="label" bind-source="CcMultitaskingRow" bind-property="title" bind-flags="sync-create"/>
+ <property name="lines">1</property>
+ <property name="wrap">True</property>
+ <property name="wrap-mode">word-char</property>
+ <property name="xalign">0</property>
+ <style>
+ <class name="title"/>
+ </style>
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel" id="subtitle">
+ <property name="ellipsize">end</property>
+ <property name="halign">start</property>
+ <property name="hexpand">True</property>
+ <property name="lines">2</property>
+ <property name="wrap">True</property>
+ <property name="wrap-mode">word-char</property>
+ <property name="xalign">0</property>
+ <style>
+ <class name="subtitle"/>
+ </style>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkBox" id="suffixes">
+ <property name="spacing">12</property>
+ <property name="visible">False</property>
+ </object>
+ </child>
+
+ </object>
+ </child>
+
+ <child>
+ <object class="GtkBox" id="artwork_box">
+ <property name="visible">False</property>
+ <property name="hexpand">True</property>
+ <property name="margin-top">12</property>
+ <property name="margin-bottom">12</property>
+ <style>
+ <class name="frame" />
+ <class name="background" />
+ </style>
+ </object>
+ </child>
+
+ </object>
+ </child>
+ </template>
+</interface>
diff --git a/panels/multitasking/gnome-multitasking-panel.desktop.in.in b/panels/multitasking/gnome-multitasking-panel.desktop.in.in
new file mode 100644
index 0000000..c8f0fe8
--- /dev/null
+++ b/panels/multitasking/gnome-multitasking-panel.desktop.in.in
@@ -0,0 +1,14 @@
+[Desktop Entry]
+Name=Multitasking
+Comment=Manage preferences for productivity and multitasking
+Exec=gnome-control-center multitasking
+# Translators: Do NOT translate or transliterate this text (this is an icon file name)!
+Icon=org.gnome.Settings-multitasking-symbolic
+Terminal=false
+Type=Application
+NoDisplay=true
+StartupNotify=true
+Categories=GNOME;GTK;Settings;DesktopSettings;X-GNOME-Settings-Panel;X-GNOME-PersonalizationSettings;
+OnlyShowIn=GNOME;
+# Translators: Search terms to find the Search panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon!
+Keywords=Multitasking;Multitask;Productivity;Customize;Desktop;Hot Corner;Workspaces;
diff --git a/panels/multitasking/icons/meson.build b/panels/multitasking/icons/meson.build
new file mode 100644
index 0000000..b274dd1
--- /dev/null
+++ b/panels/multitasking/icons/meson.build
@@ -0,0 +1,4 @@
+install_data(
+ 'scalable/org.gnome.Settings-multitasking-symbolic.svg',
+ install_dir: join_paths(control_center_icondir, 'hicolor', 'scalable', 'apps')
+)
diff --git a/panels/multitasking/icons/scalable/org.gnome.Settings-multitasking-symbolic.svg b/panels/multitasking/icons/scalable/org.gnome.Settings-multitasking-symbolic.svg
new file mode 100644
index 0000000..50b8a84
--- /dev/null
+++ b/panels/multitasking/icons/scalable/org.gnome.Settings-multitasking-symbolic.svg
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
+ <path d="m 6 0 c -1.644531 0 -3 1.355469 -3 3 v 10 c 0 1.644531 1.355469 3 3 3 h 4 c 1.644531 0 3 -1.355469 3 -3 v -10 c 0 -1.644531 -1.355469 -3 -3 -3 z m 0 2 h 4 c 0.570312 0 1 0.429688 1 1 v 10 c 0 0.570312 -0.429688 1 -1 1 h -4 c -0.570312 0 -1 -0.429688 -1 -1 v -10 c 0 -0.570312 0.429688 -1 1 -1 z m -5 1 c -0.554688 0 -1 0.445312 -1 1 v 8 c 0 0.554688 0.445312 1 1 1 s 1 -0.445312 1 -1 v -8 c 0 -0.554688 -0.445312 -1 -1 -1 z m 14 0 c -0.554688 0 -1 0.445312 -1 1 v 8 c 0 0.554688 0.445312 1 1 1 s 1 -0.445312 1 -1 v -8 c 0 -0.554688 -0.445312 -1 -1 -1 z m 0 0" fill="#2e3436"/>
+</svg>
diff --git a/panels/multitasking/meson.build b/panels/multitasking/meson.build
new file mode 100644
index 0000000..53fd0d8
--- /dev/null
+++ b/panels/multitasking/meson.build
@@ -0,0 +1,48 @@
+panels_list += cappletname
+desktop = 'gnome-@0@-panel.desktop'.format(cappletname)
+
+desktop_in = configure_file(
+ input: desktop + '.in.in',
+ output: desktop + '.in',
+ configuration: desktop_conf
+)
+
+i18n.merge_file(
+ type: 'desktop',
+ input: desktop_in,
+ output: desktop,
+ po_dir: po_dir,
+ install: true,
+ install_dir: control_center_desktopdir
+)
+
+sources = files(
+ 'cc-multitasking-panel.c',
+ 'cc-multitasking-row.c',
+)
+
+resource_data = files(
+ 'cc-multitasking-panel.ui',
+)
+
+sources += gnome.compile_resources(
+ 'cc-' + cappletname + '-resources',
+ cappletname + '.gresource.xml',
+ c_name: 'cc_' + cappletname,
+ dependencies: resource_data,
+ export: true
+)
+
+cflags += [
+ '-DDATADIR="@0@"'.format(control_center_datadir)
+]
+
+panels_libs += static_library(
+ cappletname,
+ sources: sources,
+ include_directories: [ top_inc, common_inc ],
+ dependencies: common_deps,
+ c_args: cflags
+)
+
+subdir('icons')
diff --git a/panels/multitasking/multitasking.gresource.xml b/panels/multitasking/multitasking.gresource.xml
new file mode 100644
index 0000000..df47764
--- /dev/null
+++ b/panels/multitasking/multitasking.gresource.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<gresources>
+ <gresource prefix="/org/gnome/control-center/multitasking">
+ <file preprocess="xml-stripblanks">cc-multitasking-panel.ui</file>
+ <file preprocess="xml-stripblanks">cc-multitasking-row.ui</file>
+
+ <!-- Assets -->
+ <file>assets/active-screen-edges.svg</file>
+ <file>assets/active-screen-edges-rtl.svg</file>
+ <file>assets/hot-corner.svg</file>
+ <file>assets/hot-corner-rtl.svg</file>
+ <file>assets/workspaces-primary-display.svg</file>
+ <file>assets/workspaces-span-displays.svg</file>
+ </gresource>
+</gresources>