Pano kaynağını (uygulamasını) bilmek mümkün mü?


10

Kaynak uygulama (içeriğin kopyalandığı yer) kapatıldığında bazen pano içeriğinin kullanılamayacağını fark ettim.

Bu beni kaynak uygulamanın ne olduğunu bilmek mümkün olup olmadığını merak (örneğin belki PID tarafından).

Neden? Kaynak uygulama bir terminal ise, kopyalanan içeriğin göreli bir yol olması durumunda, bir dosyaya tam yol oluşturmak için terminalin çalışma dizinini bulmak istiyorum.

Bilginize, şu anda pano içeriğini belirlemek için xclip kullanıyorum, örn.

xclip -selection primary -t STRING -o 2> /dev/null

2
XGetSelectionOwner(3)size seçimin sahibinin pencere kimliğini alır. Örneğin, _NET_WM_PID özelliğine sahip bir pencere bulmaya çalışmak için pencere ağacında yürüyebilirsiniz xprop(bu pencerenin bu özelliği ayarlayan yerel bir istemciden geldiğini varsayarak). xwininfo -root -tree | less +/0x<that-id>uygulamayı tanımlamak için yeterli olabilir.
Stéphane Chazelas

2
@ StéphaneChazelas ne dedi. Ancak, X11'den diğer istemcinin güvenilir bir PID'sini almanın olası olmadığını unutmayın. X istemcilerinin X sunucularına genel ağ bağlantıları (UNIX soketi veya TCP soketi) ile bağlandığını unutmayın, uygulama yerel olmayabilir. TCP (bu günlerde artık yaygın değil) veya SSH iletimli X11 bağlantısı (daha yaygın) üzerinden bağlanmış olabilir.
Celada

Notlar için teşekkürler - XGetSelectionOwner'a erişmek için biraz C kodu yazmam gerektiğini varsayalım? Muhtemelen bunu yapabilirim - bir çözüme ulaştığımda geri göndereceğim.
Jeff Ward

Yanıtlar:


5

Düz uygulama adını döndüren bir araç yazdım (örn. Test ettiğim 'Terminal', 'gedit' veya 'SmartGit'). Çoğu kod utanmadan burada @Harvey çalınmıştır .

// gcc clipboard-owner.c -lX11 -o clipboard-owner

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>

#define MAX_PROPERTY_VALUE_LEN 4096

typedef unsigned long ulong;

static char *get_property(Display *, Window, Atom , const char *, ulong *);

int main(void)
{
  // Open the Display
  Display *display = XOpenDisplay(NULL);

  // Get the selection window
  Window selection_owner = XGetSelectionOwner(display, XA_PRIMARY);

  if(!selection_owner) {
    exit(0);
  } else {
      char *window_name = get_property(display, selection_owner, XA_STRING, "WM_NAME", NULL);
      printf("%s\n", window_name);
  }

  XCloseDisplay(display);
}

static char *get_property (Display *disp, Window win,
        Atom xa_prop_type, const char *prop_name, ulong *size) {
    Atom xa_prop_name;
    Atom xa_ret_type;
    int ret_format;
    ulong ret_nitems;
    ulong ret_bytes_after;
    ulong tmp_size;
    unsigned char *ret_prop;
    char *ret;

    xa_prop_name = XInternAtom(disp, prop_name, False);

    if (XGetWindowProperty(disp, win, xa_prop_name, 0,
            MAX_PROPERTY_VALUE_LEN / 4, False,
            xa_prop_type, &xa_ret_type, &ret_format,     
            &ret_nitems, &ret_bytes_after, &ret_prop) != Success) {
        printf("Cannot get %s property.\n", prop_name);
        return NULL;
    }

    if (xa_ret_type != xa_prop_type) {
        printf("Invalid type of %s property.\n", prop_name);
        XFree(ret_prop);
        return NULL;
    }

    /* null terminate the result to make string handling easier */
    tmp_size = (ret_format / 8) * ret_nitems;
    /* Correct 64 Architecture implementation of 32 bit data */
    if(ret_format==32) tmp_size *= sizeof(long)/4;
    ret = (char *)malloc(tmp_size + 1);
    memcpy(ret, ret_prop, tmp_size);
    ret[tmp_size] = '\0';

    if (size) {
        *size = tmp_size;
    }

    XFree(ret_prop);
    return ret;
}

Harika bir başlangıç, teşekkürler! Hmm, terminal, firefox ve chrome ile çalışıyor, ancak emacs ve robomongo gibi diğerleri için "WM_NAME mülkü alınamıyor" atar. Stéphane'nin bahsettiği "ağaç yürüyüşü" bölümü olup olmadığını merak ediyorum.
Jeff Ward

Ben ekleyerek çalıştı olmasa robomongo ve yapılan emacs işin o - "WM_NAME özelliği bulunana kadar deneyin üst" a. İlginç. Bu yanıt ayrıca PID'yi bulmak için ilgili bazı bilgilere de sahiptir: unix.stackexchange.com/questions/5478/… İlginçtir ki bu PID (kardinal olmak?) Tüm "Terminal" pencereleri için aynıdır. Her terminal ayrı bir geçerli çalışma dizininde olabileceğinden, bu benim özel kullanım durumum için iyi bir sonuç vermiyor.
Jeff Ward

Evet. PID almak için "_NET_WM_PID" özelliği ile hiç şansım yoktu ama adı bir başlangıç ​​noktası olarak kullanabileceğini umuyordu.
jschlichtholz

1
@JeffWard gnome-terminalsaygıdeğer gibi terminal penceresi başına bir örnek yerine, oturum başına uygulamanın yalnızca bir kez başlatılması gibi bazı modern terminal programları xterm. Belki de bu yüzden hepsinde aynı PID'yi görüyorsunuz? İçin gnome-terminalsize o misfeature devre dışı edebilmek için kullanılan --disable-factory(bir seçenek için tek isim), ancak görünüşe göre bu artık mümkün olabilir . Her neyse, terminalin içinde çalışan işlemlerden birinin pwd'sine ihtiyacınız var gibi geliyor, kendinden değil.
Celada

@Celada - doğru ve mantıklı - X pencere sistemi pencereleri biliyor, her programın onlarla ne yapmak istediğini değil. Ayrıca Chrome'un panoya ayrılmış ayrı bir penceresi (veya işlemi?) Var gibi görünüyor. Görünüşe göre birçok şema var ve benim fikrim ortaya çıkmayabilir.
Jeff Ward
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.