Sostituisci il titolo di una finestra arbitraria in KDE e imposta un titolo di finestra personalizzato


14

Usando KDE qui, ma potrebbe esserci una soluzione che funziona anche con altri ambienti desktop. Spesso ho a che fare con molte finestre. La maggior parte delle finestre contiene molte schede (ad esempio una finestra Dolphin con molte schede o Firefox, Konsole, ecc.). Il titolo della finestra cambierà in base alla mia scheda corrente (che per la maggior parte è utile la maggior parte delle volte), ma quando lavoro con così tante finestre mi piacerebbe organizzarle un po 'e riuscire a rinominare manualmente la finestra , sovrascrivendo il titolo della finestra fornito dall'applicazione . Potrei nominare una finestra di Firefox "Ricerca" e un'altra finestra di Firefox "Documentazione" per poter facilmente distinguere tra le finestre che ho usato per organizzare e raggruppare le diverse schede di conseguenza.

Idealmente sarei in grado di fare clic su una barra del titolo della finestra e assegnarle facilmente un nome personalizzato, ma mi accontenterei di una soluzione leggermente più ingombrante finché funziona.

Ho provato wmctrl -r :SELECT: -T "Research"ma funziona solo temporaneamente (il titolo viene ripristinato quando l'applicazione lo modifica, ad esempio quando si cambia scheda).


Le app native di KDE hanno --captionun'opzione da riga di comando che ti consente di impostare il titolo della finestra, ma non credo sia proprio quello che stai cercando.
David Z,

@SeanMadsen Heya, hai ancora bisogno di questo? Perché se lo fai, mi piacerebbe sapere se riesci a far funzionare la mia sceneggiatura per te. ^^;
Owen_R,

Grazie @Owen_R Il tuo script ha funzionato e ho aggiunto un repository per esso su GitHub .
Sean,

@SeanMadsen ah, sono felice di sentire che qualcun altro ha finalmente avuto un po 'di utile dalla mia risposta! Anche se la cosa divertente è che io stesso non uso più quella sceneggiatura di pesce; L'ho riscritto in ruby ​​qualche tempo fa. Ma realisticamente non riuscirò a metterlo su Github in qualunque momento presto, comunque, quindi l'ho modificato alla fine della mia risposta se lo vuoi.
Owen_R

Risposte:


4

Ho avuto lo stesso identico problema.

Quindi ho scritto uno script di shell che ho associato a un tasto di scelta rapida.

Quando premo il tasto di scelta rapida, ottiene l'ID della finestra attualmente attiva (quella che ha lo stato attivo).

Quindi ti dà una finestra pop-up in cui inserisci il titolo che desideri che quella finestra abbia.

Quindi ogni volta che quella finestra cambia nome, lo cambia di nuovo nel titolo desiderato.

Per utilizzare lo script, è necessario:

  • il fishguscio
    (l'ho scritto nei pesci piuttosto che bash perché mi fa venire mal di testa)

  • kdialog

  • un modo per associare lo script a un tasto di scelta rapida
    (io uso xbindkeys, perché tutto quello che dovevo fare per farlo funzionare era aggiungere:

"[PATH TO SCRIPT]/[NAME OF SCRIPT]" Mod4 + t

(ovvero, tasto finestra + t)
a mio /home/o1/.xbindkeysrc)

Grazie a questo tizio , che mi ha dato le informazioni sulla roba magica di xprop.

(Tipo, un anno fa, e poi non sono mai riuscito a scrivere la sceneggiatura fino ad oggi. XD)

PS Se un neofita trova questa risposta e non sa come usarla, chiedimi e ti guiderò. ^^

EDIT: L'ho aggiornato in modo da poterlo utilizzare dalla riga di comando con le opzioni -tfor title_i_wante -wfor window_id.

Ecco la sceneggiatura:

#!/usr/local/bin/fish

# this block is so you can use it from the command line with -t and -w
if test "$argv" != "" -a (math (count $argv)%2 == 0)
    for i in (seq 1 (count $argv))
        if test $argv[$i] = '-t'
            set title_i_want $argv[(math 1 + $i)]
        else if test $argv[$i] = '-w'
            set window_id $argv[(math 1 + $i)]
        end
    end
    if not test $window_id
        echo "YOU DIDN'T ENTER A `window_id` WITH `-w`,
SO MAKE SURE THE WINDOW YOU WANT HAS FOCUS
TWO SECONDS FROM NOW!"
        sleep 2
    end
end

# get the id of the currently focused window
if not test $window_id
    set window_id (xprop -root _NET_ACTIVE_WINDOW | grep -P -o "0x\w+")
end

# get the title to force on that window

if not test $title_i_want
    set title_i_want (kdialog --title "entitled" --inputbox "type the title you want and hit enter.
to stop renaming,
just enter nothing and hit esc")
end

# this bit is needed for a kludge that allows window renaming
set has_renamed_before "FALSE"
set interrupt_message "WAIT WAIT I WANT A TURN BLOO BLOO BLEE BLUH BLOO" # hopefully i never want to actually use that as a title xD
xprop -f _NET_WM_NAME 8u -set _NET_WM_NAME $interrupt_message -id $window_id

# take the output of xprop
# pipe it into a while loop
# everytime it outputs a new line
# stuff it into a variable named "current_title"
xprop -spy _NET_WM_NAME -id $window_id | while read current_title

    # cut off extraneous not-the-title bits of that string
    set current_title (echo $current_title | grep -P -o '(?<=_NET_WM_NAME\(UTF8_STRING\) = ").*(?="\z)')

    # if the current title is the interrupt message
    # AND
    # this script has renamed the window at least once before
    # then we wanna let the new name take over
    if test $current_title = $interrupt_message -a $has_renamed_before = "TRUE"
        exit
    # if title_i_want is an empty string, exit
    else if test $title_i_want = ""
        xprop -f _NET_WM_NAME 8u -set _NET_WM_NAME "WIDNOW WILL START RENAMING ITSELF AS NORMAL" -id $window_id
        exit
    # otherwise just change the title to what i want
    else if test $current_title != $title_i_want
        xprop -f _NET_WM_NAME 8u -set _NET_WM_NAME "$title_i_want" -id $window_id
        set has_renamed_before "TRUE"
    end
end

EDIT: In realtà non uso più questo script Fish;
L'ho riscritto in Ruby:

#!/usr/bin/env ruby
# -*- coding: utf-8 -*-

require 'trollop'
opts = Trollop.options do
                        opt :title_i_want,  "title_i_want",     default: ""
                        opt :bluh,          "write to bluh",    default: nil
                        opt :copy_title,    "copy_title",       default: nil
# TODO - AUTO OPTION                                            
                        opt :auto,          "auto",             default: nil
end

title_i_want    = opts[:title_i_want]


def get_current_wid
    `xprop -root _NET_ACTIVE_WINDOW`[/0x\w+/]
end

def with_current_title wid, &block
    IO.popen("xprop -spy _NET_WM_NAME _NET_WM_ICON_NAME -id #{wid}") do |io|
        loop do
            line = io.gets
            exit if line.nil?
            line = line.strip
            # cut off extraneous not-the-title bits of that string
            current_title = line[/(?:_NET_WM_(?:ICON_)?NAME\(UTF8_STRING\) = ")(.*)("$)/, 1]

            block.call current_title unless current_title.nil?
        end
    end
end
def get_current_title wid
    IO.popen("xprop _NET_WM_NAME _NET_WM_ICON_NAME -id #{wid}") do |io|
            line = io.gets.strip
            # cut off extraneous not-the-title bits of that string
            current_title = line[/(?:_NET_WM_(?:ICON_)?NAME\(UTF8_STRING\) = ")(.*)("$)/, 1]

            return current_title unless current_title.nil?
    end
end

if opts[:copy_title]
    # require "muflax"
    p 1
    wid = get_current_wid
    `echo -n '#{get_current_title wid}(WID: #{wid})'|xclip -selection c`
    exit
end
if opts[:bluh]
    require "muflax"
    loop do
        # p 1   #db
        wid = get_current_wid
        # p 2   #db
        File.open "bluh", "a+" do |f| f.puts get_current_title wid end
        while wid == get_current_wid
            # puts "..."    #db
            sleep 1
        end
    end
    exit
end

#> 1A - from terminal - give title_i_want
if not title_i_want.empty?
#> 1A.1 - get current wid - assume it's the terminal_wid
    terminal_wid = get_current_wid
#> 1A.2 - wait for wid to change
    while get_current_wid == terminal_wid
        puts "focus the window you want to title «#{title_i_want}»..."
        sleep 1
    end
#> 1A.3 - set new wid to target TWID
    TWID = get_current_wid

#> 1B - from hotkey (or just sleeping) - no give title_i_want
else
#> 1B.1 - set current wid to target TWID
    TWID = get_current_wid
#> 1B.2 - get title_i_want (with kdialog)
#> 1B.2.1 - default to current title
    with_current_title TWID do |current_title|
        # v :current_title  #db
        default_title = current_title

        sublime_match = /
            (?<beginning>.*?)                                   # beginning might be...
                                                                #           path
                                                                #           untitled, find results, other useless junk
                                                                #           𝌆 dired
            (?<dirty>\s•)?                                      # dirty?
            (?:\s\(\.?(?<projname>[^()]*)\))?                   # project name, preceded by "." (i name them that way), and in rkaks (sublime does that)
                                                                # or, sans dot, it's the dir, if the window was opened as a dir
            (?<issub>\s-\sSublime\sText\s2\s\(UNREGISTERED\))   # garbage at the end that marks it as a sublime window
        /x =~ current_title

        #if it's a sublime window...
        if sublime_match
            dummy = beginning.split("/")
            if dummy.length > 1
                taildir = dummy[-2]
            end
            /𝌆 (?<direddir>.*)/ =~ beginning

            default_title =
            if      projname    ;   projname
            elsif   taildir     ;   taildir
            elsif   direddir    ;   direddir
            else                ;   beginning
            end
        end

        if opts[:auto]
            title_i_want = default_title
        else
            title_i_want = `kdialog --title "entitled" --inputbox "type the title you want and hit enter.\nto stop renaming,\njust enter nothing and hit esc" '#{default_title}'`.chomp
        end
        break
    end
end


# v :terminal_wid   #db
# v :TWID           #db
# v :ARGV           #db
# v :title_i_want   #db


def set_title wid, title
    `xprop  -f _NET_WM_NAME 8u      -set _NET_WM_NAME       "#{title}"  -id #{wid}`
    `xprop  -f _NET_WM_ICON_NAME 8u -set _NET_WM_ICON_NAME  "#{title}"  -id #{wid}`
end


#> 2 - apply title to TWID
#> 2.1 - allow de-naming
#> 2.2 - allow renaming

# this bit is needed for a kludge that allows window renaming
has_renamed_before  = false
interrupt_message   = "WAIT WAIT I WANT A TURN BLOO BLOO BLEE BLUH BLOO" # hopefully i never want to actually use that as a title xD
`xprop -f _NET_WM_NAME 8u -set _NET_WM_NAME '#{interrupt_message}' -id #{TWID}`

with_current_title TWID do |current_title|

    # if title_i_want is an empty string, exit
    if title_i_want.empty?
        # p 1   #db
        set_title TWID, "WINDOW WILL START RENAMING ITSELF AS NORMAL"
        exit

    # if the current title is the interrupt message
    # AND
    # this script has renamed the window at least once before
    # then we wanna let the new name take over
    elsif current_title == interrupt_message and has_renamed_before
        # p 2   #db
        exit


    # otherwise just change the title to what i want
    elsif current_title != title_i_want
        # p 3   #db
        set_title TWID, title_i_want
        has_renamed_before = true
    end
end

Sì, questo ha funzionato per me!
Sean,

Trova questo script su GitHub qui: github.com/seanmadsen/kustom-window-title
Sean

Lo script ruby ​​non sembra funzionare su Kubuntu 16.04? Ottengo la finestra pop-up, ma il titolo della finestra non cambia. La sceneggiatura del pesce funziona alla grande, però!
Supernormal

2

Quello che stai cercando suona come una funzione di tagging finestra . Dubito che KDE abbia il supporto per questo, altri WM (come XMonad, DWM ecc.).

Pertanto, una possibilità per ottenere questo incremento di produttività sarebbe quella di scambiare kwinXMonad e configurare XMonad per eseguire il tagging . Il meccanismo di tagging XMonad come descritto nel secondo link sarebbe quello di associare una combinazione di tasti per aprire un prompt che ti permetta di taggare la finestra focalizzata. (La configurazione di XMonad è in realtà un programma Haskell, quindi non esitate a chiedere aiuto in #xmonad.

Modifica: Mentre consiglierei a tutti di provare almeno una volta WM di piastrellatura, ho dimenticato di sottolineare che mentre XMonad viene comunemente chiamato WM di piastrellatura, esiste una modalità "float". Ci sono sicuramente altri WM che supportano layout di tagging e non-tiling, ma non conosco la loro interoperabilità con KDE.


1

Poiché non esiste alcun modo per impostare il titolo della finestra in modo da proteggere dalla scrittura, non esiste una soluzione a questo problema, poiché molti programmi reimpostano il titolo su azioni diverse come già scoperto.

Ma forse un bel suggerimento per le persone di KDE e Gnome ;-)


0

Stavo cercando la stessa cosa e per lo stesso motivo. Ho finito per passare troppo tempo su questo, con questo script da 70 righe.

Come funziona?

  • avvia la sceneggiatura
  • fai clic sulla finestra per cui vuoi impostare un titolo
  • e inserisci il titolo che desideri

Quindi inizierà un ciclo in background, controllerà ogni 3 secondi e imposterà il titolo se cambia.

Attenzione: non eseguire due volte nella stessa finestra, lo script non è perfetto.

nome dello script di esempio:sticky-title

#!/bin/bash


# stop all instance of this script if "killall" provided as first argument
if [ "$1" == "killall" ]; then
  scriptname=$(basename "$0")
  pattern="[0-9]* /bin/bash .*$scriptname$"
  pids=$(ps ax -o pid,cmd | grep -P "$pattern" | sed 's/^ *//;s/ *$//' | grep -Pv ' grep|killall$' | cut -d" " -f1)
  if [ "$pids" != "" ]; then
    kill -TERM $pids
    echo "$(echo '$pids' | wc -l) instances stopped"
  else
    echo "None found to stop"
  fi
  exit 0
fi

# ask for window
echo -en "\nClick the window you want to set its title "
id=$(printf %i $(xwininfo | grep 'Window id' | cut -d" " -f4))

# fail if no window id
if [ "$id" == "" ]; then
  echo 'Error: Window id not found'
  exit 1
else
  echo "- Got it"
fi

# ask for title
read -e -p "Enter target title: " title

# fail if no title
if [ "$title" == "" ]; then
  echo "Error: No title to set"
  exit 1
fi

# define loop as a function, so we can run it in background
windowByIdSetStickyTitle() {
  local id title curr_title
  id="$1"
  title="$2"

  while true; do
    # get current title
    curr_title="$(xdotool getwindowname $id 2>/dev/null)"

    # exit if we can't find window anymore
    if [ $? -ne 0 ]; then
      echo "Window id does not exist anymore"
      break
    fi

    # update title if changed
    if [ "$curr_title" != "$title" ]; then
      xdotool set_window --name "$title" $id
    fi

    # needed else you will eat up a significant amount of cpu
    sleep 3
  done
}

# infinite loop
windowByIdSetStickyTitle $id "$title" &


# done
echo "Sticky title set"
exit 0
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.