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:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user