Saya hanya ingin Telegram dijalankan dan saya telah menambahkannya ke aplikasi startup. Intinya adalah bahwa saya perlu diminimalkan. Ada perintah?
Saya hanya ingin Telegram dijalankan dan saya telah menambahkannya ke aplikasi startup. Intinya adalah bahwa saya perlu diminimalkan. Ada perintah?
Jawaban:
Memulai aplikasi dengan cara yang diminimalkan membutuhkan dua perintah:
Oleh karena itu, perintah atau skrip harus "pintar"; perintah kedua harus menunggu jendela aplikasi muncul.
Script di bawah ini melakukan itu dan dapat digunakan sebagai solusi umum untuk memulai aplikasi dengan cara yang diminimalkan. Jalankan saja di sintaks:
<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
Script membutuhkan keduanya wmctrl
dan xdotool
:
sudo apt-get install wmctrl xdotool
Kemudian:
startup_minimizd.py
Tes-jalankan skrip dengan (misalnya) gedit
perintah:
python3 /path/to/startup_minimizd.py gedit gedit
Startup Applications
wmctrl
) untuk windows, dinamai argumen kedua Anda.xdotool
Untuk mencegah perulangan tanpa akhir jika jendela mungkin tidak muncul karena suatu alasan, skrip mempraktikkan batas waktu 30 detik agar jendela muncul.Tidak perlu menyebutkan bahwa Anda dapat menggunakan skrip untuk beberapa aplikasi sekaligus, karena Anda menjalankannya dengan argumen di luar skrip.
Jika judul jendela tidak pasti atau variabel, atau ada risiko bentrokan nama dalam nama jendela, menggunakan pid
adalah metode yang lebih dapat diandalkan untuk digunakan.
Script di bawah ini didasarkan pada penggunaan pid aplikasi, seperti pada output keduanya wmctrl -lp
danps -ef
.
Pengaturannya hampir sama, tetapi judul jendela tidak diperlukan dalam versi ini, jadi perintah untuk menjalankannya adalah:
python3 /path/to/startup_minimizd.py <command_to_run_application>
Sama seperti skrip pertama, ia membutuhkan keduanya wmctrl
danxdotool
#!/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)
Meskipun secara umum versi kedua harus lebih dapat diandalkan, dalam kasus ketika aplikasi dimulai oleh skrip wrapper, pid dari perintah akan berbeda dari aplikasi yang akhirnya dipanggil.
Dalam kasus seperti itu, saya sarankan menggunakan skrip pertama.
Seperti yang diminta dalam komentar, di bawah versi, khusus dibuat untuk memulai STEAM diminimalkan.
Ternyata Steam
berperilaku sangat berbeda dari aplikasi "normal":
Steam
tidak menjalankan satu pid, tetapi tidak kurang dari (dalam pengujian saya) delapan!Steam
berjalan saat memulai dengan setidaknya dua jendela (satu jendela seperti splash), tetapi terkadang jendela pesan tambahan muncul.pid 0
, yang merupakan masalah dalam skrip seperti itu.Perilaku luar biasa ini Steam
meminta versi khusus dari skrip, yang ditambahkan di bawah ini. Script dimulai Steam
, dan selama 12 detik, itu mengawasi semua jendela baru yang sesuai WM_CLASS
, memeriksa apakah mereka diminimalkan. Jika tidak, skrip akan memastikannya.
Seperti skrip asli, yang ini perlu wmctrl
dan xdotool
harus diinstal.
#!/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
Jalankan dengan perintah:
python3 /path/to/runsteam_minimized.py
except:
hanya untuk mengembalikan Tidak ada. Mungkin lebih baik membiarkannya gagal sehingga Anda melihat apa yang gagal; jika tidak, itu dapat rusak untuk segala jenis penyebab yang berbeda dan akan berlalu tanpa iklan.
subprocess.CalledProcesError
(sebagai hasil dari kereta wmctrl
) dan IndexError
(pengecualian normal) akan diedit dalam satu menit :). Terima kasih telah menyebutkan
Ada baiknya memiliki skrip yang diberikan oleh user72216 dan Sergey sebagai solusi umum untuk masalah ini, tetapi kadang-kadang aplikasi yang Anda ingin mulai diminimalkan sudah memiliki sakelar yang akan melakukan apa yang Anda inginkan.
Berikut adalah beberapa contoh dengan string perintah program startup yang sesuai:
-startintray
opsi:<path-to-Telegram>/Telegram -startintray
-silent
opsi:/usr/bin/steam %U -silent
--minimized
opsi:/usr/bin/transmission-gtk --minimized
Di Unity aplikasi ini mulai diminimalkan sebagai ikon di bilah menu atas daripada sebagai ikon pada peluncur, meskipun ikon peluncuran normal akan tetap muncul setelah Anda mulai menggunakan aplikasi. Aplikasi lain mungkin berperilaku berbeda.
Saya mengambil skrip Jacob dan memodifikasinya sedikit untuk membuatnya lebih universal.
#!/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)
Perbedaan utama adalah:
WAIT_TIME harus disetel cukup besar untuk memungkinkan program memotong proses anaknya. Di komputer saya itu sudah cukup untuk program besar seperti steam. Tingkatkan itu, jika perlu.
Tambahan
xdotool
Opsi windowunmap
dapat berfungsi funky dengan beberapa aplikasi dan program baki (misalnya baki linux mint), jadi inilah versi alternatif dari skrip untuk pengecualian tersebut.
#!/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
. Lalu aku berlari startminimized gnome-calendar
. Kalender terbuka dan terus berjalan?
WAIT_TIME
. Saya menggunakan penundaan 40 detik untuk komputer yang lemah. Anda juga dapat mencoba skrip kedua karena menggunakan perintah yang berbeda untuk meminimalkan aplikasi.
Jika program sedang ditutup ke baki, orang mungkin benar-benar ingin menutup jendela program saat startup daripada meminimalkannya. Salah satu contoh program tersebut adalah Viber. Dalam hal ini orang dapat menggunakan skrip berikut 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
Pemakaian: <path-to-script> <program-to-start>
xdotool
tidak akan berfungsi dengan baik pada instalasi dengan Wayland.
Saya baru saja menjelajahi dan menemukan pertanyaan ini, jadi saya hanya ingin tahu apa sistem operasi Anda? Sedangkan saya, saya menggunakan UBUNTU BUDGIE 18.04 LTS sehingga dalam sistem operasi ini sangat sederhana.
Cukup buka menu
Dari Menu, buka Pengaturan Desktop Budgie
dan
Dari Pengaturan Desktop pergi ke Auto Start
Ini akan memberi Anda 2 opsi, dari "+" tambah
1. Tambahkan Aplikasi
2. Tambahkan Perintah
Dengan memilih Tambahkan Aplikasi, semua aplikasi akan terdaftar, pilih aplikasi apa pun yang Anda inginkan dan itu akan mulai ketika Anda memulai komputer Anda dan itu juga akan diminimalkan.
Saya membutuhkan program yang tertutup untuk nampan, tidak diperkecil, dan saya sudah mencoba semua skrip yang diposting di sini, yang bekerja, hanya bekerja untuk beberapa program dan tidak untuk yang lain. Jadi saya telah membuat kode yang berfungsi lebih baik (Anda hampir tidak melihat jendela yang muncul, hanya ikon baki, yang terlihat asli) dan berfungsi untuk semua program yang saya coba. Ini didasarkan pada milik Yakub. Dengan skrip ini Anda mungkin perlu menambahkan argumen tergantung pada programnya (lihat di bawah) tetapi selalu bekerja untuk saya dengan banyak program itu juga harus bekerja dengan uap.
Pemakaian:
sudo apt-get install wmctrl xdotool
startup_closed.py
memberikan izin eksekusi dan kemudian jalankanpython3 ./startup_closed.py -c <command to open program>
-splash
atau -hide
, dengan coba-coba. Misalnya: python3 ./startup_closed.py -hide -c teamviewer
ataupython3 ./startup_closed.py -splash -c slack
./startup_closed.py --help
Naskah:
#!/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")
Saya datang dengan solusi yang agak elegan yang hanya mengandalkan xdotool
, dan ini cukup berguna untuk aplikasi yang tidak memiliki argumen "mulai diminimalkan" , seperti Telegram.
Satu-satunya downside adalah bahwa solusi harus dibuat secara manual untuk setiap aplikasi, tetapi dengan asumsi itu bukan masalah (misalnya: jika Anda ingin melakukan autostart aplikasi tertentu tanpa membiarkannya mencemari layar Anda setelah masuk) , ini jauh lebih sederhana dan mudah. .
## 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 &
Pada pandangan pertama, Anda mungkin berpikir lebih baik menggunakan proses 'PID atau kelas untuk mencocokkan, namun itu sebenarnya kontraproduktif karena Anda sering akan mendapatkan beberapa hasil untuk PID yang sama. Contohnya adalah jendela 0x0 yang sebenarnya menunggu pemberitahuan, ikon systray, atau jendela "tersembunyi" lainnya.
Solusinya adalah membuat perintah xdotool yang selalu mengembalikan hanya satu jendela unik . Dalam kedua contoh saya yang dilakukan menggunakan --name
, namun Anda dapat menggabungkan beberapa penyeleksi dengan --all
(misalnya: cocok dengan nama kelas yang diberikan + nama kelas + nama regex) . Biasanya --name
regex yang baik berhasil .
Setelah menyusun search
kondisi Anda , cukup buat instance xdotool (terlepas dari shell) dengan --sync
parameter dan kondisi Anda, diikuti oleh windowclose
. Jalankan aplikasi Anda setelahnya:
xdotool search --sync [... myapp-match-conditions] windowclose &
my-app
Periksa
xdotool search --help
semua kemungkinan kombinasi yang dapat Anda atur untuk dapat menargetkan jendela yang tepat yang Anda inginkan. Kadang-kadang itu menjadi rumit dan Anda harus menggabungkan beberapa kondisi, tetapi begitu Anda selesai, jarang akan gagal (kecuali pembaruan mengubah aplikasi dan menghancurkan implementasi Anda, tentu saja).