让Chrome左键点击书签栏时打开新标签

来源:互联网 发布:papi酱起诉 知乎 编辑:程序博客网 时间:2024/05/21 14:58
前段时间我的火狐彻底无法启动了,万般无奈下花了很大的力气转投Chrome

Chrome有很多地方不符合我的使用习惯,虽然可换枫树浏览器,这方面她做得很好,但我更希望使用原版的Chrome

不符习惯的问题中有个很典型的就是:在鼠标左键点击书签栏的书签时,新标签页会替换当前标签页,使用中键点击才会另新建标签页

(注意区分书签和标签)

这点非常不好,非常不符习惯。在改习惯和改程序直接,我选择了后者


我们现在的目标很简单,就是修改原版Chrome,让其左键点击书签栏时新建标签页,而不是替换


好在Chrome是开源的,不然我可能要多花三四天的时间,但是开源的也没我想的那么简单

代码有4G多,想找点什么真是大海捞针。而且我又无法编译代码,因为它需要很多工具比如SVN什么的,我这里全部没有,只能干看

我在这里做个简易教程,把关键点提出来,主要是为应付以后版本更新,大家可自行修改。别看文章有点长,其实我没说过几句话


----------------------------------------------------------------------------------------------------


(此代码在文件\chromium\src\chrome\browser\ui\views\bookmarks\bookmark_bar_view.cc)

void BookmarkBarView::ButtonPressed(views::Button* sender, const views::Event& event) {    const BookmarkNode* node;    if (sender->tag() == kOtherFolderButtonTag) {        node = model_->other_node();    }    else    {        int index = GetIndexOf(sender);        DCHECK_NE(-1, index);        node = model_->bookmark_bar_node()->GetChild(index);    }    DCHECK(page_navigator_);    //注意disposition_from_event_flags,关键    WindowOpenDisposition disposition_from_event_flags = event_utils::DispositionFromEventFlags(        sender->mouse_event_flags()    );    Profile* profile = browser_->profile();      if (node->is_url())     {        RecordAppLaunch(profile, node->url());        OpenURLParams params(                  //这是构造函数            node->url(),             Referrer(),             disposition_from_event_flags,      //推荐修改此处的disposition_from_event_flags            content::PAGE_TRANSITION_AUTO_BOOKMARK, false );           page_navigator_->OpenURL(params);    }     else     {        bookmark_utils::OpenAll(            GetWidget()->GetNativeWindow(),            profile,            page_navigator_,            node,            disposition_from_event_flags );    }    bookmark_utils::RecordBookmarkLaunch(        IsDetached() ?         bookmark_utils::LAUNCH_DETACHED_BAR : bookmark_utils::LAUNCH_ATTACHED_BAR );    content::RecordAction(UserMetricsAction("ClickedBookmarkBarURLButton"));}

(此代码在文件\chromium\src\ui\views\controls\menu\menu_runner.cc)
MenuRunner::RunResult MenuRunnerImpl::RunMenuAt(    Widget* parent,    MenuButton* button,    const gfx::Rect& bounds,    MenuItemView::AnchorPosition anchor,    int32 types ){    if (running_)    {        return MenuRunner::NORMAL_EXIT;    }    MenuController* controller = MenuController::GetActiveInstance();    if (controller)    {        if ((types & MenuRunner::IS_NESTED) != 0)        {            if (!controller->IsBlockingRun()) {                controller->CancelAll();                controller = NULL;            }        }        else        {            controller->CancelAll();            if ((types & MenuRunner::FOR_DROP) == 0) {                return MenuRunner::NORMAL_EXIT;            }            controller = NULL;        }    }    running_  = true;    for_drop_ = (types & MenuRunner::FOR_DROP) != 0;    bool has_mnemonics = (types & MenuRunner::HAS_MNEMONICS) != 0 && !for_drop_;    menu_->PrepareForRun(has_mnemonics, !for_drop_ && ShouldShowMnemonics(button));    //注意mouse_event_flags,关键    int mouse_event_flags = 0;    owns_controller_      = false;    if (!controller)    {        controller = new MenuController(!for_drop_, this);        owns_controller_ = true;    }    controller_ = controller;    menu_->set_controller(controller_);    //参六为返回    MenuItemView* result = controller->Run(parent, button, menu_, bounds, anchor, &mouse_event_flags);    if (for_drop_)    {        return MenuRunner::NORMAL_EXIT;    }    //推荐修改此处的mouse_event_flags    return MenuDone(result, mouse_event_flags);}


你可能觉得,这些代码看不懂。其实完全不用看懂,不过是一些代码片段,有什么理解必要?你只要看懂我在讲什么就行了

上面两条函数中出现了两个变量,是关键:

<1> disposition_from_event_flags
<2> mouse_event_flags

这两个变量记录的都是用户鼠标点击事件,比如你点的是左键呢,还是中键

为什么要有两个呢,因为对于书签栏中“普通书签按钮”和“菜单书签按钮”,它是分开处理的,所以要修改的地方也就是两处

我多解释一下所谓的“菜单书签按钮”,比如放在书签栏文件夹中的书签按钮就是


那解决方案现在已经非常明显了,用户点击了鼠标左键,我把它改成点击鼠标中键不就达成目的了吗

应该修改的地方,我在上述代码中用注释标明出来了,这里再强调一下

disposition_from_event_flags的推荐修改这里:

OpenURLParams params(
    node->url(),
    Referrer(), 
    disposition_from_event_flags,              //推荐修改此处
    content::PAGE_TRANSITION_AUTO_BOOKMARK, false );

mouse_event_flags的修改这里:

return MenuDone(result, mouse_event_flags);    //推荐修改此处


还有最后一个问题,就是这两个变量的取值:

变量左键中键disposition_from_event_flags25mouse_event_flags0x100x20
(后者的宏定义在\chromium\src\ui\base\events.h中,前者懒得找了)


----------------------------------------------------------------------------------------------------


还有最后的最后一个问题,就是如何修改

当然是定位汇编来修改,我这里做个简单例子,至于如何定位到这两条函数,大家可以通过函数中的特征码来定位

文件名:   Chrome.dll
版本号:   18.0.1025.142
ImageBase:0x57790000

585B3D00    55              push    ebp                              ; BookmarkBarView::ButtonPressed( )585B3D01    8BEC            mov     ebp, esp585B3D03    81EC 78010000   sub     esp, 178585B3D09    A1 00003659     mov     eax, dword ptr [59360000]585B3D0E    33C5            xor     eax, ebp585B3D10    8945 FC         mov     dword ptr [ebp-4], eax585B3D13    83A5 F4FEFFFF 0>and     dword ptr [ebp-10C], 0585B3D1A    53              push    ebx585B3D1B    8B5D 08         mov     ebx, dword ptr [ebp+8]585B3D1E    83BB F0000000 0>cmp     dword ptr [ebx+F0], 1585B3D25    56              push    esi585B3D26    57              push    edi585B3D27    8BF1            mov     esi, ecx585B3D29    75 0B           jnz     short 585B3D36585B3D2B    8B46 38         mov     eax, dword ptr [esi+38]585B3D2E    8BB8 2C010000   mov     edi, dword ptr [eax+12C]585B3D34    EB 20           jmp     short 585B3D56585B3D36    53              push    ebx585B3D37    8D8E 08FFFFFF   lea     ecx, dword ptr [esi-F8]585B3D3D    E8 F1E85200     call    58AE2633585B3D42    8B4E 38         mov     ecx, dword ptr [esi+38]585B3D45    8B89 28010000   mov     ecx, dword ptr [ecx+128]585B3D4B    50              push    eax585B3D4C    83C1 24         add     ecx, 24585B3D4F    E8 962920FF     call    577B66EA585B3D54    8B38            mov     edi, dword ptr [eax]585B3D56    FFB3 F4000000   push    dword ptr [ebx+F4]585B3D5C    E8 49EBE7FF     call    584328AA585B3D61    83BF B0000000 0>cmp     dword ptr [edi+B0], 0585B3D68    59              pop     ecx585B3D69    8B4E 64         mov     ecx, dword ptr [esi+64]585B3D6C    8B99 C8000000   mov     ebx, dword ptr [ecx+C8]585B3D72    8985 F4FEFFFF   mov     dword ptr [ebp-10C], eax         ; 此变量是disposition_from_event_flags585B3D78    75 70           jnz     short 585B3DEA585B3D7A    83EC 68         sub     esp, 68585B3D7D    83C7 48         add     edi, 48585B3D80    8BCC            mov     ecx, esp585B3D82    57              push    edi585B3D83    E8 75C721FF     call    577D04FD585B3D88    53              push    ebx585B3D89    E8 8BF4FFFF     call    585B3219585B3D8E    83C4 6C         add     esp, 6C585B3D91    8D8D 88FEFFFF   lea     ecx, dword ptr [ebp-178]585B3D97    E8 25C121FF     call    577CFEC1585B3D9C    6A 00           push    0585B3D9E    6A 02           push    2585B3DA0    FFB5 F4FEFFFF   push    dword ptr [ebp-10C]              ; 修改这里,把push disposition_from_event_flags改成push 5585B3DA0                                                             ; FF B5 F4 FE FF FF -> 6A 05 90 90 90 90585B3DA6    8D85 88FEFFFF   lea     eax, dword ptr [ebp-178]585B3DAC    50              push    eax585B3DAD    57              push    edi585B3DAE    8D8D F8FEFFFF   lea     ecx, dword ptr [ebp-108]585B3DB4    C785 F0FEFFFF 0>mov     dword ptr [ebp-110], 1585B3DBE    E8 27972000     call    587BD4EA                         ; OpenURLParams::OpenURLParams( )585B3DC3    8D8D 88FEFFFF   lea     ecx, dword ptr [ebp-178]585B3DC9    E8 F6C521FF     call    577D03C4585B3DCE    8B4E 34         mov     ecx, dword ptr [esi+34]585B3DD1    8B01            mov     eax, dword ptr [ecx]585B3DD3    8D95 F8FEFFFF   lea     edx, dword ptr [ebp-108]585B3DD9    52              push    edx585B3DDA    FF50 04         call    dword ptr [eax+4]585B3DDD    8D8D F8FEFFFF   lea     ecx, dword ptr [ebp-108]585B3DE3    E8 E0962000     call    587BD4C8585B3DE8    EB 21           jmp     short 585B3E0B585B3DEA    50              push    eax585B3DEB    57              push    edi585B3DEC    FF76 34         push    dword ptr [esi+34]585B3DEF    8D8E 08FFFFFF   lea     ecx, dword ptr [esi-F8]585B3DF5    8B01            mov     eax, dword ptr [ecx]585B3DF7    53              push    ebx585B3DF8    FF50 10         call    dword ptr [eax+10]585B3DFB    8BC8            mov     ecx, eax585B3DFD    E8 87844FFF     call    57AAC289585B3E02    50              push    eax585B3E03    E8 6D33EFFF     call    584A7175585B3E08    83C4 14         add     esp, 14585B3E0B    8D8E 08FFFFFF   lea     ecx, dword ptr [esi-F8]585B3E11    8B01            mov     eax, dword ptr [ecx]585B3E13    FF90 9C010000   call    dword ptr [eax+19C]585B3E19    33C9            xor     ecx, ecx585B3E1B    84C0            test    al, al585B3E1D    0F95C1          setne   cl585B3E20    51              push    ecx585B3E21    E8 1B28EFFF     call    584A6641585B3E26    8D85 F4FEFFFF   lea     eax, dword ptr [ebp-10C]585B3E2C    50              push    eax585B3E2D    C785 F4FEFFFF D>mov     dword ptr [ebp-10C], 591214D8    ; ASCII "ClickedBookmarkBarURLButton"585B3E37    E8 DE3E41FF     call    579C7D1A                         ; RecordAction( )585B3E3C    59              pop     ecx585B3E3D    59              pop     ecx585B3E3E    8B4D FC         mov     ecx, dword ptr [ebp-4]585B3E41    5F              pop     edi585B3E42    5E              pop     esi585B3E43    33CD            xor     ecx, ebp585B3E45    5B              pop     ebx585B3E46    E8 83021EFF     call    577940CE585B3E4B    C9              leave585B3E4C    C2 0800         retn    8


58AE8F2B    55              push    ebp                              ; MenuRunnerImpl::RunMenuAt( )58AE8F2C    8BEC            mov     ebp, esp58AE8F2E    8B09            mov     ecx, dword ptr [ecx]58AE8F30    5D              pop     ebp58AE8F31  ^ E9 B2FEFFFF     jmp     58AE8DE858AE8DE8    55              push    ebp58AE8DE9    8BEC            mov     ebp, esp58AE8DEB    51              push    ecx58AE8DEC    56              push    esi58AE8DED    8BF1            mov     esi, ecx58AE8DEF    807E 2C 00      cmp     byte ptr [esi+2C], 058AE8DF3    74 08           je      short 58AE8DFD58AE8DF5    33C0            xor     eax, eax58AE8DF7    40              inc     eax58AE8DF8    E9 F5000000     jmp     58AE8EF258AE8DFD    53              push    ebx58AE8DFE    57              push    edi58AE8DFF    E8 362611FF     call    57BFB43A58AE8E04    8B5D 18         mov     ebx, dword ptr [ebp+18]58AE8E07    8BF8            mov     edi, eax58AE8E09    85FF            test    edi, edi58AE8E0B    74 2A           je      short 58AE8E3758AE8E0D    F6C3 02         test    bl, 258AE8E10    74 11           je      short 58AE8E2358AE8E12    807F 04 00      cmp     byte ptr [edi+4], 058AE8E16    75 1F           jnz     short 58AE8E3758AE8E18    6A 01           push    158AE8E1A    8BCF            mov     ecx, edi58AE8E1C    E8 3D5F0100     call    58AFED5E58AE8E21    EB 12           jmp     short 58AE8E3558AE8E23    6A 01           push    158AE8E25    8BCF            mov     ecx, edi58AE8E27    E8 325F0100     call    58AFED5E58AE8E2C    F6C3 04         test    bl, 458AE8E2F    0F84 AB000000   je      58AE8EE058AE8E35    33FF            xor     edi, edi58AE8E37    8BC3            mov     eax, ebx58AE8E39    C1E8 02         shr     eax, 258AE8E3C    24 01           and     al, 158AE8E3E    C646 2C 01      mov     byte ptr [esi+2C], 158AE8E42    8846 2E         mov     byte ptr [esi+2E], al58AE8E45    F6C3 01         test    bl, 158AE8E48    74 0A           je      short 58AE8E5458AE8E4A    84C0            test    al, al58AE8E4C    75 06           jnz     short 58AE8E5458AE8E4E    C645 18 01      mov     byte ptr [ebp+18], 158AE8E52    EB 08           jmp     short 58AE8E5C58AE8E54    C645 18 00      mov     byte ptr [ebp+18], 058AE8E58    84C0            test    al, al58AE8E5A    75 12           jnz     short 58AE8E6E58AE8E5C    FF75 0C         push    dword ptr [ebp+C]58AE8E5F    8BCE            mov     ecx, esi58AE8E61    E8 5FFFFFFF     call    58AE8DC558AE8E66    84C0            test    al, al58AE8E68    74 04           je      short 58AE8E6E58AE8E6A    B0 01           mov     al, 158AE8E6C    EB 02           jmp     short 58AE8E7058AE8E6E    32C0            xor     al, al58AE8E70    8B4E 04         mov     ecx, dword ptr [esi+4]58AE8E73    50              push    eax58AE8E74    FF75 18         push    dword ptr [ebp+18]58AE8E77    E8 53FEFFFF     call    58AE8CCF58AE8E7C    8365 FC 00      and     dword ptr [ebp-4], 0             ; 此变量是mouse_event_flags58AE8E80    C646 34 00      mov     byte ptr [esi+34], 058AE8E84    85FF            test    edi, edi58AE8E86    75 2C           jnz     short 58AE8EB458AE8E88    68 08010000     push    10858AE8E8D    E8 C9D8CAFE     call    5779675B58AE8E92    59              pop     ecx58AE8E93    85C0            test    eax, eax58AE8E95    74 17           je      short 58AE8EAE58AE8E97    807E 2E 00      cmp     byte ptr [esi+2E], 058AE8E9B    56              push    esi58AE8E9C    0F94C1          sete    cl58AE8E9F    0FB6C9          movzx   ecx, cl58AE8EA2    51              push    ecx58AE8EA3    8BC8            mov     ecx, eax58AE8EA5    E8 C8510100     call    58AFE07258AE8EAA    8BF8            mov     edi, eax58AE8EAC    EB 02           jmp     short 58AE8EB058AE8EAE    33FF            xor     edi, edi58AE8EB0    C646 34 01      mov     byte ptr [esi+34], 158AE8EB4    8B46 04         mov     eax, dword ptr [esi+4]58AE8EB7    897E 30         mov     dword ptr [esi+30], edi58AE8EBA    89B8 9C000000   mov     dword ptr [eax+9C], edi58AE8EC0    8D45 FC         lea     eax, dword ptr [ebp-4]           ; 这里是&mouse_event_flags58AE8EC3    50              push    eax58AE8EC4    FF75 14         push    dword ptr [ebp+14]58AE8EC7    8BCF            mov     ecx, edi58AE8EC9    FF75 10         push    dword ptr [ebp+10]58AE8ECC    FF76 04         push    dword ptr [esi+4]58AE8ECF    FF75 0C         push    dword ptr [ebp+C]58AE8ED2    FF75 08         push    dword ptr [ebp+8]58AE8ED5    E8 6D680100     call    58AFF74758AE8EDA    807E 2E 00      cmp     byte ptr [esi+2E], 058AE8EDE    74 05           je      short 58AE8EE558AE8EE0    33C0            xor     eax, eax58AE8EE2    40              inc     eax58AE8EE3    EB 0B           jmp     short 58AE8EF058AE8EE5    FF75 FC         push    dword ptr [ebp-4]                ; 修改这里,push mouse_event_flags改成push 0x2058AE8EE5                                                             ; FF 75 FC -> 6A 20 9058AE8EE8    8BCE            mov     ecx, esi58AE8EEA    50              push    eax58AE8EEB    E8 50FEFFFF     call    58AE8D40                         ; MenuDone( )58AE8EF0    5F              pop     edi58AE8EF1    5B              pop     ebx58AE8EF2    5E              pop     esi58AE8EF3    C9              leave58AE8EF4    C2 1400         retn    14



其实应该先判断disposition_from_event_flags和mouse_event_flags的值是否符合预期的

if (disposition_from_event_flags == 2) {    disposition_from_event_flags = 5;}else if (mouse_event_flags == 0x10) {    mouse_event_flags = 0x20;}

不过我把这些步骤省了,不判断了

对于以上汇编,我做了个补丁,仅供测试之用,放在附注中下载


----------------------------------------------------------------------------------------------------


附注:

对于本例子我做的个小补丁仅供测试,含Chrome.dll(6分):

http://download.csdn.net/detail/ucantseeme/4207421

我的Chrome代码是从这里下载的:
http://chromium-browser-source.commondatastorage.googleapis.com/chromium_tarball.html


                                                                                                    2012年04月02日
原创粉丝点击