Hlavní navigace

Konfigurace Dwm – styl rozložení oken, spouštění aplikací, ovládání myší

13. 10. 2016
Doba čtení: 12 minut

Sdílet

Minulý díl byl věnován konfigurací Dwm včetně překladu, tagů, oken a klávesových zkratek. Dnešní díl se zaměří na dokončení této části, styl rozložení oken, spouštění aplikací a ovládání myší

Na konci minulého dílu jsem načal kapitolku o manipulaci s okny a tagy a na začátku dnešního se jí pokusím v rámci možností dokončit. Z této oblasti zbývá posledních šest akcí, které jsem také trochu přetvořil a odstranil z nich „divné“ znaky:

{ MOD,                   XK_F4,     view,           {.ui = ~0 } },
{ MOD|SHIFT,             XK_F4,     tag,            {.ui = ~0 } },
{ MOD,                   XK_F5,     focusmon,       {.i = -1 } },
{ MOD,                   XK_F6,     focusmon,       {.i = +1 } },
{ MOD|SHIFT,             XK_F5,     tagmon,         {.i = -1 } },
{ MOD|SHIFT,             XK_F6,     tagmon,         {.i = +1 } },

Komentář bude jednoduchý a bude se vztahovat pouze k prvním dvěma příkazům. Ty poslední čtyři se totiž vztahují k systémům, které obsahují více obrazovek/monitorů. To ovšem není můj virtuální případ, takže jsou všechny nefunkční.

  • Win+F4 – na aktivním tagu zobrazí otevřená okna ze všech ostatních tagů a přidá je ke stávajícím oknům aktivního tagu
  • Win+Shift+F4 – aktivní okno z aktivního tagu zkopíruje na ostatní tagy a přidá je ke stávajícím otevřeným oknům

Opět malá ukázka toho, co je možné provádět z tagy a co většinou není možné nebo „zprovozněné“ nad pracovními/virtuálními plochami jiných dlaždicových WM. Tímto konstatováním bych považoval kapitolku o manipulaci s okny a tagy za uzavřenou a pustil se do další. Tou bude krátké pojednání o možnostech rozložení oken na obrazovce. Bylo to sice zmíněno na začátku seriálu, ale pro jistotu to zde znovu zopakuji. Dwm dává uživateli k dispozic tři základní styly rozložení:

  • tile – klasické dlaždicové uspořádání s hlavní a stohovací oblastí
  • none – žádná volba, což se vlastně rovná běžného plovoucímu rozložení oken
  • monocle – zobrazeno pouze jediné okno na celou obrazovku, ostatní (pokud jsou nějaká otevřená) jsou jakoby „minimalizovaná“ a hlavně nejsou viditelná

Všechny tři uvedené varianty rozložení jsou ve standardní konfiguraci deklarované jako proměnná layouts, takže stačí velmi jednoduchá změna:

static const Layout layouts[] = {
    /* symbol     arrange function */
    { "[T]",      tile },    /* first entry is default */
    { "[M]",      monocle },
    { "[F]",      NULL },    /* no layout function means floating behavior */
    };

Jak ukazuje výpis kódu, provedl jsem pouze změnu a sjednocení textu, kterým je v panelu označen aktuální styl rozložení oken a také pořadí deklarace. Jasnější důvody pro změnu uvedu následně. Kromě samotného značení a vytvoření stylu rozložení jsou samozřejmě k dispozici i funkce pro jeho ovládání:

{ MOD,                   XK_t,      setlayout,      {.v = &layouts[0]} },
{ MOD,                   XK_m,      setlayout,      {.v = &layouts[1]} },
{ MOD,                   XK_f,      setlayout,      {.v = &layouts[2]} },
{ MOD,                   XK_space,  setlayout,      {0} },
{ MOD|SHIFT,             XK_space,  togglefloating, {0} },
  • Win+T – na aktivním tagu nastaví styl tile (nebo ten, který je deklarován v proměnné jako první)
  • Win+M – na aktivním tagu nastaví styl monocle (nebo ten, který je deklarován v proměnné jako druhý)
  • Win+F – na aktivním tagu nastaví styl none (nebo ten, který je deklarován v proměnné jako třetí)
  • Win+mezerník – prohodí na aktuálním tagu dva naposledy vybrané styly rozložení oken
  • Win+Shift+mezerník – pro aktivní okno nastaví plovoucí styl otevřených oken

Po ukázce kódu a krátkém vysvětlení je asi jasné, proč jsem volil změnu textu při deklaraci proměnné stylu rozložení. Má to vlastně dva důvody: zobrazení s písmeny je mnohem intuitivnější, než předchozí rovnítko či špičaté závorky a také to přesně koresponduje s nastavením funkcí pro změnu stylu na aktivním tagu. Změnu pořadí jsem udělal proto, že jako dlouhodobý uživatel Awesome si myslím, že to odpovídá četnosti využití jednotlivých stylů rozložení oken při uživatelské práci. Na závěr kapitolek o možnostech ovládání oken tagů a stylu rozložení oken bych rád uvedl tři skutečnosti, kterých si možná uživatelé „běžných“ WM nevšimli:

  • při manipulaci s tagy není k dispozici funkce, která by je „procházela“ v definovaném pořadí v nekonečné smyčce. Tato funkce je v některých dlaždicových WM celkem běžná (v Awesome třeba je). Když se ale zamyslím nad tím, jak by byla použitelná při deklaraci více tagů, tak si myslím, že řešení v Dwm je praktičtější. Přímý přechod na vybraný tag je podle mého názoru dokonce lepším řešením, než postupná změna v daném pořadí tagů
  • podobná funkce „nekonečného“ procházení není definovaná ani pro styly rozložení oken. Je sice pravda, že pro tři styly v Dwm by to nebyl zásadní problém, ale i tak se mi přímá volba stylu jeví jako praktičtější
  • Dwm chybí (myšleno v základní konfiguraci!) možnost nastavit pro vybraný tag nějaký styl rozložení oken, který by na něm byl defaultní. Tato funkce může chybět asi nejvíce z uvedených, ale podle mého názoru to není zase až tak kritické. Navíc se to dá v rámci rozšířené konfigurace nahradit dokonce dvěma způsoby. Oba z nich v dalším textu krátce objasním a jeden i prakticky ukážu

Než úplně dokončím popis stylu rozložení oken, tak se krátce vrátím ke spouštění aplikací pomocí klávesových zkratek přímo z Dwm. Ono to zde již bylo zmíněno při krátkém popisu základních akcí ve standardní konfiguraci. Není nutné zde popisovat žádné rozsáhlé varianty, takže zůstanu při stejné formě, jako v předchozích popisovaných WM. Změna a celkový kód této sekce bude v konfiguraci vypadat následovně:

/* commands */
/*Apps launchers*/
static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */
static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbgcolor, "-sf", selfgcolor, NULL };
static const char *gmruncmd[]  = { "gmrun", NULL };
static const char *roficmd[]  = { "rofi", "-show", "run", "-sidebar-mode", "-lines", "20", "-columns", "2", NULL };

/*Basic apps*/
static const char *termcmd[]  = { "lilyterm", NULL };
static const char *editcmd[]  = { "mousepad", NULL };
static const char *fmancmd[]  = { "xfe", NULL };
static const char *webbcmd[]  = { "netsurf", NULL };

/*Session management*/
static const char *haltcmd[]  = { "oblogout", NULL };
static const char *lockcmd[]  = { "i3lock", "--color=008080", "--pointer=default", "--show-failed-attempts", NULL };

Na celé deklaraci jsou asi zajímavé pouze ty příkazy, kde je potřeba definovat nějaké parametry pro běh aplikace (dmenu, rofi, i3lock). Rozdíly oproti dříve popisovaným Spectrwm a Qtile jsou sice velké, ale z uvedených příkladů lze velmi snadno dovodit, jak by příkazy měly obecně vypadat. Pozornější čtenáři si možná také všimli, že parametry spouštěče Rofi jsou jiné, konkrétně přibyl nový parametr -sidebar-mode. K němu se ještě vrátím později. Sekci pro spouštění definovaných příkazů upravím také podle deklarovaného vzoru:

{ MOD|ALT,               XK_p,      spawn,          {.v = dmenucmd } },
{ MOD|ALT,               XK_g,      spawn,          {.v = gmruncmd } },
{ MOD|ALT,               XK_space,  spawn,          {.v = roficmd } },
{ MOD|ALT,               XK_Return, spawn,          {.v = termcmd } },
{ MOD|ALT,               XK_e,      spawn,          {.v = editcmd } },
{ MOD|ALT,               XK_f,      spawn,          {.v = fmancmd } },
{ MOD|ALT,               XK_b,      spawn,          {.v = webbcmd } },
{ MOD|ALT,               XK_Delete, spawn,          {.v = lockcmd } },
{ MOD|ALT,               XK_End,    spawn,          {.v = haltcmd } },

Abych ještě nezapomněl, trochu jsem upravil i obecný vzhled prostředí nastavením systémového fontu a fontu pro dmenu:

/* appearance */
static const char *fonts[]         = {"monospace:bold:size=10"};
static const char dmenufont[]       = "monospace:bold:size=11";

Tím by byla půda bezpečně připravena k návratu do stylů rozložení oken na obrazovce. Konkrétně řečeno pouze k jednomu z nich: Monocle. Jak již bylo uvedeno, v tomto stylu je viditelné pouze jedno aktivní okno (nejčastěji to naposledy otevřené). Pokud jsou otevřená ještě nějaká další okna, tak jsou vlastně neviditelná. To se zdá být docela nepříjemné, ale Dwm si s tím dokáže celkem hravě poradit. Pokud je totiž otevřeno v tomto stylu rozložení více oken, text na panelu neukazuje očekávanou značku stylu [M], ale místo toho značku jinou – [num]. Text num není samozřejmě zobrazen, ale v hranaté závorce se ukazuje celkový počet otevřených oken, samozřejmě na aktuálním tagu. Mezi okny lze samozřejmě přepínat pomocí změny fokusu kombinací Win+šipka vlevo/vpravo. Uvedenou skutečnost ukazuje následující obrázek

Ukazatel počtu oken

Zde se vrátím znovu ke spouštěči aplikací Rofi. Následující dva obrázky ukazují, jak vypadá v původní verzi (použité v předchozích popisovaných WM) a v aktuální verzi pro Dwm, s dalším novým parametrem:

Původní varianta Rofi

Aktuální varianta Rofi

Jak je z posledního obrázku zřejmé, ve spodním řádku se objevily tři položky: window, run, ssh. Ta prostřední je známá a obsahuje již vícekrát zmiňovaný a demonstrovaný spouštěč aplikací. Ta vpravo nebude pro článek zajímavá, ale její název asi napoví dostatečně. Pro aktuální kontext je ale zajímavá položka úplně vlevo. Je možné se do ní dostat pomocí klávesové zkratky Shift+šipka vlevo. Situaci po jejím použití ukazuje další obrázek

Seznam oken Rofi

Jak je z obrázku patrné, objevil se přehled všech otevřených oken. V něm je možné vybírat pomocí myši a myším dvojklikem dostat vybrané okno do popředí, případně mu „nadělit“ fokus v jiném stylu rozložení oken. Pro ještě lepší informaci je zde další obrázek:

Seznam všech oken

Zde je změna v tom, že je otevřené okno i na druhém tagu a Rofi ukazuje všech pět otevřených oken bez ohledu na to, ve kterém tagu byla spuštěna. Tato funkce by se někdy mohla hodit, proto jsme považoval za důležité na ni upozornit. V další části se vrátím k výše uvedené (ne)možnosti nastavit pro daný tag definovaný styl rozložení oken. Tato skutečnost se dá částečně obejít použitím pravidel pro otevírání oken, které se nazývá Rule, proměnná rules. Standardně jsou v konfiguraci nastavená dvě tato pravidla:

</p><pre>static const Rule rules[] = {
    /* xprop(1):
     *    WM_CLASS(STRING) = instance, class
     *    WM_NAME(STRING) = title
     */
    /* class      instance    title       tags mask     isfloating   monitor */
    { "Gimp",     NULL,       NULL,       0,            1,           -1 },
    { "Firefox",  NULL,       NULL,       1 << 8,       0,           -1 },
};

Jak základní definici napovídá, skládá se pravidlo z celkem šesti parametrů. První tři jsou údaje o aplikaci/okně, které pocházejí ze systémového nástroje xprop. Které informace je třeba použít je jasné z nápovědy a za chvíli to předvedu i v praxi. Dalším parametrem je tag mask, který má souvislost s tím, na kterém tagu se má daná aplikace či okno otevřít. Na první pohled to ale vypadá dost neprůhledně, takže je třeba krátké vysvětlení. To podrobnější je možné najít zde: Nápověda Tag mask. Obecně platí, že pro vyjádření pozice tagu (ta ovšem nijak nesouvisí s tím, že jsem tagy pojmenoval 1–3! Klidně by mohly být pojmenované pomocí jednotlivých písmen nebo jejich „shluků“) se používá bitová maska. Pro konkrétní případ tří definovaných tagů bude jejich binární vyjádření vypadat takto:

  • tag označený 1 = 000000001
  • tag označený 2 = 000000010
  • tag označený 3 = 000000100

Parametr tag mask může mít dva různé formáty zápisu, což je ostatně vidět i z kódu. První formát je jednoduchý a je vždy vyjádřen hodnotou NULA (0). To znamená, že je aplikace/okno otevřeno na aktuálním tagu. Druhý formát je obecně možné popsat takto: 1 << NUM. Toto znamená bitový posun jedničky o NUM míst doleva. Abych to ještě více objasnil, tak použiju jako příklad spouštěč aplikací gmrun. To je docela dobrý příklad pro nastavení v dlaždicových WM, kdy se rád otevírá přes celou plochu obrazovky… Jako první uvedu obrázek s výsledkem zjištění vlastností spuštěného okna aplikace:

Parametry okna Gmrun

Důležité parametry jsou až na konci:

WM_CLASS(STRING) = "gmrun", "Gmrun"
WM_NAME(STRING) = "Execute program feat. completion"

Mám tedy k dispozici základní informace o aplikaci/okně a kromě toho chci, aby se Gmrun otevíral, kdekoliv to bude nutné (na aktuálním tagu), a pro jistotu měl plovoucí charakter. Tím se dostávám k dalšímu parametru pravidel – isfloating. Jak je z příkladu patrné, jedná se o logickou hodnotu, která se buď nastaví nebo ne. Poslední parametr (monitor) bude v aktuálním případě mít vždy hodnotu –1 (není vybrán žádný konkrétní monitor, neboť je k dispozici pouze jeden jediný). Celé pravidlo pak může vypadat takto:

{ "Gmrun",     NULL,       NULL,       0,            1,           -1 },

Pokud by to chtěl někdo vyzkoušet, tak zjistí, že toto pravidlo bylo pouze ukázkou pro vysvětlení. Bez ohledu na to, jaký styl má daný tag, Gmrun se zobrazí vždy korektně i bez nastavení pravidel. Zkusím proto jiný příklad a upravím stávající pravidlo pro Gimp tak, aby se vždy otevřel na druhém (prostředním) tagu. Jenom kvůli tomu budu Gimp instalovat a nechám ho v základním formátu se samostatnými okny. Pokud se otevře samotná aplikace na libovolném stylu rozložení, nic se neděje. Při otevření další aplikace vedle Gimpu už může být docela problém prakticky u všech stylů rozložení. Pravidlo by tedy mohlo vypadat takto:

{ „Gimp“,     NULL,       NULL,       1 << 1,            1,           –1 },

Bitovým posunem o 1 se provedlo zobrazení na druhém tagu. Pokud by byl posun 0, byl by to první tag, při posunu o 2 by to byl tag poslední. Je třeba si také všimnout standardního pravidla pro Firefox, kde jsou dva problémy. První je celkem snadno řešitelný: žádná taková aplikace není ve zkušebním systému instalovaná. Druhý problém je ale ještě trochu zákeřnější: zadané pravidlo říká, že by se měla aplikace otevřít na devátém tagu. Samozřejmě to vychází z původně deklarovaných devíti tagů, ale dané pravidlo by nemohlo fungovat v aktuální konfiguraci, protože by nebyl k dispozici tag, na kterém se má aplikace otevřít. Proto je dobré toto pravidlo buď smazat nebo použít pro jinou aplikaci nebo upravit podle potřeby. Po uložení změn a novém překladu je možné definovaná pravidla vyzkoušet. Fungují naprosto bezvadně.

Na závěr dnešního dílu dám sekci konfigurace, kde jsou definovány akce pro myší tlačítka, popř. kombinace s nějakým modifikátorem:

/* button definitions */
/* click can be ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */
static Button buttons[] = {
    /* click                event mask      button          function        argument */
    { ClkLtSymbol,          0,              Button1,        setlayout,      {0} },
    { ClkLtSymbol,          0,              Button3,        setlayout,      {.v = &layouts[2]} },
    { ClkWinTitle,          0,              Button2,        zoom,           {0} },
    { ClkStatusText,        0,              Button2,        spawn,          {.v = termcmd } },
    { ClkClientWin,         MOD,            Button1,        movemouse,      {0} },
    { ClkClientWin,         MOD,            Button2,        togglefloating, {0} },
    { ClkClientWin,         MOD,            Button3,        resizemouse,    {0} },
    { ClkTagBar,            0,              Button1,        view,           {0} },
    { ClkTagBar,            0,              Button3,        toggleview,     {0} },
    { ClkTagBar,            MOD,            Button1,        tag,            {0} },
    { ClkTagBar,            MOD,            Button3,        toggletag,      {0} },
};

K nim jenom krátké vysvětlení:

root_podpora

  • klik levým tlačítkem na zobrazení stylu rozložení oken v panelu prohodí poslední dva aktivní tagy
  • klik pravým tlačítkem na zobrazení stylu rozložení oken v panelu nastaví styl rozložení oken v aktivním tagu na none = [F] (případně jiný, podle čísla v parametru pořadí deklarovaných stylů)
  • klik prostředním tlačítkem (= současně levým i pravým) na název okna v panelu přesune dané okno ze stohovací do hlavní oblasti obrazovky
  • klik prostředním tlačítkem na text dwm-6.1 v pravém rohu spustí deklarovaný terminál
  • Win+klik levým tlačítkem kdekoliv v otevřeném okně umožní při jeho držení posunovat okno po ploše
  • Win+klik prostředním tlačítkem kdekoliv v otevřeném okně umožní nastavit okno jako plovoucí
  • Win+klik pravým tlačítkem kdekoliv v otevřeném okně umožní při jeho držení měnit velikost okna po ploše

Poslední tři části konfigurace si nechám zase až do příštího dílu.

Dnešní díl jsem věnoval dokončení popisu manipulace s tagy a okny. Dále byla probrána konfigurace stylů rozložení oken a jejich ovládání. Nastavení klávesových zkratek bylo dokončeno konfigurací spouštěčů pro základní uživatelskou sadu aplikací. Krátce byla také zmíněna pravidla pro spouštěné aplikace a možnosti ovládání prostředí pomocí myších tlačítek. V příštím dílu se pustím do krátkého nastavení vzhledu prostředí. Kromě toho představím možnosti využití stavového panelu pro uživatelské účely. Díl pak bude ukončen rozsáhlejší ukázkou možnosti úpravy Dwm pomocí patchů.

Byl pro vás článek přínosný?