아직 열지 않은 경우에만 앱을 시작하십시오.


16

Mac OS X에서 Alfred의 사용을 모방하고 싶습니다. 여기서 응용 프로그램을 검색 한 후 응용 프로그램을 열려고하면 프로그램이 아직 실행 중이 지 않은 경우 새 창만 열립니다. 그렇지 않으면 현재 해당 응용 프로그램의 인스턴스를 실행 중입니다. 어쨌든 새 창을 열기 전에이를 확인하기 위해 실행기의 기본 동작을 변경해야합니까?


또한 @pidge 이렇게하는 것은 어렵지 않지만 오른쪽 클릭 "Open with"동작에 영향을줍니다. 나는 그것이 받아 들일 수없는 부작용이라고 생각합니다.
Jacob Vlijm

1
특정 프로세스가 이미 실행 중인지 확인하고 새 프로세스를 시작하거나 기존 창에 초점을 둘지 결정할 수있는 스크립트를 작성할 수 있어야한다고 생각합니다. 불행히도, 나는 아직 스크립팅에 능숙하지 않지만 ... @JacobVlijm은 모든 목적을 위해 스크립트를 가진 사람으로 알려져 있습니다. 당신이 그렇게하고 싶거나 할 수 있는지 확실하지 않습니다 – 나는 ...
바이트 사령관

2
스크립트 경로를 사용 하면이 스크립트 를 시작점으로 사용할 수 있습니다 . 처음에는 LXDE / Openbox 용으로 작성했지만 Unity에서도 작동합니다. 스크립트 및 사용법에 대한 자세한 내용은 여기를 참조하십시오 .
Glutanimate

1
@ByteCommander 정확히 그것이 내가 생각한 것입니다. .desktop파일 의 명령을 스크립트로 바꿀 수도 있습니다. .desktop그러나 파일 에서 명령을 바꾸면 마우스 오른쪽 단추로 열기 옵션이 손상됩니다.
Jacob Vlijm

1
어떤 데스크탑 환경에 적합합니까?
j0h

답변:


6

4 월 7 일 업데이트 : 다른 버전이 추가되어 Albert를 찾았습니다. 업데이트 및 보너스 벨로우즈 참조!

대시 기능 관련 : " 새 창을 열기 전에이를 확인하기 위해 실행기의 기본 동작을 변경 하시겠습니까? " 기본 답변은 일반 사용자로서 해당 동작을 대시에 추가 할 수있는 방법이 없다는 것입니다. 그러나 그것을 구현할 의지가있는 단일 범위 개발자가 있다면, 해결하고 배우고 자한다면 그들에게 다가 가거나 직접 개발할 수 있습니다. 코딩 기술은 매우 겸손하므로 셸 스크립팅과 스크립트에 사용 가능한 그래픽 프런트 엔드를 해결 방법으로 사용합니다.

관련 정보

원본 게시물 :

나는 당신이 요구 한 것을 달성하기 위해 zenity dialogue와 wmctrl을 사용하는 스크립트를 작성했습니다. 이 스크립트는 GUI에서 Windows에서만 작동하며 tty에서 무언가를 실행하려고하면 작동하지 않는 그래픽 스크립트입니다. 게다가 알프레드가 이해 한 것에서 정확히 같은 일을합니다. 여기여기에 설명 된대로 바탕 화면 바로 가기 또는 바탕 화면 바로 가기를 만들 수 있습니다 .

스크립트 :

#!/bin/bash
# Author: Serg Kolo
# Description: A launcher script that checks whether
#       or not a window of a particular program already exists
#       If a window of such program is open, bring it to focus
#       Otherwise - launch a new window
#       Written for /ubuntu//q/440142/295286
# Date: April 6 , 2015
#


MYPROG=$( zenity --entry --title='MY LAUNCHER' --text='Type the name of application to run' )
sleep 0.5
wmctrl -lx | awk '{print $3}' | grep -i "$MYPROG"

if [ $? -eq 0 ]; then
    sleep 1         
    wmctrl -xa $MYPROG
   #as an alternative try the line bellow
   #wmctrl -a $MYPROG
    exit 1
else 
    $MYPROG &
    exit 0
fi

참고 사항 : 이전 버전에서 스크립트는 echo $?를 사용하여 이전 표현식이 성공적으로 종료되었는지 테스트했습니다. muru의 제안 (edit에서)에 따라 코드를 좀 더 컴팩트 한 버전으로 변경 했으므로 이전 버전과 현재를 살펴 보는 것이 좋습니다.

또한 이전 wmctrl -a $MYPROG에는 google-chrome 또는 크롬 브라우저 테스트와 작동하지 않았습니다. 어리석은 이유로 일부 프로그램에는 대문자로 된 WM_CLASS 속성이 대문자로 표시되어 있지만 나열된 프로그램 dpkg --get-selections은 소문자입니다 (읽고 man wmctrl실행 wmctrl -lx하면 알 수 있습니다). -ax를 추가하면이 문제를 해결해야합니다. 스크립트는 이미 열려있는 크롬 창을 불러옵니다.

또 다른 것은-wmctlr은 때로는 지연이 필요하다는 점에서 다소 이상합니다 (다른 스크립트에서 경험이 있었기 때문에) sleep 1. 이전에는 파이어 폭스와 함께 일종의 켜기 및 끄기가되었지만 이제는 수영으로 작동합니다.

작동중인 스크립트

애니메이션 아래에서 스크립트를 처음 실행할 때 파이어 폭스 인스턴스가 하나 열리고 스크립트 스위치가 해당 창으로 초점을 맞춘다는 것을 알 수 있습니다. 두 번째 테스트에서는 이전에 열지 않은 google-chrome의 새 인스턴스를 엽니 다. (Side note : 데스크탑에 대해 마음에 들지 않으면 cairo dock이있는 Openbox입니다)

주석에서 제안에 따라 포함 된 애니메이션이 제거되고 게시 된 링크 만 있습니다. 고장난 경우 신고하십시오! http://i.stack.imgur.com/puuPZ.gif

4 월 7 일 업데이트

나는 zenity의 드롭 다운 항목 상자에 나열된 모든 프로그램을 만들기 위해 스크립트를 다소 개선했습니다. 이제 사용자는 각 프로그램을 기억할 필요는 없지만 화살표 키를 사용하여 목록을 스크롤하거나 드롭 다운 메뉴를 열면됩니다. 또한이 개선 된 버전은 이름이 아니라 창 ID별로 창을 표시하므로 성능이 훨씬 향상됩니다. .desktop 파일을 통과하는 방식은 cut 명령을 두 번 사용하여 중복되는 것이지만 지금까지는 스크립트가 좋지 않기 때문에 이것이 내가 할 수있는 전부입니다. 개선을위한 제안은 환영합니다!

#!/bin/bash
# Author: Serg Kolo
# Description: Second version of a launcher script that checks whether
#       or not a window of a particular program already exists
#       If a window of such program is open, bring it to focus
#       Otherwise - launch a new window
#       Written for /ubuntu//q/440142/295286
# Date: April 7 , 2015
#

set -x

MYPROG=$(zenity --entry --text 'Select program from list' --entry-text $(ls /usr/share/applications/*.desktop | cut -d'/' -f5 | cut -d'.' -f1 | xargs echo))
sleep 0.5
# Do we have a window of such program ?
wmctrl -lx| awk '{print $3}'  | grep -i $MYPROG

if [ $? -eq 0 ]; then
    sleep 0.5 # if yes, find that window id, and raise it
    WINID=$(wmctrl -lx | grep -i $MYPROG | awk 'NR==1{print $1}')
    wmctrl -ia $WINID &
 #  exit 0  
else
    echo $MYPROG | grep -i libreoffice
    if [ $? -eq 0  ]
    then
        MYPROG=$(echo $MYPROG | sed 's/-/ --/g')
    fi
    $MYPROG &

#  exit 0 
fi

여기에 이미지 설명을 입력하십시오

보너스:

실제로 Alfred의 Linux 버전 인 Albert를 찾았 지만 직접 시도하지는 않았습니다. 그래도 체크 아웃 할 가치가 있습니다. 그러나 야곱이 이미 지적했듯이 여전히 버그가 있습니다.

Gnome-Do라는 앱이 있는데,이 그래픽은 Alfred와 비슷하게 보이지만이 스크립트와 기능이 다릅니다.

여기에 이미지 설명을 입력하십시오

이 스크립트가 마음에 든다면 수정해야 할 것이 있으면 알려주십시오. 유용하다고 생각되면 답을 올리는 것을 잊지 마십시오.


그건 그렇고, 내가 프로그램 이름을 어떻게 입력하는지에 주목하십시오 dpkg --get-selectons. "writer"를 입력하여 libreoffice Writer를 시작하면 작동하지 않지만 ~ / bin, / bin 또는 / usr / bin 폴더에서 해당 파일에 대한 심볼릭 링크를 만들거나 .bashrc 또는 .profile에서 별칭을 사용할 수 있습니다.
Sergiy Kolodyazhnyy

또한 wmctl을 설치해야합니다. 기본적으로 제공되지는 않지만 매우 편리합니다. 또한 만들기 위해 사용했습니다
세르지 Kolodyazhnyy

애니메이션에 연결하여 애니메이션을 이미지로 대체 할 수 있습니까? 브라우저가 계속 페이지를 "로드"하므로 새로 고침 할 수 없습니다. (그리고 애니메이션은 실행되지 않습니다 :)
Jacob Vlijm

감사! 링크는 Firefox가 아닌 Chrome에서 제대로 작동합니다.
Jacob Vlijm

@JacobVlijm Ugh, 그래. 왜 파이어 폭스가 그것을 거부하고 있는지 잘 모르겠습니다. 그것은 내가 원래 업로드 한 것에 대한 이미지 링크입니다
Sergiy Kolodyazhnyy

5

1. 두 번째 대쉬

질문에 설명 된대로 응용 프로그램을 실행할 때 Dash의 대안으로 사용할 수있는 스크립트 아래.

Dash와 동일한 기능을 가진 창이 있습니다. 응용 프로그램의 문자를 하나 이상 입력하면 응용 프로그램이 목록에 나타납니다. 를 눌러 Enter시작하거나 이미 실행 중이거나하지 않은 경우에 따라 응용 프로그램을 올리는 중 하나.

바로 가기 키 조합에서 호출하거나 런처의 아이콘을 설정하여 대시와 비슷하게 사용하거나 (아래 참조) 둘 다 사용할 수 있습니다.

여기에 이미지 설명을 입력하십시오

스크립트

#!/usr/bin/env python3
import subprocess
import os
import getpass
import time

user = getpass.getuser()
get = lambda x: subprocess.check_output(["/bin/bash", "-c", x]).decode("utf-8")
skip = ["%F", "%U", "%f", "%u"]; trim = ["chrome", "chromium", "nautilus"]

def apply(command):
    if "libreoffice" in command:
        proc = [l.split()[0] for l in get("ps -u "+user).splitlines() if "soffice.bin" in l]
        module = command.split("--")[-1]
        time.sleep(0.1)
        try:
            ws = sum([[w.split()[0] for w in get("wmctrl -lp").splitlines() if process in w and module in w.lower()] for process in proc], [])[0]
            subprocess.call(["wmctrl", "-ia", ws])
        except IndexError:
            subprocess.Popen(["/bin/bash", "-c", command+"&"])
    else:
        check = command.split("/")[-1][:14]
        proc = [p.split()[0] for p in get("ps -u "+user).splitlines() if check in p]
        time.sleep(0.5)
        try:
            ws = sum([[w.split()[0] for w in get("wmctrl -lp").splitlines() if process in w] for process in proc], [])
            if command == "nautilus":
                real_window = [w for w in ws if "_NET_WM_WINDOW_TYPE_NORMAL" in get("xprop -id "+w)][0]
            else:
                real_window = ws[0]
            subprocess.call(["wmctrl", "-ia", real_window])
        except IndexError:
            subprocess.Popen(["/bin/bash", "-c", command+"&"])
# default directories of .desktop files; globally, locally, LibreOffice- specific when separately installed
globally = "/usr/share/applications"; locally = os.environ["HOME"]+"/.local/share/applications"; lo_dir = "/opt/libreoffice4.4/share/xdg"
# create list of .desktop files; local ones have preference
local_files = [it for it in os.listdir(locally) if it.endswith(".desktop")]
global_files = [it for it in os.listdir(globally) if it.endswith(".desktop")]
lo_spec = [it for it in os.listdir(lo_dir) if it.endswith(".desktop")] if os.path.exists(lo_dir) else []
for f in [f for f in local_files if f in global_files]:
    global_files.remove(f)
for f in [f for f in local_files if f in lo_spec]:
    lo_spec.remove(f)
dtfiles = [globally+"/"+f for f in global_files]+[locally+"/"+f for f in local_files]+[lo_dir+"/"+f for f in lo_spec]
# create list of application names / commands
valid = []
for f in dtfiles:
    content = open(f).read()
    if all(["NoDisplay=true" not in content,"Exec=" in content]):
        lines = content.splitlines()
        name = [l.replace("Name=", "") for l in lines if "Name=" in l][0]
        command = [l.replace("Exec=", "") for l in lines if all(["Exec=" in l, not "TryExec=" in l])][0]
        valid.append((name, command))
valid.sort(key=lambda x: x[0])
# create zenity list + window
list_items = '"'+'" "'.join([f[0] for f in valid])+'"'
proposed = 'zenity --list --text "Type one or more characters... " --column="Application List" '+\
           '--title="Dash the Second" --height 450 --width 300 '+list_items
try:
    choice = subprocess.check_output(["/bin/bash", "-c", proposed]).decode("utf-8").strip().split("|")[0]
    command = [r[1] for r in valid if r[0] == choice][0]
    # command fixes:
    for s in skip:
        command = command.replace(" "+s, "")
    for t in trim:
        if t in command:
            command = t
    apply(command)
except subprocess.CalledProcessError:
    pass

사용하는 방법

스크립트가 wmctrl설치되어 있어야합니다.

sudo apt-get install wmctrl

그때:

  1. 위의 스크립트를 빈 파일에 붙여 넣고 다른 이름으로 저장하십시오. dash_alternative.py
  2. 바로 가기 키 조합에 추가하십시오 : 시스템 설정> "키보드"> "바로 가기"> "사용자 정의 바로 가기"를 선택하십시오. "+"를 클릭하고 다음 명령을 추가하십시오.

    python3 /path/to/dash_alternative.py
    

설명

스크립트가 실행되면로 표시된 모든 응용 프로그램이 나열됩니다 /usr/share/applications. .dektop파일을 검색하여 모든 첫 번째 "Name ="줄에서 모든 응용 프로그램 이름 목록과 첫 번째 "Exec ="줄에서 응용 프로그램을 실행하는 명령을 만듭니다.

그 후 모든 응용 프로그램을 정렬 된 방식으로 표시하는 Zenity 목록이 작성됩니다.

응용 프로그램을 선택할 때마다 스크립트는 응용 프로그램이 실행중인 경우 실행중인 프로세스 목록을 찾습니다. 그렇다면 해당 창이 올라갑니다. 그렇지 않은 경우 새 인스턴스가 열립니다.

노트

  1. 12.04에 스크립트를 실행하려면 (원래 질문에 태그가 붙어 있기 때문에 12.04단순히 shebang을 다음으로 변경 #!/usr/bin/env python하고 명령으로 실행하십시오.

    python /path/to/dash_alternative.py
    
  2. 내가 테스트 한 한 스크립트는 정상적으로 작동합니다. 명령 및 해당 프로세스가 아닌 프로세스 이름 (예 : LibreOffice<> soffice.bin), 다른 창 유형 ( nautilus"실제"창 외에 여러 창 유형이 있음), 응용 프로그램 당 여러 pid ( Chromium, Google-chrome)는 예외를 유발할 수 있습니다. 위. 누군가 문제가 발생하면 언급하십시오.

2. 추가 : 응용 프로그램 실행을위한 "실제"대시의 대안으로 설정

  1. 위에서 언급 한대로 스크립트를 복사하고 안전하게
  2. 아래 아이콘을 다음과 같이 저장하십시오 (오른쪽 클릭> 다른 이름으로 안전). dash_alternative.png

    여기에 이미지 설명을 입력하십시오

  3. 빈 파일에 아래의 코드를 복사에 저장 ~/.local/share/applicationsdash_thesecond.desktop. /path/to/dash_alternative.py(스크립트) 및 /path/to/dash_alternative.png(아이콘) 의 올바른 경로를 설정하십시오.

    [Desktop Entry]
    Name=Dash the Second
    Exec=python3 /path/to/dash_alternative.py
    Icon=/path/to/dash_alternative.png
    Type=Application
    Hidden=false
    
  4. .desktop파일을 실행기로 드래그하십시오 .


1
.desktop 파일의 전체 폴더가 있다는 것을 알고 반갑습니다! 네이티브 및 적절한 설치 응용 프로그램이 명령 대신 이름으로 나열되는 방법이 궁금합니다. 잘 했어!
Sergiy Kolodyazhnyy

@Serg 감사합니다! 그리고 당신에게 동일 :). .desktop파일 의 로컬 디렉토리도 있습니다 ~/.local/share/applications.. 전 세계적으로 설치된 응용 프로그램으로 검색을 제한한다고 생각했습니다.
Jacob Vlijm

제이콥, 나는 파이썬을 모른다. 그러나 이것은 아마도 스크립트를 단일 범위로 바꾸어 스크립트를 향상시키는 데 유용 할 것이다. 제 이해는 이것이 OP가 원하는 방식으로 대시 기능을 변경하는 유일한 방법이라는 것입니다
Sergiy Kolodyazhnyy

@Serg 감사합니다! 그것은 흥미로운 게시물입니다, 확실히 그것을 잘 볼 것입니다!
Jacob Vlijm

0

를 들어 실행기 가 작업 스위칭 인터페이스로 (화면의 왼쪽에 수직 패널)이 이미 기본 동작입니다.

를 들어 대시 (당신이 우분투 로고를 클릭하면 열리는 큰 비트), 소스 코드 자체에 아마도 큰 수정없이,이 방식으로 동작을 변경할 수있는 방법이 없습니다.

그러나 일부 앱은 이러한 방식으로 작동하도록 설계되었으므로 이미이 작업을 수행 할 수 있습니다. 그러나 모든 앱이 반드시 그런 식으로 구현되는 것은 아니며 반드시 그런 것은 아닙니다.

그러나 다른 기능으로 Super+ 를 사용하여 창을 열고 W응용 프로그램 이름을 입력하기 시작하면 해당 응용 프로그램 의 창만 표시됩니다.


실제로 OP가 원하는 Linux 버전을 찾았습니다. 내 게시물, 보너스 섹션을 참조하십시오. 다른 사람이 알프레드를 리눅스로 데려 올 생각을 가지고 있었다
Sergiy Kolodyazhnyy

1
@ Serg는 Albert를 사용해보십시오. Albert는 여전히 "LibreOffice 버그", "Chromium 버그"및 "Chrome 버그"를 가지고 있습니다. "파일 버그"조차도 알버트는 항상 이러한 응용 프로그램의 새 인스턴스를 엽니 다. LibreOffice는 전혀 작동하지 않습니다. 또한 링크 아래의 주석에서 여러 가지 문제를 찾을 수 있습니다.
Jacob Vlijm

@Serg 아니요, 백그라운드에서 실행되는 추가 소프트웨어를 추가하여 해결 방법을 찾았습니다. 이는 완전히 다른 사용자 경험을 제공하고 응용 프로그램을 찾는 방법을 재교육해야합니다. 질문은 Unity 대시 에서이 작업을 수행하는 방법이었습니다. Unity 외부에서 유사한 기능을 사용할 수 있지만 Unity를 변경하는 유일한 방법은 소스 코드를 변경하는 것입니다.
dobey April

@dobey 글쎄, 그건 사실이다; 대시 기능 변경은 우리의 범위를 벗어납니다. . .gotta는 우리가 사용할 수있는 것과 관련이 있습니다. 그러한 기능으로 단일 범위를 기꺼이 코딩하려는 개발자가 없다면. . .
Sergiy Kolodyazhnyy
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.