Sadece Telegram'ın çalışmasını istiyorum ve onu başlangıç uygulamalarına ekledim. Mesele şu ki, minimize edilmesi gerekiyor. Herhangi bir komut var mı?
Sadece Telegram'ın çalışmasını istiyorum ve onu başlangıç uygulamalarına ekledim. Mesele şu ki, minimize edilmesi gerekiyor. Herhangi bir komut var mı?
Yanıtlar:
Bir uygulamayı simge durumuna küçültülmüş olarak başlatmak iki komut alır:
Bu nedenle, komut veya komut dosyasının "akıllı" olması gerekir; ikinci komut, uygulama penceresinin görünmesini beklemelidir.
Aşağıdaki komut dosyası bunu yapar ve bir uygulamayı en aza indirgemek için genel bir çözüm olarak kullanılabilir. Sadece sözdiziminde çalıştırın:
<script> <command_to_run_the_application> <window_name>
#!/usr/bin/env python3
import subprocess
import sys
import time
subprocess.Popen(["/bin/bash", "-c", sys.argv[1]])
windowname = sys.argv[2]
def read_wlist(w_name):
try:
l = subprocess.check_output(["wmctrl", "-l"]).decode("utf-8").splitlines()
return [w.split()[0] for w in l if w_name in w][0]
except (IndexError, subprocess.CalledProcessError):
return None
t = 0
while t < 30:
window = read_wlist(windowname)
time.sleep(0.1)
if window != None:
subprocess.Popen(["xdotool", "windowminimize", window])
break
time.sleep(1)
t += 1
Senaryo hem ihtiyacı wmctrl
ve xdotool
:
sudo apt-get install wmctrl xdotool
Sonra:
startup_minimizd.py
Komut dosyasını (örn.) Komutuyla test gedit
edin:
python3 /path/to/startup_minimizd.py gedit gedit
Startup Applications
wmctrl
, ikinci argümanınızdan sonra adlandırılan pencereler için pencere listesini (yardımıyla ) denetler .xdotool
pencerenin herhangi bir nedenle görünmemesi durumunda sonsuz bir döngüyü önlemek için komut dosyası, pencerenin görünmesi için 30 saniyelik bir zaman sınırı uygular.Komut dosyasını, komut dosyasının dışındaki bağımsız değişkenlerle çalıştırdığınız için, komut dosyasını aynı anda birden çok uygulama için kullanabileceğinizi belirtmenize gerek yoktur.
Pencere başlığı emin veya değişken değilse veya pencerenin adında ad çakışması riski varsa, kullanmak pid
daha güvenilir bir yöntemdir.
Aşağıdaki komut dosyası, hem wmctrl -lp
ve hem de çıktısında olduğu gibi uygulamanın pid'inin kullanımına dayanmaktadır ps -ef
.
Kurulum hemen hemen aynıdır, ancak bu sürümde pencere başlığı gerekli değildir, bu nedenle çalıştırma komutu şöyledir:
python3 /path/to/startup_minimizd.py <command_to_run_application>
Sadece ilk senaryosu gibi, ihtiyacı hem wmctrl
vexdotool
#!/usr/bin/env python3
import subprocess
import sys
import time
command = sys.argv[1]
command_check = command.split("/")[-1]
subprocess.Popen(["/bin/bash", "-c", command])
t = 1
while t < 30:
try:
w_list = [l.split() for l in subprocess.check_output(["wmctrl", "-lp"]).decode("utf-8").splitlines()]
proc = subprocess.check_output(["pgrep", "-f", command_check]).decode("utf-8").strip().split()
match = sum([[l[0] for l in w_list if p in l] for p in proc], [])
subprocess.Popen(["xdotool", "windowminimize", match[0]])
break
except (IndexError, subprocess.CalledProcessError):
pass
t += 1
time.sleep(1)
Genel olarak ikinci sürüm daha güvenilir olmakla birlikte, uygulamanın bir sarıcı komut dosyası tarafından başlatılması durumunda, komutun pid'i nihayet çağrılan uygulamadan farklı olacaktır.
Bu gibi durumlarda, ilk komut dosyasını kullanmanızı öneririm.
Bir yorumda istendiği gibi, bir versiyonun altında, STEAM'ı başlatmak için özel olarak yapılmıştır.
Bu çıkıyor Steam
"normal" bir uygulamadan oldukça farklı davranır:
Steam
çalıştırmıyor , ancak (testimde) sekizden az değil !Steam
başlangıçta en az iki pencere (bir sıçrama benzeri pencere) ile çalışır, ancak bazen ek bir mesaj penceresi görünür.pid 0
, senaryoda olduğu gibi bir sorundur.Bu istisnai davranış Steam
, betiğin aşağıda eklenen özel bir sürümünü ister. Senaryo başlar Steam
ve 12 saniye boyunca, WM_CLASS
minimize olup olmadıklarını kontrol ederek ilgili tüm yeni pencerelere göz atar. Değilse, komut dosyası bunların olmasını sağlar.
Orijinal komut dosyası gibi, bunun da yüklenmesi wmctrl
ve xdotool
yüklenmesi gerekir.
#!/usr/bin/env python3
import subprocess
import time
command = "steam"
subprocess.Popen(["/bin/bash", "-c", command])
def get(cmd):
return subprocess.check_output(cmd).decode("utf-8").strip()
t = 0
while t < 12:
try:
w_list = [l.split()[0] for l in get(["wmctrl", "-l"]).splitlines()]
for w in w_list:
data = get(["xprop", "-id", w])
if all(["Steam" in data, not "_NET_WM_STATE_HIDDEN" in data]):
subprocess.Popen(["xdotool", "windowminimize", w])
except (IndexError, subprocess.CalledProcessError):
pass
t += 1
time.sleep(1)
runsteam_minimized.py
Komut ile çalıştırın:
python3 /path/to/runsteam_minimized.py
except:
sadece Yok dönmek için yakalamak olmaz . Muhtemelen daha iyi başarısız olmasına izin verin, böylece neyin başarısız olduğunu göreceksiniz; Aksi takdirde, her türlü farklı nedenden dolayı kırılabilir ve reklamsız olarak geçer.
subprocess.CalledProcesError
( bir hata sonucu wmctrl
) ve IndexError
(normal istisna) bir dakika içinde düzenlenir :).
Kullanıcı72216 ve Sergey tarafından soruna genel çözümler olarak verilen komut dosyalarına sahip olmak iyidir, ancak bazen en aza indirmek istediğiniz uygulamanın zaten istediğiniz şeyi yapacak bir anahtarı vardır.
İlgili başlangıç programı komut dizelerine sahip birkaç örnek:
-startintray
seçeneği vardır:<path-to-Telegram>/Telegram -startintray
-silent
seçeneğe sahiptir:/usr/bin/steam %U -silent
--minimized
seçeneği vardır:/usr/bin/transmission-gtk --minimized
Unity'de bu uygulamalar, başlatıcıdaki simgeler yerine üst menü çubuğunda simgeler olarak simge durumuna küçültülür, ancak uygulamayı kullanmaya başladığınızda normal başlatma simgesi görünmeye devam eder. Diğer uygulamalar farklı davranabilir.
Jacob'un senaryolarını aldım ve daha evrensel bir senaryo oluşturmak için biraz değiştirdim.
#!/usr/bin/python
import os
import subprocess
import sys
import time
import signal
WAIT_TIME = 10
def check_exist(name):
return subprocess.Popen("which "+name,
shell=True,
stdout=subprocess.PIPE
).stdout.read().rstrip("-n")
def killpid(pidlist):
for pid in pidlist:
args = ["xdotool",
"search",
"--any",
"--pid",
pid,
"--name",
"notarealprogramname",
"windowunmap",
"--sync",
"%@"]
subprocess.Popen(args)
def killname(name):
args = ["xdotool",
"search",
"--any",
"--name",
"--class",
"--classname",
name,
"windowunmap",
"--sync",
"%@"]
subprocess.Popen(args)
sys.argv.pop(0)
if check_exist(sys.argv[0]) == "":
sys.exit(1)
if check_exist("xdotool") == "":
sys.stderr.write("xdotool is not installed\n")
sys.exit(1)
if check_exist("wmctrl") == "":
sys.stderr.write("wmctrl is not installed\n")
sys.exit(1)
try:
prog = subprocess.Popen(sys.argv, preexec_fn=os.setsid)
except OSError, e:
sys.exit(1)
time.sleep(WAIT_TIME)
idlist = subprocess.Popen("pgrep -g " + str(prog.pid),
shell=True,
stdout=subprocess.PIPE
).stdout.read().splitlines()
ps1 = os.fork()
if ps1 > 0:
ps2 = os.fork()
if ps1 == 0: # Child 1
os.setpgid(os.getpid(), os.getpid())
killpid(idlist)
sys.exit(0)
elif ps2 == 0: # Child 2
killname(os.path.basename(sys.argv[0]))
sys.exit(0)
elif ps1 > 0 and ps2 > 0: # Parent
time.sleep(WAIT_TIME)
os.killpg(os.getpgid(int(ps1)), signal.SIGTERM)
os.kill(ps2, signal.SIGTERM)
os.waitpid(ps1, 0)
os.waitpid(ps2, 0)
sys.exit(0)
else:
exit(1)
Temel farklar:
WAIT_TIME, programın alt süreçlerini çatallamasına izin verecek kadar büyük ayarlanmalıdır. Bilgisayarımda buhar gibi büyük programlar için yeterli. Gerekirse artırın.
İlave
xdotool
seçeneği windowunmap
bazı uygulamalarda ve tepsi programlarında (örneğin linux nane tepsisi) korkak çalışabilir, bu nedenle bu istisnalar için komut dosyasının alternatif bir sürümü.
#!/usr/bin/python
import os
import subprocess
import sys
import time
import signal
WAIT_TIME = 10
def check_exist(name):
return subprocess.Popen("which "+name,
shell=True,
stdout=subprocess.PIPE
).stdout.read().rstrip("-n")
def killpid(pidlist):
for pid in pidlist:
args = ["xdotool",
"search",
"--sync",
"--pid",
pid]
for i in subprocess.Popen(args,
stdout=subprocess.PIPE).\
stdout.read().splitlines():
if i != "":
subprocess.Popen("wmctrl -i -c " +
hex(int(i)), shell=True)
def killname(name):
args = ["xdotool",
"search",
"--sync",
"--any",
"--name",
"--class",
"--classname",
name]
for i in subprocess.Popen(args,
preexec_fn=os.setsid,
stdout=subprocess.PIPE)\
.stdout.read().splitlines():
if i != "":
subprocess.Popen("wmctrl -i -c " + hex(int(i)),
shell=True)
sys.argv.pop(0)
if check_exist(sys.argv[0]) == "":
sys.exit(1)
if check_exist("xdotool") == "":
sys.stderr.write("xdotool is not installed\n")
sys.exit(1)
if check_exist("wmctrl") == "":
sys.stderr.write("wmctrl is not installed\n")
sys.exit(1)
try:
prog = subprocess.Popen(sys.argv, preexec_fn=os.setsid)
except OSError, e:
sys.exit(1)
time.sleep(WAIT_TIME)
idlist = subprocess.Popen("pgrep -g " + str(prog.pid),
shell=True,
stdout=subprocess.PIPE
).stdout.read().splitlines()
ps1 = os.fork()
if ps1 > 0:
ps2 = os.fork()
if ps1 == 0: # Child 1
os.setpgid(os.getpid(), os.getpid())
killpid(idlist)
sys.exit(0)
elif ps2 == 0: # Child 2
killname(os.path.basename(sys.argv[0]))
sys.exit(0)
elif ps1 > 0 and ps2 > 0: # Parent
time.sleep(WAIT_TIME)
os.killpg(os.getpgid(int(ps1)), signal.SIGTERM)
os.kill(ps2, signal.SIGTERM)
os.waitpid(ps1, 0)
os.waitpid(ps2, 0)
sys.exit(0)
else:
exit(1)
startminimized
. Sonra koştum startminimized gnome-calendar
. Takvim açık ve yayınlanmaya devam ediyor mu?
WAIT_TIME
. Zayıf bilgisayarlar için 40 saniyelik gecikme kullanıyorum. Ayrıca, uygulamayı en aza indirmek için farklı bir komut kullandığı için ikinci komut dosyasını deneyebilirsiniz.
Program tepsiye kapatılıyorsa, aslında başlangıçta program penceresini simge durumuna küçültmek yerine kapatmak isteyebilirsiniz. Böyle bir programa örnek olarak Viber verilebilir. Bu durumda aşağıdaki komut dosyası kullanılabilir start_closed.sh
:
#!/bin/bash
# Check that there is only one input argument
if [[ $# -gt 1 ]]; then
echo "Usage: $0 <program-to-start>"
exit 1
fi
$1 & # Start program passed in first argument
pid=$! # Get PID of last started program
xdotool search --sync --pid $pid | # Wait for window with PID to appear...
xargs wmctrl -i -c # ...and close it
Kullanımı: <path-to-script> <program-to-start>
xdotool
Wayland ile kurulumlarda düzgün çalışmayacağını belirtmek isteyebilirsiniz .
Sadece sörf yapıyordum ve bu soruya rastladım, bu yüzden işletim sisteminizin ne olduğunu merak ediyordum? Bana gelince ben UBUNTU BUDGIE 18.04 LTS kullanıyorum bu yüzden bu işletim sisteminde çok basit.
Sadece menüye gidin
Menüden Budgie Masaüstü Ayarlarına gidin
ve
Masaüstü Ayarından Otomatik Başlat'a gidin
Size "+" eklemenizden 2 seçenek sunar
1. Uygulama Ekle
2. Komut Ekle
Uygulama Ekle'yi seçerek tüm uygulamalar listelenir ve istediğiniz herhangi bir uygulamayı seçin ve bilgisayarınızı başlattığınızda başlar ve simge durumuna küçültülür.
Tepsiye kapalı programlara ihtiyacım vardı, küçültülmedi ve burada yayınlanan tüm komut dosyalarını denedim, çalışanlar, sadece bazı programlar için çalıştı, diğerleri için değil. Bu yüzden çok daha iyi çalışan bir kod yazdım (neredeyse pencerenin göründüğünü görmüyorsunuz, sadece tepsi simgesi, yerel görünüyor) ve denediğim tüm programlar için çalışıyor. Yakup'un esasına dayanıyor. Bu komut dosyasıyla, programa bağlı olarak bir argüman eklemeniz gerekebilir (aşağıya bakın), ancak her zaman benim için çok sayıda programla çalıştı, ayrıca buharla da çalışmalıdır.
Kullanımı:
sudo apt-get install wmctrl xdotool
startup_closed.py
yürütme izinleri olarak kaydedin ve çalıştırınpython3 ./startup_closed.py -c <command to open program>
-splash
veya -hide
deneme yanılma yoluyla. Örneğin: python3 ./startup_closed.py -hide -c teamviewer
veyapython3 ./startup_closed.py -splash -c slack
./startup_closed.py --help
Senaryo:
#!/usr/bin/env python3
import subprocess
import sys
import time
import argparse
import random
parser = argparse.ArgumentParser(description='This script executes a command you specify and closes or hides the window/s that opens from it, leaving only the tray icon. Useful to "open closed to tray" a program. If the program does not have a tray icon then it just gets closed. There is no magic solution to achieve this that works for all the programs, so you may need to tweek a couple of arguments to make it work for your program, a couple of trial and error may be required with the arguments -splash and -hide, you probably will not need the others.')
parser.add_argument("-c", type=str, help="The command to open your program. This parameter is required.", required=True)
parser.add_argument("-splash", help="Does not close the first screen detected. Closes the second window detected. Use in programs that opens an independent splash screen. Otherwise the splash screen gets closed and the program cannot start.", action='store_true', default=False)
parser.add_argument("-hide", help="Hides instead of closing, for you is the same but some programs needs this for the tray icon to appear.", action='store_true', default=False)
parser.add_argument("-skip", type=int, default=0, help='Skips the ammount of windows specified. For example if you set -skip 2 then the first 2 windows that appear from the program will not be affected, use it in programs that opens multiple screens and not all must be closed. The -splash argument just increments by 1 this argument.', required=False)
parser.add_argument("-repeat", type=int, default=1, help='The amount of times the window will be closed or hidden. Default = 1. Use it for programs that opens multiple windows to be closed or hidden.', required=False)
parser.add_argument("-delay", type=float, default=10, help="Delay in seconds to wait before running the application, useful at boot to not choke the computer. Default = 10", required=False)
parser.add_argument("-speed", type=float, default=0.02, help="Delay in seconds to wait between closing attempts, multiple frequent attempts are required because the application may be still loading Default = 0.02", required=False)
args = parser.parse_args()
if args.delay > 0:
finalWaitTime = random.randint(args.delay, args.delay * 2);
print(str(args.delay) + " seconds of delay configured, will wait for: " + str(finalWaitTime))
time.sleep(finalWaitTime)
print("waiting finished, running the application command...")
command_check = args.c.split("/")[-1]
subprocess.Popen(["/bin/bash", "-c", args.c])
hasIndependentSplashScreen = args.splash
onlyHide = args.hide
skip = args.skip
repeatAmmount = args.repeat
speed = args.speed
actionsPerformed = 0
lastWindowId = 0
if hasIndependentSplashScreen:
skip += 1
while True:
try:
w_list = [l.split() for l in subprocess.check_output(["wmctrl", "-lp"]).decode("utf-8").splitlines()]
proc = subprocess.check_output(["pgrep", "-f", command_check]).decode("utf-8").strip().split()
match = sum([[l[0] for l in w_list if p in l] for p in proc], [])
if len(match) > 0:
windowId = match[0]
if windowId != lastWindowId:
if skip > 0:
skip -= 1
print("skipped window: " + windowId)
lastWindowId = windowId
else:
print("new window detected: " + windowId)
if onlyHide:
subprocess.Popen(["xdotool", "windowunmap", windowId])
print("window was hidden: " + windowId)
else:
subprocess.Popen(["xdotool", "key", windowId, "alt+F4"])
print("window was closed: " + windowId)
actionsPerformed += 1
lastWindowId = windowId
if actionsPerformed == repeatAmmount:
break
except (IndexError, subprocess.CalledProcessError):
break
time.sleep(speed)
print("finished")
Sadece zarif bir çözümle geldim xdotool
ve Telegram gibi "minimize edilmiş bir başlangıç" argümanı olmayan uygulamalar için oldukça kullanışlıdır .
Tek dezavantajı, çözümün her uygulama için manuel olarak hazırlanması gerektiğidir, ancak bunun bir sorun olmadığını varsayarsak (örneğin: belirli bir uygulamayı giriş yaptıktan sonra ekranınızı kirletmesine izin vermeden otomatik olarak başlatmak istiyorsanız) , bu çok daha basit ve kolaydır .
## Starts Telegram and immediately closes it
xdotool search --sync --onlyvisible --name '^Telegram$' windowclose &
telegram-desktop &
## Starts WhatsApp and immediately closes it
xdotool search --sync --onlyvisible --name '(\([0-9]*\) ){0,1}(WhatsApp$|WhatsApp Web$)' windowclose &
whatsapp-nativefier &
İlk bakışta, 'PID veya sınıf sürecini eşleşmek için kullanmanın daha iyi olduğunu düşünebilirsiniz, ancak aynı PID için sıklıkla birden fazla sonuç alacağınız için aslında bu ters etki yaratır. Örnek olarak bir bildirim, bir systray simgesi veya başka bir "gizli" pencere bekleyen bir 0x0 penceresi gösterilebilir.
Çözüm, her zaman yalnızca bir benzersiz pencere döndüren bir xdotool komutu hazırlamaktır . --name
Bununla birlikte yapılan her iki --all
örneğimde de, birden fazla seçiciyi (örneğin: verilen bir sınıf adını + bir sınıf adını + bir ad regex ile eşleştirebilirsiniz) birleştirebilirsiniz . Genellikle iyi bir --name
regex hile yapar.
Koşullarınızı hazırladıktan sonra , parametre ve koşullarınızla bir search
xdotool örneği (kabuktan ayrılmış)--sync
ve ardından takip edin windowclose
. Daha sonra uygulamanızı çalıştırın:
xdotool search --sync [... myapp-match-conditions] windowclose &
my-app
xdotool search --help
Tam olarak istediğiniz pencereyi hedefleyebilmek için ayarlayabileceğiniz tüm kombinasyon olanaklarına göz atın . Bazen zorlaşır ve birkaç koşulu birleştirmeniz gerekir, ancak bitirdiğinizde nadiren başarısız olur (bir güncelleme uygulamayı değiştirmediği ve uygulamanızı bozmadığı sürece).