ক্লিপবোর্ডের উত্স (অ্যাপ্লিকেশন) জানা কি সম্ভব?


10

আমি লক্ষ করেছি যে কখনও কখনও উত্স অ্যাপ্লিকেশন (যেখানে সামগ্রীটি অনুলিপি করা হয়) বন্ধ করা হয় তবে ক্লিপবোর্ডের সামগ্রীগুলি অনুপলব্ধ হয়ে যায়।

এটি আমাকে উত্সাহিত করে যে উত্স অ্যাপ্লিকেশনটি কী তা জানা সম্ভব (উদাহরণস্বরূপ সম্ভবত পিআইডি দ্বারা)।

কেন? যদি উত্স অ্যাপ্লিকেশনটি একটি টার্মিনাল হয় তবে অনুলিপিযুক্ত বিষয়বস্তু যদি কোনও ফাইলের পুরো পথটি তৈরি করতে হয় তবে অনুলিপিটিযুক্ত টার্মিনালের কার্যকারী ডিরেক্টরিটি সন্ধান করতে চাই।

এফওয়াইআই, আমি বর্তমানে ক্লিপবোর্ডের সামগ্রীগুলি নির্ধারণ করতে এক্সক্লিপ ব্যবহার করছি eg

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

2
XGetSelectionOwner(3)আপনি নির্বাচনের মালিকের উইন্ডো আইডি পাবেন। যা থেকে আপনি উদাহরণ হিসাবে উদাহরণস্বরূপ _NET_WM_PID সম্পত্তি সহ একটি উইন্ডোটি দেখতে চেষ্টা করতে এবং উইন্ডো ট্রিটিতে যেতে পারেন xprop(ধরে নিই যে এই স্থানীয় বৈশিষ্ট্যটি সেট করে এমন স্থানীয় ক্লায়েন্টের কাছ থেকে উইন্ডো এসেছে)। xwininfo -root -tree | less +/0x<that-id>অ্যাপ্লিকেশন সনাক্ত করতে যথেষ্ট হতে পারে।
স্টাফেন চেজেলাস

2
@ স্টাফেনচাজেলাস যা বলেছে। তবে সচেতন থাকুন যে আপনি এক্স 11 এর বাইরে অন্য ক্লায়েন্টের একটি নির্ভরযোগ্য পিআইডি পাওয়ার সম্ভাবনা নেই। এক্স ক্লায়েন্টরা জেনেরিক নেটওয়ার্ক সংযোগের মাধ্যমে এক্স সার্ভারের সাথে সংযুক্ত হওয়ার বিষয়টি মনে করে (ইউএনআইএক্স সকেট বা টিসিপি সকেট), অ্যাপ্লিকেশন স্থানীয় না হওয়ায় একটি পিআইডি অর্থহীন হতে পারে। এটি টিসিপির মাধ্যমে সংযুক্ত থাকতে পারে (এই দিনগুলিতে আর সাধারণ নয়) বা এসএসএইচ-ফরওয়ার্ডেড এক্স 11 সংযোগ (আরও সাধারণ)।
সেলেদা

নোটগুলির জন্য ধন্যবাদ - আমি ধরে নিচ্ছি XGetSelectionOwner এর পরে অ্যাক্সেস করার জন্য আমার কিছু সি কোড লিখতে হবে? আমি সম্ভবত এটি করতে পারি - আমি কোনও সমাধান পেয়ে গেলে আমি পোস্ট করব।
জেফ ওয়ার্ড

উত্তর:


5

আমি একটি সরঞ্জাম লিখেছিলাম যা সমতল অ্যাপ্লিকেশনটির নাম দেয় (যেমন 'টার্মিনাল', 'জিডিট' বা 'স্মার্টজিট' যা আমি পরীক্ষা করেছি)। বেশিরভাগ কোডটি এখানে @ হার্ভে থেকে নির্লজ্জভাবে চুরি হয়েছে

// 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;
}

একটি দুর্দান্ত শুরু, ধন্যবাদ! হুঁ, এটি টার্মিনাল, ফায়ারফক্স এবং ক্রোমের সাথে কাজ করে তবে ইমাস এবং রোবমোঙ্গো ইত্যাদির মতো অন্যদের জন্য "WM_NAME সম্পত্তি পেতে পারে না" ইত্যাদি ছুঁড়ে দেয় আমি আশ্চর্য হয়েছি যে স্টাফেন "অংশটি গাছের সাথে হাঁটা" অংশটি উল্লেখ করছেন।
জেফ ওয়ার্ড

আমি "ডাব্লুএম_NAME সম্পত্তি না পাওয়া অবধি পিতামাতার চেষ্টা" যুক্ত করার চেষ্টা করেছি - এবং এটি রোমোঙ্গো না হলেও ইম্যাক্স তৈরি করেছে। মজাদার. এই উত্তরের পিআইডি সন্ধানের জন্য কিছু প্রাসঙ্গিক তথ্য রয়েছে: unix.stackexchange.com/questions/5478/… মজার বিষয় হল এই "পিআইডি (কার্ডিনাল হচ্ছে?) সমস্ত" টার্মিনাল "উইন্ডোগুলির জন্য একই। এটি আমার নির্দিষ্ট ব্যবহারের ক্ষেত্রে ভাল বিবেচনা করে না, যেহেতু প্রতিটি টার্মিনাল পৃথক বর্তমান ওয়ার্কিং ডিরেক্টরিতে থাকতে পারে।
জেফ ওয়ার্ড

হ্যাঁ. পিআইডি পাওয়ার জন্য "_NET_WM_PID" সম্পত্তি নিয়ে আমার ভাগ্য নেই তবে আমি আশা করি আপনি এই নামটি একটি প্রাথমিক পয়েন্ট হিসাবে ব্যবহার করতে পারবেন।
jschlichtholz

1
@ জেফ ওয়ার্ড কিছু আধুনিক টার্মিনাল প্রোগ্রাম যেমন gnome-terminalএকবার সেশন প্রতি প্রয়োগ একবার উদাহরণস্বরূপ যেমন টার্মিনাল উইন্ডো প্রতি সম্মানজনক মত প্রতি একবার উদাহরণ শুরু xterm। সম্ভবত সে কারণেই আপনি তাদের সকলের মধ্যে একই পিআইডি দেখছেন? আপনি gnome-terminalযে অপশক্তিটি --disable-factory(কোনও বিকল্পের জন্য বিজোড় নাম) দিয়ে অক্ষম করতে সক্ষম হয়েছিলেন তবে স্পষ্টতই সম্ভবত এটি আর সম্ভব হবে না । যাইহোক, মনে হচ্ছে আপনার নিজেরাই নয়, টার্মিনালের অভ্যন্তরে প্রসেসগুলির মধ্যে একটিতে পিডাব্লুডি প্রয়োজন।
সেলেদা

@ ক্যালাডা - ঠিক আছে, এবং এটি উপলব্ধি করে - এক্স উইন্ডো সিস্টেমটি উইন্ডোজ সম্পর্কে জানে, প্রতিটি প্রোগ্রাম তাদের সাথে কী পছন্দ করে তা অগত্যা নয়। ক্রোমের ক্লিপবোর্ডে উত্সর্গীকৃত একটি পৃথক উইন্ডো (বা প্রক্রিয়া?) রয়েছে বলেও দেখা যায়। স্পষ্টতই এখানে অনেকগুলি স্কিমাটা রয়েছে এবং আমার ধারণাটি পাতলা নাও হতে পারে।
জেফ ওয়ার্ড
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.