2010-12-23 12 views
5

के साथ उपभोग करना मैं अपने जादू ट्रैकपैड से ईवेंट को सक्षम/अक्षम करने के लिए एक ईवेंट जाल जोड़ने की कोशिश कर रहा हूं। मैंने सोचा कि यह सीधे आगे होगा, यानी एक घटना जाल पंजीकृत करें और जब आवश्यक हो, तो NULL लौटकर ईवेंट को त्यागें। विचार कुछ विशिष्ट, समय लेने वाली डेटा एंट्री के लिए पैड का उपयोग करना है, डेटा में प्रवेश करने के लिए एप्लिकेशन तीसरे पक्ष के हैं इसलिए मैं चाहता हूं कि मैं चाहता हूं कि मैं चाहता हूं कि कोड न जोड़ें। तो मैंने सोचा कि मैं सिस्टम घटनाओं की निगरानी करता हूं और फिर CGEventCreateKeyboardEvent एस के गुच्छा के माध्यम से वांछित इनपुट भेजता हूं।ओएसएक्स माउस/ट्रैकपैड घटनाओं को एक ईवेंट टैप

समस्या वापस आ रही है, घटनाओं को त्यागना प्रतीत नहीं होता है, थोड़ा और जांच से पता चलता है कि यह ट्रैकपैड से आने वाले लोगों तक ही सीमित नहीं है बल्कि मेरा डिफ़ॉल्ट यूएसबी माउस भी प्रतिबंधित है।

मेरा कोड नीचे है। नीचे क्या है, मैं उम्मीद करता हूं कि माउस को स्थानांतरित करने में सक्षम न होने की उम्मीद है, अगर मैं kCGEventScrollWheel या kCGEventLeftMouseDragged का उपयोग करने के लिए (ए) बदलता हूं तो ईवेंट का उपभोग होता है, यानी स्क्रॉलिंग या बाएं बीटीएन ड्रैग नहीं होता है। क्या इसका मतलब यह है कि सभी घटनाओं को त्याग दिया नहीं जा सकता है? उम्मीद है कि मैं सिर्फ यहाँ कुछ स्पष्ट याद कर रहा हूँ

#define case_print(a) case a: printf("%s - %d\n",#a,a); break; 


    CGEventRef eventOccurred(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void* refcon) { 
    int subType = CGEventGetIntegerValueField(event, kCGMouseEventSubtype); 
    if (type == NSEventTypeGesture || subType == NX_SUBTYPE_MOUSE_TOUCH) { 
     printf("touchpad\n"); 

     switch(type) { 
       case_print(kCGEventNull) 
       case_print(kCGEventLeftMouseDown) 
       case_print(kCGEventLeftMouseUp) 
       case_print(kCGEventRightMouseDown) 
       case_print(kCGEventRightMouseUp) 
       case_print(kCGEventMouseMoved) 
       case_print(kCGEventLeftMouseDragged) 
       case_print(kCGEventRightMouseDragged) 
       case_print(kCGEventScrollWheel) 
       case_print(kCGEventOtherMouseDown) 
       case_print(kCGEventOtherMouseUp) 
       case_print(kCGEventOtherMouseDragged) 
       case_print(kCGEventTapDisabledByTimeout) 
       case_print(kCGEventTapDisabledByUserInput) 
       case_print(NSEventTypeGesture) 
       case_print(NSEventTypeMagnify) 
       case_print(NSEventTypeSwipe) 
       case_print(NSEventTypeRotate) 
       case_print(NSEventTypeBeginGesture) 
       case_print(NSEventTypeEndGesture) 
      default: 
       printf("default: %d\n",type); 
       break;  
     } 

     event = NULL; 
    } else { 
     if (type == kCGEventMouseMoved) { // (A) 
      printf("discarding mouse event"); 
      event = NULL; 
     } 
    } 

    return event; 
} 


CFMachPortRef createEventTap() { 
    CGEventMask eventMask = NSAnyEventMask; 

    if (!AXAPIEnabled() && !AXIsProcessTrusted()) { 
     printf("axapi not enabled"); 
    } 

    return CGEventTapCreate(kCGHIDEventTap, 
          kCGHeadInsertEventTap, 
          kCGEventTapOptionDefault, 
          eventMask, 
          eventOccurred, 
          NULL); 
} 

int main (int argc, const char * argv[]) { 
    CFMachPortRef tap = createEventTap(); 

    if (tap) { 
     CFRunLoopSourceRef rl = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, tap, 0); 
     CFRunLoopAddSource(CFRunLoopGetMain(), rl, kCFRunLoopCommonModes); 
     CGEventTapEnable(tap, true); 
     CFRunLoopRun(); 

     printf("Tap created.\n"); 
     sleep(-1); 
    } else { 
     printf("failed!\n"); 
    } 

    return 0; 
} 

ध्यान दें, "axapi सक्षम नहीं" उत्पादन हालांकि मुझे नहीं लगता पहुंच विकल्प कुछ भी लेकिन कुंजीपटल की घटनाओं को प्रभावित करता है नहीं है।

बीटीडब्ल्यू, मैंने टच पैड से घटनाओं को कैसे प्राप्त किया है, इस पर कुछ समान पोस्ट देखी हैं, उन्हें छोड़ने के लिए कुछ भी लागू नहीं है (शून्य को वापस करने के अलावा काम करना चाहिए)।

उत्तर

1

यदि आपकी टैप निष्क्रिय है, तो वापस लौटने से ईवेंट स्ट्रीम अप्रभावित हो जाएगी। CGEventTapCallBack संदर्भ दस्तावेज़ से:।

"घटना नल एक निष्क्रिय श्रोता है, तो अपने कॉलबैक फ़ंक्शन घटना है कि में पारित हो जाता है, या NULL वापस आ सकते हैं या तो मामले में, घटना धारा नहीं है लग जाना।"

हालांकि, ऐसा लगता है कि आपकी टैप सक्रिय है। इस प्रकार आपके लौटने वाले न्यूल को घटना को हटाना चाहिए। क्या आपने कार्रवाई को रद्द करने के लिए घटना को संशोधित करने पर विचार किया है?

यह भी ध्यान रखें कि कॉल CGEventTapCreate को सभी घटनाओं को रोकने के लिए रूट उपयोगकर्ता अनुमतियों की आवश्यकता होती है। क्या आपकी प्रक्रिया रूट के रूप में चल रही है?

+0

क्यों इस उत्तर के रूप में चिह्नित किया गया था? क्या आप प्रोजेक्ट से माउस ईवेंट को रोकने में सक्षम थे? मैं मुख्य घटनाओं को रोकने में सक्षम हूं, लेकिन माउस आंदोलनों नहीं ... – cksubs

4

मुझे लगता है कि इन घटनाओं को आसानी से छोड़ना संभव नहीं है। CGEventTypes.h हेडर फाइल से:

"घटना कॉलबैक के लिए पारित बुला कोड द्वारा बनाए रखा है, और बाद कॉलबैक लौट आते हैं और डेटा वापस घटना प्रणाली को पारित कर दिया है जारी किया गया है। एक अलग घटना कॉलबैक फ़ंक्शन द्वारा दिया जाता है, तो तो उस घटना मूल घटना के साथ बुला कोड से, इवेंट डेटा घटना व्यवस्था करने के लिए वापस पारित किया गया है के बाद जारी किया जाएगा। "

मैंने इस के साथ बहुत कुछ खेला है और ऐसा लगता है कि कॉलबैक लौटने के बाद विंडो सर्वर सक्रिय रूप से ईवेंट के लिए किए गए कार्यों के लिए फिर से जांच करता है।यह केवल मुख्य घटनाओं और माउस अप/डाउन इवेंट्स को हटाने की इजाजत देता है, लेकिन जैसे ही यह माउस की घटनाओं को हटाने की अनदेखी करता है (ठीक है, माउस रेंडरिंग को कहीं और संसाधित किया जाता है, मुझे लगता है) ऐसा लगता है कि यह हटाना अनदेखा करता है (यानी आपका कॉलबैक न्यूल लौट रहा है) माउस इशारे के लिए।

आंकड़े, जेस्चर के लिए टैपिंग पर विचार करना विशेष रूप से प्रलेखन (इस स्तर पर परिभाषित कोई प्रकार नहीं) में समझाया नहीं गया है।

मैंने एक अलग घटना (एक कुंजी प्रेस) लौटने की कोशिश की और इसे मूल रूप से मूल इशारा करने के लिए संभाला जाता है। आपके कॉलबैक में ईवेंट को रिहा करने से यह नहीं होता है, या तो (बिल्कुल), केवल अपवाद में परिणाम होता है।

एकमात्र चीज जिसे मैंने कोशिश नहीं की है, सीधे सीजेईएंड के आंतरिक डेटा को सीधे जोड़ना है ताकि कम से कम इशारा कुछ भी नहीं कर सके (सभी आंदोलन और इस तरह से हटाया जा सके), लेकिन यह बहुत कठिन है क्योंकि ऐसा करने के लिए परिभाषित कोई विशिष्ट तरीका नहीं है उस। मुझे पूरा यकीन है कि आवश्यक जानकारी कहीं भी CGEventSet * विधियों के माध्यम से उपलब्ध विभिन्न क्षेत्रों में कहीं भी है।

मैंने अपनी डेटा संरचना को समझने के लिए IOLLEvent.h तक नीचे देखा, लेकिन यह मेरे स्वाद के लिए और अधिक बदसूरत होने के लिए बहुत बदसूरत था। आइए उम्मीद करते हैं कि शेर सीएफ स्तर पर इशारा करते हुए घटनाओं के बारे में कुछ और प्रदान करता है।

+1

जो CGEventSetIntegerValueField (ईवेंट, kCGMouseEventDeltaX, 0) होगा; और CGEventSetIntegerValueField (घटना, kCGMouseEventDeltaY, 0); लेकिन यह भी अनदेखा किया जाता है। – valexa

3

मैं 10.6 पर पुष्टि कर सकता हूं कि इस उद्देश्य के लिए निम्न विधियों में से कोई भी सफल नहीं है।

1-लौटने शून्य

पिछले कर्सर स्थिति

3-लौटा रहा है इसके साथ पारित कर दिया घटना kCGMouseEventDelta के लिए 0

बदल रहा 10.7 की बात नहीं कर सकते हैं के साथ एक नया माउस घटना 2-लौट लेकिन चलो बस कहना है कि मुझे अपनी उम्मीद नहीं मिलेंगी।

हालांकि एक बात यह है कि आप आंदोलन को छोड़ने के बजाय इसे वापस कर सकते हैं, CGWarpMouseCursorPosition के साथ पिछले स्थान पर वापस ले जाएं, असल में कर्सर पहले पर केवल थोड़ी सी बदलाव के साथ आगे बढ़ना बंद कर देगा।

+0

मेरा अनुभव वही है ... माउस आंदोलन को रोकने के लिए डेलटा को वापस या संशोधित नहीं कर सकता है। मैं कर्सर को वापस ले जाता हूं लेकिन कर्सर अभी भी मूल स्थान पर चमकता है। यहां इसे रोकने की उम्मीद है: http://stackoverflow.com/questions/9899534/prevent-mousemovedevent-callback-from-processing-the-movement-or-globally-hid – cksubs

1
CGAssociateMouseAndMouseCursorPosition(FALSE); 

आपके ऐप सक्रिय होने पर माउस को काम करने से रोक देगा।

फिर भी तलाश रही है, तो मैं वैश्विक क्षुधा है कि विस्तार कर सकते हैं ...

http://lists.apple.com/archives/quartz-dev/2007/May/msg00112.html

संबंधित मुद्दे