SVG-Icons statt ICNS, Popup-Höhe an Monitor begrenzt, GNOME-Shell-Extension für Popup-Positionierung, Bundle-Targets explizit

This commit is contained in:
marcus hinz
2026-07-11 21:45:20 +02:00
parent 165501c8f9
commit ce4e48e311
6 changed files with 218 additions and 34 deletions
+15 -3
View File
@@ -2,6 +2,7 @@
import { onMounted, onUnmounted, ref } from "vue";
import { invoke } from "@tauri-apps/api/core";
import { getCurrentWebviewWindow } from "@tauri-apps/api/webviewWindow";
import { currentMonitor } from "@tauri-apps/api/window";
import { LogicalSize } from "@tauri-apps/api/dpi";
interface Project {
@@ -11,10 +12,13 @@ interface Project {
}
const WIDTH = 300;
// Sicherheitsabstand für Panel + Rand; die Extension klemmt zusätzlich exakt.
const MARGIN = 64;
const projects = ref<Project[]>([]);
const icons = ref<Record<string, string>>({});
const wrapRef = ref<HTMLElement>();
const maxH = ref(10000);
const win = getCurrentWebviewWindow();
async function refresh() {
@@ -46,12 +50,14 @@ async function quit() {
// Fenster nur so hoch wie der Inhalt: bei jeder Layout-Änderung nachziehen.
let ro: ResizeObserver | undefined;
let timer: number;
onMounted(() => {
onMounted(async () => {
const mon = await currentMonitor();
if (mon) maxH.value = Math.floor(mon.size.height / mon.scaleFactor) - MARGIN;
refresh();
timer = window.setInterval(refresh, 2000);
if (wrapRef.value) {
ro = new ResizeObserver(() => {
const h = Math.ceil(wrapRef.value!.getBoundingClientRect().height);
const h = Math.min(Math.ceil(wrapRef.value!.getBoundingClientRect().height), maxH.value);
if (h > 0) win.setSize(new LogicalSize(WIDTH, h));
});
ro.observe(wrapRef.value);
@@ -64,7 +70,7 @@ onUnmounted(() => {
</script>
<template>
<div ref="wrapRef" class="wrap">
<div ref="wrapRef" class="wrap" :style="{ maxHeight: maxH + 'px' }">
<ul class="list">
<li v-for="p in projects" :key="p.name" class="row" @click="pick(p)">
<span class="dot" :class="{ on: p.running }"></span>
@@ -86,6 +92,8 @@ onUnmounted(() => {
.wrap {
width: 300px;
box-sizing: border-box;
display: flex;
flex-direction: column;
background: #1e1e2e;
color: #cdd6f4;
border: 1px solid #313244;
@@ -101,6 +109,9 @@ onUnmounted(() => {
list-style: none;
margin: 0;
padding: 5px;
overflow-y: auto;
flex: 1 1 auto;
min-height: 0;
}
.row {
@@ -154,6 +165,7 @@ onUnmounted(() => {
.ft {
display: flex;
flex: none;
gap: 6px;
padding: 5px 6px 6px;
border-top: 1px solid #313244;
+1 -1
View File
@@ -226,7 +226,7 @@ async function pickIcon() {
const file = await open({
multiple: false,
directory: false,
filters: [{ name: "Icon", extensions: ["png", "icns"] }],
filters: [{ name: "Icon", extensions: ["png", "svg"] }],
});
if (typeof file === "string") settings.value!.icon = file;
}