Миграция с Gnome на Sway, неспешно

Стековые, фреймовые, динамические
Ответить
lnx
Сообщения: 155
Зарегистрирован: 24.08.2022

#

Вцелом тянет на полновесную инструкцию по миграции, актуальную на лето 2025г.

Изобилие в интернете адптированных для SEO статей проблему усложняет. Я к задаче миграции подступался мысленного много лет с обострениями после каждого обновления Gnome или его падения. Вопрос не сводится к хаутошке - "установить из реп sway + waybar", проблема шире.

Очевидно, каждый имеет уже обжитой годами и даже десятилетиями десктоп-лэптоп и такого рода переезды доллго назревают и получаются болезненными. Меняется не только DE, но и наборы привычек. От общих слов - к делу.

Собирая самостоятельно из компонент целое собственное десктоп-окружение приходится заботиться и о необходимых компонентах. Применительно к sway речь идет о сервисе локскрина, чего-то для скрин-шотов и пр. важных вещей. Структура этого хозяйства имеет вполне стройную логику - есть Sway, он запускается и все обслуживает. Его конфиг лежит в ~/.config/sway/config. Это простой текстовой файл с гуманной структурой, содержащий в себе главное - указание на то, какой верхний бар запускаем, какой именно вариант программы терминала используем, набор автозапускаемых программ и горячие клавиши. Способ задания элементарен и разрешает собой все проблемы гномовской дури с растыканными по многим местам настройка клавиш. Для обеспечения читаемости комментарии по тексту конфига следует записывать обильно. Пример конфига ниже.
Полезная литература по sway -

https://wiki.archlinux.org/title/Sway


У sway есть ключевое место - верхний бар. Штатный бар чаще всего заменяют на waybar, конфиг которого лежит в ~/.config/waybar/config и украшательства, с учетом Вашего вкуса к фломастерам, там же в файле style.css. Конфиг бара логически строен, в нем мы делаем почти что хотим - кнопочки, индикаторы и пр. Пример конфига ниже.
Полезная литература по sway+waybar -

https://www.lorenzobettini.it/2024/12/sway-and-waybar/
https://github.com/Alexays/Waybar/wiki

Строго говоря набор sway + waybar не требует даже "дисплейного менеджера" и после переезда можно радикально облегчить систему, избавив ее от gnome-хлама и вытекающих из него источников падений, жора и других проблем. Пакетов к установке требуется не много:
pacman -S sway wob swayidle  swaylock  waybar  autotiling pavucontrol brightnessctl wmenu mako grim swaybg  sway-contrib nwg-menu swayimg swaync foot 
Установленный набор не содержит разве что гномо-подобного меню запуска прграмм, но его организовать не сложно, https://github.com/nwg-piotr/nwg-launchers. Исходим из того, что по опубликованной на гите инструкции поставить может любой в пару команд -
 git clone https://github.com/nwg-piotr/nwg-launchers.git
cd nwg-launchers
meson builddir -Dbuildtype=release
ninja -C builddir

sudo ninja -C builddir install
С этими установленными пакетами в своем хомовнике следует создать директории и файлы
.conf/sway/conf
# Фон рабочего стола
#set $background $HOME/.config/sway/generated_background.svg

#автозапуск программ
exec {
    nm-applet #аплет управления сетью
    /usr/bin/tilix --maximize -s ~/.config/tilix.json
    #nwg-dock -x -f -a start -i 32 -p left  #док с отображением запущенных программ, мне надо, но кому-то...
    /usr/bin/libinput-gestures -c ~/.config/libinput-gestures.conf
    }

# Назначение менеджера задач, у меня htop
    set $task_manager  $term htop


# Верхняя панель, используется waybar вместо основного бара
bar {  
    swaybar_command waybar   
     }

#клавиатура - смена раскладки и лампочки
input * {
    xkb_layout "us,ru"
    xkb_options "grp:caps_toggle",grp_led:caps" 
    }



# Основная, главная клавиша, можно несколько, кнопки стрелок-направлений. Задать можно любые, включая буквенные. Сейчас - стрелки
set {
    $mod Super 
    $left Left
    $down Down
    $up Up
    $right Right
    }




# Здесь про подключаемые экраны
#
#output HDMI-A-1 resolution 1920x1080 position 1920,0
#
# Показать имено устройств вывода: swaymsg -t get_outputs



###режим ожидания, его настройка  -
exec swayidle -w    timeout 600 'swaylock -f -c 000000' before-sleep 'swaylock -f -c 000000'
    #\
    #          timeout 600 'swaymsg "output * dpms off"' resume 'swaymsg "output * dpms on"' \
    before-sleep 'swaylock -f -c 000000'
    #
    # This will lock your screen after 300 seconds of inactivity, then turn off
    # your displays after another 300 seconds, and turn your screens back on when
    # resumed. It will also lock your screen before your computer goes to sleep.

# настройки тачпада
input  type:touchpad {
           dwt enabled
           tap enabled
           middle_emulation enabled
       }

# Закрытие окна, релоад конфига,  выход из Sway  - Ctrl+ кнопка
bindsym --to-code $mod+q kill
    
# Запуск программ через разные варианты меню запуска
bindsym --to-code {
    $mod+Ctrl+s exec  wmenu-run #вариант выбора в верхней строке
    $mod+Ctrl+w exec nwg-menu #вариант виндо-подобного меню Старт
    $mod+d exec nwggrid #вариант гномо-подобного меню запуска
    # Выход из сессии
    $mod+Ctrl+e exec swaynag -t warning -m 'Выход?' -B 'Да, выходим!' 'swaymsg exit'
    }


    # Reload the configuration file
    bindsym --to-code $mod+Ctrl+r reload
    
   # Назначение основного эмулятора терминала 
    set $term /usr/bin/tilix
    
for_window [app_id="galculator"] floating enable assign [class="firefox"] -> 3 assign [class="^Urxvt$" instance="^htop$"] -> 9
     
# Window borders
for_window [class="^.*"] border none #все запускаемые программы без заголовка.
smart_borders on
gaps inner 0
gaps outer 0



#Запуск явно указанных программ Shift+кнопка, двойники как Shift+Ctrl+та же кнопка
bindsym  --to-code {
    $mod+Return  exec  $term #запуск терминала
    $mod+Shift+t exec thunar
    $mod+Shift+f exec /usr/bin/freecad 
    $mod+Shift+Ctrl+f exec /opt/FC_main/AppRun
    $mod+Shift+g exec gimp 
    $mod+Shift+p exec palemoon
    $mod+Shift+m exec evolution
    $mod+Shift+k exec galculator
  
    } 


#мультимедиа клавиши
bindsym --locked {
    XF86AudioRaiseVolume exec pactl set-sink-volume @DEFAULT_SINK@ +5%
    XF86AudioLowerVolume exec pactl set-sink-volume @DEFAULT_SINK@ -5%
    XF86AudioMute exec pactl set-sink-mute @DEFAULT_SINK@ toggle
    XF86AudioMicMute exec pactl set-source-mute @DEFAULT_SOURCE@ toggle
    XF86MonBrightnessDown exec brightnessctl set 5%-
    XF86MonBrightnessUp exec brightnessctl set 5%+
    XF86AudioPlay exec playerctl play-pause
    XF86AudioNext exec playerctl next
    XF86AudioPrev exec playerctl previous
    XF86Search exec bemenu-run
    }
    
#переключение вида заголовка окна и их раскладки на экране
bindsym --to-code {
        $mod+t border toggle # переключение вида заголовка окна
        $mod+s layout stacking # полный экран, вертикальным штабелем
        $mod+w layout tabbed # полный экран, окна программ - как вкладки
        $mod+e layout toggle split #вертикально-табличная раскладка окон
        }
        
        
# Передача фокуса активного окна вместо альт+шифт  - используем  $mod+[up|down|left|right]
bindsym {
    $mod+$left focus left
    $mod+$down focus down
    $mod+$up focus up
    $mod+$right focus right
    }

# Перемещения окна по рабочему столу - при нажатом шифте
bindsym {
    $mod+Shift+$left move left
    $mod+Shift+$down move down
    $mod+Shift+$up move up
    $mod+Shift+$right move right
    }

# Рабочие столы:
# переключение между рабочими столами
bindsym {
    $mod+1 workspace number 1
    $mod+2 workspace number 2
    $mod+3 workspace number 3
    $mod+4 workspace number 4
    $mod+5 workspace number 5
    $mod+6 workspace number 6
    $mod+7 workspace number 7
    $mod+8 workspace number 8
    $mod+9 workspace number 9
    $mod+0 workspace number 10
    }
        
# перенос активного окна на конкретный рабочий стол
bindsym {
    $mod+Shift+1 move container to workspace number 1
    $mod+Shift+2 move container to workspace number 2
    $mod+Shift+3 move container to workspace number 3
    $mod+Shift+4 move container to workspace number 4
    $mod+Shift+5 move container to workspace number 5
    $mod+Shift+6 move container to workspace number 6
    $mod+Shift+7 move container to workspace number 7
    $mod+Shift+8 move container to workspace number 8
    $mod+Shift+9 move container to workspace number 9
    $mod+Shift+0 move container to workspace number 10
    }


# Разделение окон горизонтально и вертикально
bindsym --to-code {
    $mod+b splith
    $mod+v splitv
    }
    

    
# Развернуть на весь экран
bindsym --to-code $mod+f fullscreen
    
# Перевести окно в плавающий режим
bindsym $mod+Shift+space floating toggle

# Swap focus between the tiling area and the floating area
bindsym $mod+space focus mode_toggle

# Move focus to the parent container
bindsym --to-code $mod+a focus parent


# Resizing containers:
#
bindsym $mod+r mode "resize"
mode "resize" {
    # left will shrink the containers width
    # right will grow the containers width
    # up will shrink the containers height
    # down will grow the containers height
    bindsym $left resize shrink width 10px
    bindsym $down resize grow height 10px
    bindsym $up resize shrink height 10px
    bindsym $right resize grow width 10px


    # Return to default mode
    bindsym Return mode "default"
    bindsym Escape mode "default"
}


set $script_path ~/.config/sway/scripts
include /etc/sway/config.d/*

./conf/sway/scripts/power.sh
#!/bin/bash
 
entries="Logout Suspend Reboot Shutdown"
selected=$(printf '%s\n' $entries | rofi -dmenu | awk '{print tolower($1)}')
case $selected in
  logout)
    swaymsg exit;;
  suspend)
    exec systemctl suspend;;
  reboot)
    exec systemctl reboot;;
  shutdown)
    exec systemctl poweroff -i;;
esac

./conf/waybar/conf
{
  "layer": "bottom",
  "position": "top",//может быть top, left и т.д.
  "height": 20, //общая высота бара. Не может быть меньше высоты кнопок
  "spacing": 3,
  
  
"modules-left": [
    "sway/workspaces",
    "sway/mode",
    "sway/scratchpad", 
    "wlr/taskbar"
    ],
    
"modules-center": [
    "sway/window"
    
    ],
    

//посмотреть все возможные в системе температуры -
//for i in /sys/class/thermal/thermal_zone*; do echo "$i: $(<$i/type)"; done

"modules-right": [
  "mpd",
  "clock",
  "idle_inhibitor", //запрет автолока экрана
  //"custom/clipboard",
 "sway/language",
  "cpu",
  "memory", 
  //"temperature", // температуры 
  "battery",
  "tray",
  "pulseaudio",
  "custom/power"
  ],
  
// Themperature
"temperature": {
    "critical-threshold": 80,
    "interval": 5,
    "thermal-zone": 1,
    "format": "{icon} {temperatureC}°C",
    "format-icons": [
        "", // Icon: temperature-empty
        "", // Icon: temperature-quarter
        "", // Icon: temperature-half
        "", // Icon: temperature-three-quarters
        ""  // Icon: temperature-full
    ],
    "tooltip": true
},

"sway/mode": {
    "format": "{}"
  },
  
"sway/languae": {
  "format": "{}",
     "on-click": "swaymsg input type:keyboard xkb_switch_layout next",
  },
  
  
// Clipboard
"custom/clipboard": {
    "format": " ",
    "interval": "once",
    "return-type": "json",
    "on-click": "swaymsg -q exec '$clipboard'; pkill -RTMIN+9 waybar",
    "on-click-right": "swaymsg -q exec '$clipboard-del'; pkill -RTMIN+9 waybar",
    "on-click-middle": "swaymsg -q exec '$clipboard-del-all'",
    "exec": "printf '{\"tooltip\":\"%s\"}' $(cliphist list | wc -l)",
    "exec-if": "[ -x \"$(command -v cliphist)\" ] && [ $(cliphist list | wc -l) -gt 0 ]",
    "signal": 9
},
  
"sway/window": {
    "format": "{title}"
  },
  
"idle_inhibitor": {
    "format": "{icon}",
    "format-icons": {
      "activated": "\uf06e",
      "deactivated": "\uf070"
      
    }
  },
  
"wlr/taskbar": {
        "format": "{icon}",
        "icon-size": 16,
        //"icon-theme": "Numix-Circle",
        "tooltip-format": "{title}",
        "on-click": "activate",
        "on-click-middle": "close"
    },
    

// Keyboard
"keyboard-state": {
    "capslock": true,
    "format": " {name} {icon}",
    "format-icons": {
        "locked": " ",
        "unlocked": " "
    }
},
    
"cpu": { 
    "interval": 1, 
    "format": "{usage}%" 
  },
  
"memory": {
    "interval": 1,
    "format": "{used:0.1f}G"
  },
  
"battery": {
    "bat": "BAT0",
    "states": {
      "good": 95,
      "warning": 30,
      "critical": 5
    },
   // "format": " {capacity}%",
   //"format": "{icon}",
     
    "format-charging": " {capacity}%",
    "format-plugged": " {capacity}%",
  },
  
"clock": {
    "format": "{:%Y/%m/%d %H:%M}",
    "tooltip-format": "<tt><small>{calendar}</small></tt>",
    "calendar": {
      "format": {
        "months": "<span color='#ffead3'><b>{}</b></span>",
        "today": "<span color='#ff6699'><b>{}</b></span>"
      }
    }
  },
  
"pulseaudio": {
   "format": "{icon} {volume}%",
    "format-icons": {
      "default": ["\uf026", "\uf027", "\uf028"]
    },
    "on-click": "pactl set-sink-mute @DEFAULT_SINK@ toggle",
    "on-click-right": "pavucontrol",
    "format-muted": "\uf00d {volume}%"
  },
  
"custom/power": {
        "format":" ⏻ ",
        "on-click": "exec ~/.config/sway/scripts/power.sh",
        "tooltip": false,
    },
    
"tray": {
    "icon-size": 16,
    "spacing": 6
  },
}

и, наконец, файл стилей - цвета-размеры-форматы того, что будет отображаться в баре. аждый под свое отношение к фломастерам вправе раскрасить ~.conf/waybar/style.css
* {
    /* `otf-font-awesome` is required to be installed for icons */
    font-family: FontAwesome, Roboto, Helvetica, Arial, sans-serif;
    font-size: 16px;
}



window#waybar {
    background-color: #000000;
    border-bottom: 2px solid #ffffff;
    color: #ffffff;
    transition-property: background-color;
    transition-duration: .5s;
}

window#waybar.hidden {
    opacity: 0.2;
}

/*
window#waybar.empty {
    background-color: transparent;
}
window#waybar.solo {
    background-color: #FFFFFF;
}
*/

window#waybar.termite {
    background-color: #3F3F3F;
}

window#waybar.chromium {
    background-color: #000000;
    border: none;
}
button {
    box-shadow: inset 0 -3px transparent;
    /* Avoid rounded borders under each button name */
    border-bottom: 2px solid #ffffff;
    border-radius: 0;
}

/* https://github.com/Alexays/Waybar/wiki/FAQ#the-workspace-buttons-have-a-strange-hover-effect */
button:hover {
    background: inherit;
    box-shadow: inset 0 -3px #ffffff;
    border-bottom: 2px solid #ffffff;
}


#workspaces button {
    padding: 0 5px;
    background-color: transparent;
    color: #ffffff;
}

#workspaces button:hover {
    background: rgba(0, 0, 0, 0.2);
}

#workspaces button.focused {
    background-color: #64727D;
    box-shadow: inset 0 -3px #ffffff;
}

#workspaces button.urgent {
    background-color: #eb4d4b;
}

#mode {
    background-color: #64727D;
    box-shadow: inset 0 -3px #ffffff;
}

#clock,
#battery,
#cpu,
#memory,
#disk,
#temperature,
#backlight,
#network,
#pulseaudio,
#wireplumber,
#custom-media,
#tray,
#mode,
#idle_inhibitor,
#scratchpad,
#power-profiles-daemon,
#mpd {
    padding: 0 10px;
    color: #ffffff;
}

#window,
#workspaces {
    margin: 0 4px;
}


/* If workspaces is the leftmost module, omit left margin */
.modules-left > widget:first-child > #workspaces {
    margin-left: 0;
}

/* If workspaces is the rightmost module, omit right margin */
.modules-right > widget:last-child > #workspaces {
    margin-right: 0;
}

#clock {
    background-color: #000000;
    font-weight: bold;
     color: #ffffff;
     border-bottom: 2px solid #ffffff;
}

#battery {
    background-color: #ffffff;
    color: #000000;
    border-bottom: 2px solid #ffffff;
}


#battery.charging, #battery.plugged {
    color: #ffffff;
    background-color: #26A65B;
}

@keyframes blink {
    to {
        background-color: #ffffff;
        color: #000000;
    }
}

/* Using steps() instead of linear as a timing function to limit cpu usage */
#battery.critical:not(.charging) {
    background-color: #000000;
    color: #ffffff;
    animation-name: blink;
    animation-duration: 0.5s;
    animation-timing-function: steps(12);
    animation-iteration-count: infinite;
    animation-direction: alternate;
}

#power-profiles-daemon {
    padding-right: 15px;
}

#power-profiles-daemon.performance {
    background-color: #f53c3c;
    color: #ffffff;
}

#power-profiles-daemon.balanced {
    background-color: #2980b9;
    color: #ffffff;
}

#power-profiles-daemon.power-saver {
    background-color: #2ecc71;
    color: #000000;
}

label:focus {
    background-color: #000000;
}
             
#cpu {
    background-color: #ffffff;
    color: #000000;
    border-bottom: 2px solid #000000;
}

#memory {
    background-color: #000000;
    border-bottom: 2px solid #ffffff;
}

#disk {
    background-color: #964B00;
}

#backlight {
    background-color: #90b1b1;
}

#network {
    background-color: #2980b9;
    border-bottom: 2px solid #ffffff;
}

#network.disconnected {
    background-color: #f53c3c;
    border-bottom: 2px solid #ffffff;
}

/* you can set a style on hover for any module like this */
#pulseaudio:hover {
    background-color: #000000;
    border-bottom: 2px solid #ffffff;
}

#pulseaudio {
    background-color: #f1c40f;
    color: #000000;
    border-bottom: 2px solid #ffffff;
}

#pulseaudio.muted {
    background-color: #90b1b1;
    color: #2a5c45;
    border-bottom: 2px solid #ffffff;
}

#wireplumber {
    background-color: #fff0f5;
    color: #000000;
}

#wireplumber.muted {
    background-color: #f53c3c;
}

#custom-media {
    background-color: #66cc99;
    color: #2a5c45;
    min-width: 100px;
}

#custom-media.custom-spotify {
    background-color: #66cc99;
}

#custom-media.custom-vlc {
    background-color: #ffa000;
}

#temperature {
    background-color: #f0932b;
}

#temperature.critical {
    background-color: #eb4d4b;
}

#tray {
    background-color: #000000;
    border-bottom: 2px solid #ffffff;
}

#tray > .passive {
    -gtk-icon-effect: dim;
    border-bottom: 2px solid #ffffff;
}

#tray > .needs-attention {
    -gtk-icon-effect: highlight;
    background-color: #eb4d4b;
    border-bottom: 2px solid #ffffff;
}

#idle_inhibitor {
    background-color: #2d3436;
    border-bottom: 2px solid #ffffff;
}

#idle_inhibitor.activated {
    background-color: #ecf0f1;
    color: #2d3436;
}

#mpd {
    background-color: #66cc99;
    color: #2a5c45;
}

#mpd.disconnected {
    background-color: #f53c3c;
}

#mpd.stopped {
    background-color: #90b1b1;
}

#mpd.paused {
    background-color: #51a37a;
}


#language {
    background: #000000;
    font-weight: bold;
    color: #ffffff;
    padding: 0 5px;
    margin: 0 5px;
    min-width: 20px;
    border-bottom: 2px solid #ffffff;
}


#keyboard-state {
    background: #97e1ad;
    color: #000000;
    padding: 0 0px;
    margin: 0 5px;
    min-width: 16px;
    border-bottom: 2px solid #ffffff;
}



#scratchpad {
    background: rgba(0, 0, 0, 0.2);
}

#scratchpad.empty {
        background-color: transparent;
}

#privacy {
    padding: 0;
}


#privacy-item {
    padding: 0 5px;
    color: white;
}

#privacy-item.screenshare {
    background-color: #cf5700;
}

#privacy-item.audio-in {
    background-color: #1ca000;
}

#privacy-item.audio-out {
    background-color: #0069d4;
}
          
Этот набор программ и конфигов формирует вполне самодостаточный набор интерфйеса и глаз радуется - после старта памяти занято на 300-400мб меньше, чем с гномом, занятость процессора на уровне .... низком, низчайшем и пр.

Вполне возможно, что gdm не захочет даже показывать возможность запуска сессии sway. В этом случае следует проверить содержание файла /etc/gdm/custom.conf - нет ли строчки WaylandEnable=false? и исправить на true, рестартовать gdm. После пробного входа в sway следует как минимум деактивировать gdm. Запуск осуществлятся стартом компьютера + логин + ввод в терминале слова sway

Про автологин и автозапуск sway - будем надеяться, что у Вас шифрованный раздел и до ввода пароля ничего не происходит. А после ввода хтелось бы не вводить другие и сразу попасть в рабочее окружение и делается это так:

от рута правим файл запуска службы первого терминала, закомментив одну строку и вписав другую -
vi  /etc/systemd/system/getty.target.wants/getty@tty1.service

#ExecStart=-/sbin/agetty -o '-- \\u' --noreset --noclear - ${TERM}
ExecStart=-/sbin/agetty -a ВАШЕ_ИМЯ_ПОЛЬЗОВАТЕЛЯ %I $TERM

и затем в хомовнике нужного пользователя (или всех) добавить строку в файл -
echo >> ~/.bash_profile  ' [[ -z $DISPLAY && $XDG_VTNR -eq 1 ]] && exec sway'


Вопросы запуска программ решаются трояко -

а) на бар прибиваем кнопку запуска нужной программы с нужными параметрами запуска, "командной строки". Это простые записи в конфиге waybar. Просто по аналогии с другими запиясями разнможаете свои.
б) на сочетание клавиш прибивается запуск нужной программы с нужными параметрами запуска, "командной строки". Это простые записи в конфиге sway, ассоциативно понятные индивидуальному пользователю. Кнопочек на клавиатуре много, возможностей для запуска хватит всем.
в) на сочетание клавиш Win (или иная главная клавиша) + d открывается терминальчки с интерфейсом ввода буковок и выбора к запуску программы без всяких параметров. Здесь возможно много модификаций, размеров и пр. Выбор этой модификации задается в конфиге sway. В представленном конфиге аж три версии запускалки, включая Вин-подобная кнопка Пуск (цвета шрифтов требуют коррекции по вкусу) и даже гномо-подобный Dash.

Предполагая, что переезд проводится из устоявшегося хозяйства, нет проблемы и даже есть прелесть в использовании варианта б).


Перед миграцией, переездом, надо разрешить важные прикладные вопросы - какими именно программами мы будем пользоваться? для меня существенную сложность представляют собой следующие блоки -
1. электронная почта. По-стариковски предпочитаю мейл всему остальному. Птица забракована за монстроидальность, Evolution привязан к Gnome, claws-mail не умеет в адресной книге делать заметки к контакту. Для меня этот вопрос пока не решен и прошу совета. Гугломылом я не пользуюсь, почта своя.
2. календарь-задачи. Если не птица и не эволюшн, то пока не знаю что, прошу совета.

Собственно эти два не решенных вопроса останавливают от окончательной миграции и полного снова гномова софта.
Последний раз редактировалось lnx 07.07.2025 12:29, всего редактировалось 9 раз.
indeviral
Аватара пользователя
Сообщения: 237
Зарегистрирован: 15.08.2022

#

lnx: 1. электронная почта. По-стариковски предпочитаю мейл всему остальному. Птица забракована за монстроидальность, Evolution привязан к Gnome, claws-mail не умеет в адресной книге делать заметки к контакту. Для меня этот вопрос пока не решен и прошу совета. Гугломылом я не пользуюсь, почта своя.
Не знаю при чём здесь sway. Но если у вас уже развёрнута почта, разверните к ней веб интерфейс. Сейчас они настолько функциональны, что перекрывают 100% задач.
lnx: 2. календарь-задачи. Если не птица и не эволюшн, то пока не знаю что, прошу совета.
Аналогично, я использую для этих целей nextcloud. Но так же есть дополнения к почтовым веб-интерфейсам которые закрывают эти задачи.

Ошибки в тексте-неповторимый стиль автора©

lnx
Сообщения: 155
Зарегистрирован: 24.08.2022

#

Веб доступы неприемлемы. Все должно быть локально. Онлайнами и вебмордами, включая к сосбвтенным же серверам, я наелся, надеюсь, навсегда.
Arhei
Сообщения: 6
Зарегистрирован: 04.07.2025

#

lnx: 1. электронная почта.
2. календарь-задачи.
...
Веб доступы неприемлемы. Все должно быть локально. Онлайнами и вебмордами, включая к сосбвтенным же серверам, я наелся, надеюсь, навсегда.
тогда наверное emacs/vim вам в помощь
Ответить